[Bug tree-optimization/52548] missed PRE optimization when function call follows to-be hoisted variable

rguenth at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Mon Mar 12 09:50:00 GMT 2012


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52548

Richard Guenther <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|alias                       |missed-optimization
          Component|middle-end                  |tree-optimization

--- Comment #2 from Richard Guenther <rguenth at gcc dot gnu.org> 2012-03-12 09:50:05 UTC ---
(In reply to comment #1)
> (In reply to comment #0)
> 
> > The bark() function call is in the same basic block as "z = hoist + 4".  I wild
> > guess is that "hoist" isn't anticipatable at the *end* of the BB beginning with
> > "z = hoist + 4".  Splitting BB's at function calls may improve PRE.  Just a
> > guess...
> 
> What is anticipated at the end of BB is uninteresting. It is computed but not
> stored (only needed to compute ANTIC_IN, see compute_antic_aux).
> 
> You can check the ANTIC sets and AVAIL_OUT set with -fdump-tree-pre-details.
> The value for the expression "hoist+4" should be in EXP_GEN of the basic block
> with the call, and in AVAIL_OUT of the basic block with "y=hoist+4". But this
> isn't the case here:
> * the value representative for "y=hoist+4" is y.2_3->"{plus_expr,hoist.1_2,4}"
> * the value representative for "z=hoist+4" is y.2_5->"{plus_expr,hoist.1_2,4}"
>   (the name of the representative is y instead of z, probably due to
> copyrename)
> * SCCVN finds "Value numbers:(...)y.2_5=y.2_3, as expected
> * y.2_3 is in AVAIL_OUT of the then-block, as expected
> * {plus_expr,hoist.1_2,4} is in EXP_GEN of the block with the call, as expected
> * {plus_expr,hoist.1_2,4} is *not* in ANTIC_IN of the block with the call!
> 
> This is strange because ANTIC_IN = ANTIC_OUT U EXP_GEN - TMP_GEN

That's simply because ANTIC_IN in reality is clean (ANTIC_OUT U EXP_GEN -
TMP_GEN) and clean () removes all values that are clobbered in that block
(and EXP_GEN is at BB granularity, so inside-BB flow is ignored).

Thus indeed, splitting blocks can improve things here, as would
on-the-fly construction of EXP_GEN/TMP_GEN and doing clean () on its
way when we compute ANTIC_IN.  Of course that would be more expensive
if we are iterating.

Note that the way we clean () for memory PRE is ugly anyway, probably
not really envisioned by the original paper (which I bet didn't deal
with aliasing ...)



More information about the Gcc-bugs mailing list