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)
{