On December 5, 2017 10:05:43 PM GMT+01:00, Jakub Jelinek <ja...@redhat.com> wrote: >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?
OK. I suppose if we ever encounter this in inlining we need sth similar there. Richard. >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