Hi,

> Seems that use info is not updated.
>

You should put a TODO_update_ssa in the flags of prefetching pass.
With the attached patch I don't see an error.

Also, why don't you use trunk for your developments?

Sebastian
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index 1d2e69a..1320b5a 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -782,6 +782,7 @@ bool gimple_duplicate_loop_to_header_edge (struct loop *, edge,
 					 edge, VEC (edge, heap) **,
 					 int);
 struct loop *slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *, edge);
+void slpeel_update_phis_for_duplicate_loop (struct loop *, struct loop *, bool);
 void rename_variables_in_loop (struct loop *);
 void rename_variables_in_bb (basic_block bb);
 struct loop *tree_ssa_loop_version (struct loop *, tree,
diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c
index e43c0bc..2f536df 100644
--- a/gcc/tree-ssa-loop-manip.c
+++ b/gcc/tree-ssa-loop-manip.c
@@ -1104,6 +1104,44 @@ tree_unroll_loop (struct loop *loop, unsigned factor,
 				  NULL, NULL);
 }
 
+/* Peel off the first or last few iterations of the loop. */
+
+struct loop *
+tree_peel_loop (struct loop *loop, unsigned num,
+                edge e, struct tree_niter_desc *desc)
+{
+  struct loop *new_loop, *first_loop, *second_loop;
+  tree first_niters;
+  edge exit_e = single_exit (loop);
+
+  if (!slpeel_can_duplicate_loop_p (loop, e))
+    return NULL;
+
+  new_loop = slpeel_tree_duplicate_loop_to_edge_cfg (loop, e);
+
+  if (e == exit_e)
+    {
+      /* NEW_LOOP was placed after LOOP.  */
+      first_loop = loop;
+      second_loop = new_loop;
+    }
+  else
+    {
+      /* NEW_LOOP was placed before LOOP.  */
+      first_loop = new_loop;
+      second_loop = loop;
+    }
+
+  slpeel_update_phis_for_duplicate_loop (loop, new_loop, e == exit_e);
+  rename_variables_in_loop (new_loop);
+
+  first_niters = build_int_cst (integer_type_node, num);
+
+  slpeel_make_loop_iterate_ntimes (first_loop, first_niters);
+
+  return new_loop;
+}
+
 /* Rewrite the phi node at position PSI in function of the main
    induction variable MAIN_IV and insert the generated code at GSI.  */
 
diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c
index b479707..36f2402 100644
--- a/gcc/tree-ssa-loop-prefetch.c
+++ b/gcc/tree-ssa-loop-prefetch.c
@@ -1548,7 +1548,7 @@ loop_prefetch_arrays (struct loop *loop)
   unsigned ahead, ninsns, time, unroll_factor;
   HOST_WIDE_INT est_niter;
   struct tree_niter_desc desc;
-  bool unrolled = false, no_other_refs;
+  bool unrolled_or_peeled = false, no_other_refs;
   unsigned prefetch_count;
   unsigned mem_ref_count;
 
@@ -1599,13 +1599,20 @@ loop_prefetch_arrays (struct loop *loop)
   if (!schedule_prefetches (refs, unroll_factor, ahead))
     goto fail;
 
-  /* Step 5: unroll the loop.  TODO -- peeling of first and last few
+  /* step 5: peel off the last few iterations. */
+  if (ahead > 0)
+    {
+      if (tree_peel_loop (loop, ahead, single_exit (loop), &desc) != NULL)
+        unrolled_or_peeled = true;
+    }
+
+  /* Step 6: unroll the loop.  TODO -- peeling of first and last few
      iterations so that we do not issue superfluous prefetches.  */
   if (unroll_factor != 1)
     {
       tree_unroll_loop (loop, unroll_factor,
 			single_dom_exit (loop), &desc);
-      unrolled = true;
+      unrolled_or_peeled = true;
     }
 
   /* Step 6: issue the prefetches.  */
@@ -1613,7 +1620,7 @@ loop_prefetch_arrays (struct loop *loop)
 
 fail:
   release_mem_refs (refs);
-  return unrolled;
+  return unrolled_or_peeled;
 }
 
 /* Issue prefetch instructions for array references in loops.  */
diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c
index 8f7047f..6adbb7b 100644
--- a/gcc/tree-ssa-loop.c
+++ b/gcc/tree-ssa-loop.c
@@ -626,7 +626,8 @@ struct gimple_opt_pass pass_loop_prefetch =
   0,					/* properties_provided */
   0,					/* properties_destroyed */
   0,					/* todo_flags_start */
-  TODO_dump_func | TODO_verify_loops	/* todo_flags_finish */
+  TODO_dump_func | TODO_verify_loops
+  | TODO_update_ssa			/* todo_flags_finish */
  }
 };
 
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index c0b15cd..c1d7564 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -121,7 +121,7 @@ rename_variables_in_loop (struct loop *loop)
    AFTER is true if NEW_LOOP executes after ORIG_LOOP, and false if it
    executes before it.  */
 
-static void
+void
 slpeel_update_phis_for_duplicate_loop (struct loop *orig_loop,
 				       struct loop *new_loop, bool after)
 {

Reply via email to