2009/8/13 Sebastian Pop <[email protected]>:
> Could you please send the patch you are working on, together with
> a reduced testcase? This could help to reproduce the error.
Thanks.
I put the patch and a test below. The patch is based on 4.4.0. It's
just a toy, I haven't a nice design for now.
Actually, first_niters shouldn't be calculated in this way.
--- gcc-4.4.0/gcc/tree-ssa-loop-manip.c 2009-02-20 23:20:38.000000000 +0800
+++ new-gcc-4.4.0/gcc/tree-ssa-loop-manip.c 2009-08-14 11:28:44.000000000
+0800
@@ -1089,3 +1089,41 @@ tree_unroll_loop (struct loop *loop, uns
tree_transform_and_unroll_loop (loop, factor, exit, desc,
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;
+}
--- gcc-4.4.0/gcc/tree-ssa-loop-prefetch.c 2009-03-05 01:50:20.000000000
+0800
+++ new-gcc-4.4.0/gcc/tree-ssa-loop-prefetch.c 2009-08-14
11:25:53.000000000 +0800
@@ -1459,7 +1459,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;
if (optimize_loop_nest_for_size_p (loop))
{
@@ -1511,13 +1511,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. */
@@ -1525,7 +1532,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. */
--- gcc-4.4.0/gcc/tree-vectorizer.c 2009-03-18 23:29:28.000000000 +0800
+++ new-gcc-4.4.0/gcc/tree-vectorizer.c 2009-08-14 11:26:29.000000000 +0800
@@ -253,7 +253,7 @@ rename_variables_in_loop (struct loop *l
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)
{
----------------------------------
#include <stdlib.h>
extern int length;
extern unsigned short calc_crc (unsigned short data, unsigned short crc);
unsigned short
test (void)
{
int i;
unsigned short crc = 0;
char *image;
image = (char *)malloc (length);
for (i = 0; i < length; i++)
{
crc = calc_crc (image[i], crc);
}
return crc;
}
--------------------------------
But, for this test case, it's an another error.
Program received signal SIGSEGV, Segmentation fault.
0x0840a46d in gimple_bb (g=0x0) at ../../gcc-4.4.0/gcc/gimple.h:1070
1070 return g->gsbase.bb;
(gdb) bt
#0 0x0840a46d in gimple_bb (g=0x0) at ../../gcc-4.4.0/gcc/gimple.h:1070
#1 0x0840b446 in find_uses_to_rename_use (bb=0xb7c5e3c0,
use=0xb7c5a000, use_blocks=0x89befd8, need_phis=0x89b2778)
at ../../gcc-4.4.0/gcc/tree-ssa-loop-manip.c:246
#2 0x0840b60d in find_uses_to_rename_bb (bb=0xb7c5e3c0,
use_blocks=0x89befd8, need_phis=0x89b2778)
at ../../gcc-4.4.0/gcc/tree-ssa-loop-manip.c:297
#3 0x0840b7c1 in find_uses_to_rename (changed_bbs=0x0,
use_blocks=0x89befd8, need_phis=0x89b2778)
at ../../gcc-4.4.0/gcc/tree-ssa-loop-manip.c:327
#4 0x0840b879 in rewrite_into_loop_closed_ssa (changed_bbs=0x0,
update_flag=2048)
at ../../gcc-4.4.0/gcc/tree-ssa-loop-manip.c:387
#5 0x084983f8 in execute_vrp () at ../../gcc-4.4.0/gcc/tree-vrp.c:7249
#6 0x0828d69c in execute_one_pass (pass=0x898fcd0) at
../../gcc-4.4.0/gcc/passes.c:1278
------------------------------------
Seems that use info is not updated.
Eric