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] := { }