On Wed, 19 Feb 2014, Bin.Cheng wrote:

> Hi Richard,
> Does this have to wait for stage 1? Or I will try to work out a full
> patch with loop recreating issue fixed.

If it is a regression and there is a bugzilla about it it doesn't
have to wait.

The patch should be complete (but is untested yet)

> On Wed, Feb 19, 2014 at 7:57 PM, Richard Biener <rguent...@suse.de> wrote:
> >
> > This allows cfgcleanup to remove some of the extra CFG that exists
> > just for loop analysis passes convenience (those can be and are
> > easily re-created by passes doing loop_optimizer_init ()).
> >
> > It may fix a regression uncovered in private communication.
> It's the regression about the code size checks in
> gcc.target/arm/ivopts.c and gcc.target/arm/ivopts-2.c

I see.  So it is a regression then.

> >
> > Untested - my original idea how to fix this (tree_forwarder_block_p
> > hunk) ran into the issue in remove_forwarder_block which causes
> > loops to be removed / re-discovered (losing meta-data).
> >
> > Richard.
> >
> > 2014-02-19  Richard Biener  <rguent...@suse.de>
> >
> >         * tree-cfgcleanup.c (tree_forwarder_block_p): Protect
> >         latches and preheaders only if requested.
> >         (remove_forwarder_block): Update loop structure if we
> >         removed a forwarder that is a loop latch.
> >
> > Index: gcc/tree-cfgcleanup.c
> > ===================================================================
> > *** gcc/tree-cfgcleanup.c       (revision 207878)
> > --- gcc/tree-cfgcleanup.c       (working copy)
> > *************** tree_forwarder_block_p (basic_block bb,
> > *** 307,321 ****
> >
> >     if (current_loops)
> >       {
> > !       basic_block dest;
> > !       /* Protect loop latches, headers and preheaders.  */
> >         if (bb->loop_father->header == bb)
> >         return false;
> > -       dest = EDGE_SUCC (bb, 0)->dest;
> >
> > !       if (dest->loop_father->header == dest)
> >         return false;
> >       }
> >     return true;
> >   }
> >
> > --- 307,324 ----
> >
> >     if (current_loops)
> >       {
> > !       /* Protect loop headers.  */
> >         if (bb->loop_father->header == bb)
> >         return false;
> >
> > !       /* Protect loop latches and preheaders if requested.  */
> > !       basic_block dest = EDGE_SUCC (bb, 0)->dest;
> > !       if (dest->loop_father->header == dest
> > !         && (loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS)
> > !             || loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES)))
> >         return false;
> >       }
> Sorry for being nit-picking here. There is a scenario that bb is
> pre-header and loop prop is set to (!LOOPS_HAVE_PREHEADERS &&
> LOOPS_HAVE_SIMPLE_LATCHES).  Of course, this may not happen anyway.

Yeah, but then we'd have to detect whether this is a preheader
forwarder or a latch forwarder.  I doubt it happens right now
so I thought it doesn't matter to do it like above.

> > +
> >     return true;
> >   }
> >
> > *************** remove_forwarder_block (basic_block bb)
> > *** 497,503 ****
> >         set_immediate_dominator (CDI_DOMINATORS, dest, dom);
> >       }
> >
> > !   /* And kill the forwarder block.  */
> >     delete_basic_block (bb);
> >
> >     return true;
> > --- 500,511 ----
> >         set_immediate_dominator (CDI_DOMINATORS, dest, dom);
> >       }
> >
> > !   /* And kill the forwarder block, but first adjust its parent loop
> > !      latch info as otherwise the cfg hook has a hard time not to
> > !      kill the loop.  */
> > !   if (current_loops
> > !       && bb->loop_father->latch == bb)
> > !     bb->loop_father->latch = dest;
> >     delete_basic_block (bb);
> By this code, do you mean to prevent cfgcleanup from
> removing/rebuilding the loop struct?

Yes.  It prevents triggering cfghooks.c:

void
delete_basic_block (basic_block bb)
{
...
      /* If we remove the header or the latch of a loop, mark the loop for
         removal by setting its header and latch to NULL.  */
      if (loop->latch == bb
          || loop->header == bb)
        {
          loop->header = NULL;
          loop->latch = NULL;
          loops_state_set (LOOPS_NEED_FIXUP);

generally delete_basic_block has too little context to work out
anything more specific than the above (so it's a very bad tool ;))

Richard.

> >
> >     return true;
> 
> Thanks,
> bin
> 

Reply via email to