re PR middle-end/37943 ([graphite] ICE : in build_graphite_scops, at graphite.c:1823)
authorTobias Grosser <grosser@fim.uni-passau.de>
Wed, 5 Nov 2008 04:45:49 +0000 (04:45 +0000)
committerTobias Grosser <grosser@gcc.gnu.org>
Wed, 5 Nov 2008 04:45:49 +0000 (04:45 +0000)
2008-11-05  Tobias Grosser  <grosser@fim.uni-passau.de>

PR middle-end/37943

* graphite.c (scopdet_basic_block_info): Fix loops with multiple
exits and conditions.
* testsuite/gcc.dg/graphite/pr37943.c: New.

From-SVN: r141598

ChangeLog
gcc/graphite.c
gcc/testsuite/gcc.dg/graphite/pr37943.c [new file with mode: 0644]

index 9d823e2..d3079e9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2008-11-05  Tobias Grosser  <grosser@fim.uni-passau.de>
+
+       PR middle-end/37943
+
+       * graphite.c (scopdet_basic_block_info): Fix loops with multiple
+       exits and conditions.
+       * testsuite/gcc.dg/graphite/pr37943.c: New.
+
 2008-11-04  Thomas Schwinge  <tschwinge@gnu.org>
 
        * MAINTAINERS (Write after approval): Add myself. 
index 90d8230..7df3028 100644 (file)
@@ -1326,11 +1326,29 @@ scopdet_basic_block_info (basic_block bb, VEC (sd_region, heap) **scops,
         int i;
         build_scops_1 (bb, &tmp_scops, loop);
 
-       /* XXX: Use 'e->src' ot better 'bb'?  */
+
+       /* Start at all bbs dominated by a loop exit that only exists in this
+          loop.  */ 
         for (i = 0; VEC_iterate (edge, exits, i, e); i++)
-          if (dominated_by_p (CDI_DOMINATORS, e->dest, e->src)
-              && e->src->loop_father == loop)
-            build_scops_1 (e->dest, &tmp_scops, e->dest->loop_father);
+          if (e->src->loop_father == loop)
+            {  
+             VEC (basic_block, heap) *dominated;
+             basic_block b;
+             int j;
+             dominated = get_dominated_by (CDI_DOMINATORS, e->src);
+             for (j = 0; VEC_iterate (basic_block, dominated, j, b); j++)
+               /* Loop exit.  */
+               if (loop_depth (find_common_loop (loop, b->loop_father))
+                   < loop_depth (loop))
+                 {
+                   /* Pass loop_outer to recognize b as loop header in
+                      build_scops_1.  */
+                   if (b->loop_father->header == b)
+                     build_scops_1 (b, &tmp_scops, loop_outer (b->loop_father));
+                   else
+                     build_scops_1 (b, &tmp_scops, b->loop_father);
+                 }
+           }
 
         result.next = NULL; 
         result.last = NULL;
@@ -1440,7 +1458,8 @@ scopdet_basic_block_info (basic_block bb, VEC (sd_region, heap) **scops,
        for (i = 0; VEC_iterate (basic_block, dominated, i, dom_bb); i++)
          {
            /* Ignore loop exits: they will be handled after the loop body.  */
-           if (is_loop_exit (loop, dom_bb))
+           if (loop_depth (find_common_loop (loop, dom_bb->loop_father))
+               < loop_depth (loop))
              {
                result.exits = true;
                continue;
@@ -1790,7 +1809,6 @@ create_sese_edges (VEC (sd_region, heap) *regions)
   int i;
   sd_region *s;
 
-
   for (i = 0; VEC_iterate (sd_region, regions, i, s); i++)
     create_single_entry_edge (s);
 
diff --git a/gcc/testsuite/gcc.dg/graphite/pr37943.c b/gcc/testsuite/gcc.dg/graphite/pr37943.c
new file mode 100644 (file)
index 0000000..f8ec28d
--- /dev/null
@@ -0,0 +1,31 @@
+/* { dg-options "-O3 -fgraphite-identity -fdump-tree-graphite-all" } */
+
+typedef struct
+{
+      int mode,state,num,state_out;
+      unsigned char* bits;
+      char *out;
+}test;
+unsigned char copy( test* s )
+{
+   while(1)
+     {
+      if (s->mode == 0) break;
+      if (s->state_out >= s->num) break;
+      *(s->out) = s->bits[s->state_out];
+      if (s->mode == 0) s->mode++;
+     }
+}
+unsigned char compress(test *in)
+{
+   unsigned char p_in, p_out;
+   while(1)
+   {
+      if (in->state == 1) 
+      {
+         p_out |= copy(in);
+         if (in->state_out < in->num) break;
+      }
+   }
+   return p_in || p_out;
+