This fixes another case of bogus initial schedule generated by GRAPHITE.
Rather than adding my own RPO computation routine I am swapping the
edges in the edge vector containing loop exits...  not exactly nice
but sufficient.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2018-01-09  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/83668
        * graphite.c (canonicalize_loop_closed_ssa): Add edge argument,
        move prologue...
        (canonicalize_loop_form): ... here, renamed from ...
        (canonicalize_loop_closed_ssa_form): ... this and amended to
        swap successor edges for loop exit blocks to make us use
        the RPO order we need for initial schedule generation.

        * gcc.dg/graphite/pr83668.c: New testcase.

Index: gcc/graphite.c
===================================================================
--- gcc/graphite.c      (revision 256372)
+++ gcc/graphite.c      (working copy)
@@ -227,15 +227,11 @@ free_scops (vec<scop_p> scops)
 /* Transforms LOOP to the canonical loop closed SSA form.  */
 
 static void
-canonicalize_loop_closed_ssa (loop_p loop)
+canonicalize_loop_closed_ssa (loop_p loop, edge e)
 {
-  edge e = single_exit (loop);
   basic_block bb;
   gphi_iterator psi;
 
-  if (!e || (e->flags & EDGE_COMPLEX))
-    return;
-
   bb = e->dest;
 
   /* Make the loop-close PHI node BB contain only PHIs and have a
@@ -314,14 +310,34 @@ canonicalize_loop_closed_ssa (loop_p loo
    other statements.
 
    - there exist only one phi node per definition in the loop.
+
+   In addition to that we also make sure that loop exit edges are
+   first in the successor edge vector.  This is to make RPO order
+   as computed by pre_and_rev_post_order_compute be consistent with
+   what initial schedule generation expects.
 */
 
 static void
-canonicalize_loop_closed_ssa_form (void)
+canonicalize_loop_form (void)
 {
   loop_p loop;
   FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
-    canonicalize_loop_closed_ssa (loop);
+    {
+      edge e = single_exit (loop);
+      if (!e || (e->flags & EDGE_COMPLEX))
+       continue;
+
+      canonicalize_loop_closed_ssa (loop, e);
+
+      /* If the exit is not first in the edge vector make it so.  */
+      if (e != EDGE_SUCC (e->src, 0))
+       {
+         unsigned ei;
+         for (ei = 0; EDGE_SUCC (e->src, ei) != e; ++ei)
+           ;
+         std::swap (EDGE_SUCC (e->src, ei), EDGE_SUCC (e->src, 0));
+       }
+    }
 
   /* We can end up releasing duplicate exit PHIs and also introduce
      additional copies so the cached information isn't correct anymore.  */
@@ -360,7 +376,7 @@ graphite_transform_loops (void)
   the_isl_ctx = ctx;
 
   sort_sibling_loops (cfun);
-  canonicalize_loop_closed_ssa_form ();
+  canonicalize_loop_form ();
 
   /* Print the loop structure.  */
   if (dump_file && (dump_flags & TDF_DETAILS))
Index: gcc/testsuite/gcc.dg/graphite/pr83668.c
===================================================================
--- gcc/testsuite/gcc.dg/graphite/pr83668.c     (nonexistent)
+++ gcc/testsuite/gcc.dg/graphite/pr83668.c     (working copy)
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+/* { dg-options "-O -fno-tree-dominator-opts -fgraphite-identity" } */
+
+int a, b, c;
+int d[14];
+
+int
+main (void)
+{
+  short e;
+  char f;
+
+  for (; b >= 0; b--)
+    {
+      e = 0;
+      for (; e < 2; e++)
+       {
+         a = 0;
+         for (; a < 7; a++)
+           d[a] = 1;
+       }
+      if (c)
+       {
+         f = 0;
+         for (; f >= 0; f--)
+           ;
+       }
+    }
+
+  if (a != 7)
+    __builtin_abort ();
+
+  return 0;
+}

Reply via email to