On Fri, Feb 28, 2014 at 9:42 AM, H.J. Lu <hjl.to...@gmail.com> wrote: > On Fri, Feb 28, 2014 at 9:25 AM, H.J. Lu <hjl.to...@gmail.com> wrote: >> On Fri, Feb 28, 2014 at 8:11 AM, H.J. Lu <hjl.to...@gmail.com> wrote: >>> On Fri, Feb 28, 2014 at 2:09 AM, Richard Biener >>> <richard.guent...@gmail.com> wrote: >>>> On Fri, Feb 28, 2014 at 10:09 AM, Richard Biener >>>> <richard.guent...@gmail.com> wrote: >>>>> On Fri, Feb 28, 2014 at 1:52 AM, H.J. Lu <hjl.to...@gmail.com> wrote: >>>>>> On Mon, Feb 24, 2014 at 9:12 PM, bin.cheng <bin.ch...@arm.com> wrote: >>>>>>> Hi, >>>>>>> This patch is to fix regression reported in PR60280 by removing forward >>>>>>> loop >>>>>>> headers/latches in cfg cleanup if possible. Several tests are broken by >>>>>>> this change since cfg cleanup is shared by all optimizers. Some tests >>>>>>> has >>>>>>> already been fixed by recent patches, I went through and fixed the >>>>>>> others. >>>>>>> One case needs to be clarified is "gcc.dg/tree-prof/update-loopch.c". >>>>>>> When >>>>>>> GCC removing a basic block, it checks profile information by calling >>>>>>> check_bb_profile after redirecting incoming edges of the bb. This >>>>>>> certainly >>>>>>> results in warnings about invalid profile information and causes the >>>>>>> case to >>>>>>> fail. I will send a patch to skip checking profile information for a >>>>>>> removing basic block in stage 1 if it sounds reasonable. For now I just >>>>>>> twisted the case itself. >>>>>>> >>>>>>> Bootstrap and tested on x86_64 and arm_a15. >>>>>>> >>>>>>> Is it OK? >>>>>>> >>>>>>> >>>>>>> 2014-02-25 Bin Cheng <bin.ch...@arm.com> >>>>>>> >>>>>>> PR target/60280 >>>>>>> * tree-cfgcleanup.c (tree_forwarder_block_p): Protect loop >>>>>>> preheaders and latches only if requested. Fix latch if it >>>>>>> is removed. >>>>>>> * tree-ssa-dom.c (tree_ssa_dominator_optimize): Set >>>>>>> LOOPS_HAVE_PREHEADERS. >>>>>>> >>>>>> >>>>>> This change: >>>>>> >>>>>> if (dest->loop_father->header == dest) >>>>>> - return false; >>>>>> + { >>>>>> + if (loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS) >>>>>> + && bb->loop_father->header != dest) >>>>>> + return false; >>>>>> + >>>>>> + if (loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES) >>>>>> + && bb->loop_father->header == dest) >>>>>> + return false; >>>>>> + } >>>>>> } >>>>>> >>>>>> miscompiled 435.gromacs in SPEC CPU 2006 on x32 with >>>>>> >>>>>> -O3 -funroll-loops -ffast-math -fwhole-program -flto=jobserver >>>>>> -fuse-linker-plugin >>>>>> >>>>>> This patch changes loops without LOOPS_HAVE_PREHEADERS >>>>>> nor LOOPS_HAVE_SIMPLE_LATCHES from returning false to returning >>>>>> true. I don't have a small testcase. But this patch: >>>>>> >>>>>> diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c >>>>>> index b5c384b..2ba673c 100644 >>>>>> --- a/gcc/tree-cfgcleanup.c >>>>>> +++ b/gcc/tree-cfgcleanup.c >>>>>> @@ -323,6 +323,10 @@ tree_forwarder_block_p (basic_block bb, bool >>>>>> phi_wanted) >>>>>> if (loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES) >>>>>> && bb->loop_father->header == dest) >>>>>> return false; >>>>>> + >>>>>> + if (!loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS) >>>>>> + && !loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES)) >>>>>> + return false; >>>>>> } >>>>>> } >>>>>> >>>>>> fixes the regression. Does it make any senses? >>>>> >>>>> I think the preheader test isn't fully correct (bb may be in an inner loop >>>>> for example). So a more conservative variant would be >>>>> >>>>> Index: gcc/tree-cfgcleanup.c >>>>> =================================================================== >>>>> --- gcc/tree-cfgcleanup.c (revision 208169) >>>>> +++ gcc/tree-cfgcleanup.c (working copy) >>>>> @@ -316,13 +316,13 @@ tree_forwarder_block_p (basic_block bb, >>>>> /* Protect loop preheaders and latches if requested. */ >>>>> if (dest->loop_father->header == dest) >>>>> { >>>>> - if (loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS) >>>>> - && bb->loop_father->header != dest) >>>>> - return false; >>>>> - >>>>> - if (loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES) >>>>> - && bb->loop_father->header == dest) >>>>> - return false; >>>>> + if (bb->loop_father == dest->loop_father) >>>>> + return !loops_state_satisfies_p (LOOPS_HAVE_SIMPLE_LATCHES); >>>>> + else if (bb->loop_father == loop_outer (dest->loop_father)) >>>>> + return !loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS); >>>>> + /* Always preserve other edges into loop headers that are >>>>> + not simple latches or preheaders. */ >>>>> + return false; >>>>> } >>>>> } >>>>> >>>>> that makes sure we can properly update loop information. It's also >>>>> a more conservative change at this point which should still successfully >>>>> remove simple latches and preheaders created by loop discovery. >>>> >>>> I think the patch makes sense anyway and thus I'll install it once it >>>> passed bootstrap / regtesting. >>>> >>>> Another fix that may make sense is to restrict it to >>>> !loops_state_satisfies_p (LOOPS_NEED_FIXUP), though cfgcleanup >>>> itself can end up setting that ... which we eventually should fix if it >>>> still happens. That is, check if >>>> >>>> Index: gcc/tree-cfgcleanup.c >>>> =================================================================== >>>> --- gcc/tree-cfgcleanup.c (revision 208169) >>>> +++ gcc/tree-cfgcleanup.c (working copy) >>>> >>>> @@ -729,8 +729,9 @@ cleanup_tree_cfg_noloop (void) >>>> >>>> timevar_pop (TV_TREE_CLEANUP_CFG); >>>> >>>> - if (changed && current_loops) >>>> - loops_state_set (LOOPS_NEED_FIXUP); >>>> + if (changed && current_loops >>>> + && !loops_state_satisfies_p (LOOPS_NEED_FIXUP)) >>>> + verify_loop_structure (); >>>> >>>> return changed; >>>> } >>>> >>>> trips anywhere (and apply fixes). That's of course not appropriate at >>>> this stage. >>>> >>>>> Does it fix 435.gromacs? >>> >>> I tried revision 208222 and it doesn't fix 435.gromacs. >> >> Remove >> >> else if (bb->loop_father == loop_outer (dest->loop_father)) >> return !loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS); > > Should we also check other loop state, like LOOPS_HAVE_SIMPLE_LATCHES > or LOOPS_MAY_HAVE_MULTIPLE_LATCHES here? >
This patch: diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index 926d300..fb1c63d 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -328,7 +328,9 @@ tree_forwarder_block_p (basic_block bb, bool phi_wanted) (LOOPS_MAY_HAVE_MULTIPLE_LATCHES)); } else if (bb->loop_father == loop_outer (dest->loop_father)) - return !loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS); + return (!loops_state_satisfies_p (LOOPS_HAVE_PREHEADERS) + && !loops_state_satisfies_p + (LOOPS_MAY_HAVE_MULTIPLE_LATCHES)); /* Always preserve other edges into loop headers that are not simple latches or preheaders. */ return false; works. Does it look right? -- H.J.