2009/8/13 Sebastian Pop <seb...@gmail.com>:

> 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

Reply via email to