http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52548
Steven Bosscher <steven at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Last reconfirmed| |2012-03-10
CC| |steven at gcc dot gnu.org
Ever Confirmed|0 |1
--- Comment #1 from Steven Bosscher <steven at gcc dot gnu.org> 2012-03-10
00:15:12 UTC ---
(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
Function foo() at the .084.pre dump:
foo ()
{
int y.2;
int hoist.1;
int flag.0;
<bb 2>:
flag.0_1 = flag;
if (flag.0_1 != 0)
goto <bb 3>;
else
goto <bb 4>;
<bb 3>:
hoist.1_2 = hoist;
y.2_3 = hoist.1_2 + 4;
y = y.2_3;
goto <bb 5>;
<bb 4>:
flag = 888;
<bb 5>:
hoist.1_4 = hoist;
y.2_5 = hoist.1_4 + 4;
z = y.2_5;
bark ();
return;
}
Value numbers:
hoist.1_4 = hoist.1_2
y.2_5 = y.2_3
All the sets that are computed without iterations:
exp_gen[0] := { } // BB0 is ENTRY_BLOCK
phi_gen[0] := { }
tmp_gen[0] := { }
avail_out[0] := { }
exp_gen[2] := { {mem_ref<0B>,addr_expr<&flag>}@.MEM_7(D) (0002) }
phi_gen[2] := { }
tmp_gen[2] := { flag.0_1 (0002) }
avail_out[2] := { flag.0_1 (0002) }
exp_gen[3] := { {mem_ref<0B>,addr_expr<&hoist>}@.MEM_7(D) (0003),
{plus_expr,hoist.1_2,4} (0004) }
phi_gen[3] := { }
tmp_gen[3] := { hoist.1_2 (0003), y.2_3 (0004) }
avail_out[3] := { flag.0_1 (0002), hoist.1_2 (0003), y.2_3 (0004) }
exp_gen[4] := { }
phi_gen[4] := { }
tmp_gen[4] := { }
avail_out[4] := { flag.0_1 (0002) }
exp_gen[5] := { {mem_ref<0B>,addr_expr<&hoist>}@.MEM_7(D) (0003),
{plus_expr,hoist.1_2,4} (0004) }
phi_gen[5] := { }
tmp_gen[5] := { hoist.1_4 (0003), y.2_5 (0004) }
avail_out[5] := { flag.0_1 (0002), hoist.1_4 (0003), y.2_5 (0004) }
exp_gen[1] := { }
phi_gen[1] := { }
tmp_gen[1] := { }
avail_out[1] := { } // BB1 is EXIT_BLOCK
Starting iteration 0
ANTIC_OUT[5] := { }
ANTIC_IN[5] := { }
S[5] := { }
ANTIC_OUT[4] := { }
ANTIC_IN[4] := { }
S[4] := { }
ANTIC_OUT[3] := { }
ANTIC_IN[3] := { {mem_ref<0B>,addr_expr<&hoist>}@.MEM_7(D) (0003),
{plus_expr,hoist.1_2,4} (0004) }
S[3] := { }
ANTIC_OUT[2] := { }
ANTIC_IN[2] := { {mem_ref<0B>,addr_expr<&flag>}@.MEM_7(D) (0002) }
S[2] := { }
Starting iteration 1
ANTIC_OUT[3] := { }
ANTIC_IN[3] := { {mem_ref<0B>,addr_expr<&hoist>}@.MEM_7(D) (0003),
{plus_expr,hoist.1_2,4} (0004) }
S[3] := { }
ANTIC_OUT[2] := { }
ANTIC_IN[2] := { {mem_ref<0B>,addr_expr<&flag>}@.MEM_7(D) (0002) }
S[2] := { }