Hi!

move_sese_region_to_fn moves a subset of the original loop tree
to the dest_cfun (and adds the outermost loop new).
Now, some loops might have non-zero orig_loop_num field.  In the caller
that is fine, if the orig_loop_num loop is moved, then get_loop will just
return NULL and we'll clear it later.  But if a loop with orig_loop_num != 0
is moved into the dest_cfun, where we create new numbers for the loops,
orig_loop_num might be too large for the larray vector, or might point
to an unrelated loop.

The following patch goes through all the loops moved into dest_cfun and if
they have non-zero orig_loop_num, it tries to remap them into a new number
if it points to a loop that was also moved to dest_cfun, or clears it
otherwise.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2017-12-05  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/81945
        * cfgloop.h (FOR_EACH_LOOP_FN): Use FN instead of hardcoding fn.
        * tree-cfg.c (move_sese_region_to_fn): If any of the loops moved
        to dest_cfun has orig_loop_num set, either remap it to the new
        loop number if the loop got moved too, or clear it.

        * gcc.dg/graphite/pr81945.c: New test.

--- gcc/cfgloop.h.jj    2017-11-27 18:52:20.000000000 +0100
+++ gcc/cfgloop.h       2017-12-05 16:00:07.771838975 +0100
@@ -766,7 +766,7 @@ loop_iterator::~loop_iterator ()
        (LOOP) = li.next ())
 
 #define FOR_EACH_LOOP_FN(FN, LOOP, FLAGS) \
-  for (loop_iterator li(fn, &(LOOP), FLAGS); \
+  for (loop_iterator li(FN, &(LOOP), FLAGS); \
        (LOOP); \
        (LOOP) = li.next ())
 
--- gcc/tree-cfg.c.jj   2017-12-04 20:10:29.000000000 +0100
+++ gcc/tree-cfg.c      2017-12-05 15:54:53.000000000 +0100
@@ -7468,6 +7468,8 @@ move_sese_region_to_fn (struct function
   loops->state = LOOPS_MAY_HAVE_MULTIPLE_LATCHES;
   set_loops_for_fn (dest_cfun, loops);
 
+  vec<loop_p, va_gc> *larray = get_loops (saved_cfun)->copy ();
+
   /* Move the outlined loop tree part.  */
   num_nodes = bbs.length ();
   FOR_EACH_VEC_ELT (bbs, i, bb)
@@ -7514,6 +7516,20 @@ move_sese_region_to_fn (struct function
   loop->aux = current_loops->tree_root;
   loop0->aux = current_loops->tree_root;
 
+  /* Fix up orig_loop_num.  If the block referenced in it has been moved
+     to dest_cfun, update orig_loop_num field, otherwise clear it.  */
+  struct loop *dloop;
+  FOR_EACH_LOOP_FN (dest_cfun, dloop, 0)
+    if (dloop->orig_loop_num)
+      {
+       if ((*larray)[dloop->orig_loop_num] != NULL
+           && get_loop (saved_cfun, dloop->orig_loop_num) == NULL)
+         dloop->orig_loop_num = (*larray)[dloop->orig_loop_num]->num;
+       else
+         dloop->orig_loop_num = 0;
+      }
+  ggc_free (larray);
+
   pop_cfun ();
 
   /* Move blocks from BBS into DEST_CFUN.  */
--- gcc/testsuite/gcc.dg/graphite/pr81945.c.jj  2017-12-05 16:07:12.375610782 
+0100
+++ gcc/testsuite/gcc.dg/graphite/pr81945.c     2017-12-05 16:07:24.925456255 
+0100
@@ -0,0 +1,21 @@
+/* PR tree-optimization/81945 */
+/* { dg-do compile { target pthread } } */
+/* { dg-options "-O3 -ftree-parallelize-loops=2 -floop-nest-optimize" } */
+
+unsigned long int v;
+
+void
+foo (int x, int y, long int *a)
+{
+  do
+    {
+      int **b;
+
+      while (y != 0)
+        ;
+      v *= 2;
+      **b = *a;
+      ++x;
+    }
+  while (x < 1);
+}

        Jakub

Reply via email to