https://gcc.gnu.org/bugzilla/show_bug.cgi?id=126664
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |hubicka at gcc dot gnu.org,
| |rguenth at gcc dot gnu.org
--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
do
{
# COUNT A
if (cond)
{
COUNT B
if (invariant-cond)
COUNT C
else
COUNT D
}
}
while (...)
So when unswitching unswitches the invariant-cond condition it places it
outside of the dominating cond condition. There is no way to update
the profile reliably since we do not actually know how invariant-cond
depends on [a possibly invariant part of] cond. Profile-updates are
usually argued about in terms of counts, not branch probablities btw,
so the above becomes
if (invariant-cond)
do
{
NEW COUNT A
if (cond)
NEW_COUNT B
}
while (...);
else
do
{
NEW COUNT A'
if (cond)
NEW_COUNT B'
}
while (...);
the current behavior to preserve the original probabilities is correct
iff the cond and invariant-cond conditions are independent which is
a reasonable guess given one is invariant and one is not (but unswitching
can also have an invariant 'cond' it refuses to unswitch, where dependence
might be more probable).
But as said, I don't see a good way to update counters in case of a dependence
because we can't quantify that. So in this case a reset to 50:50 might be
more reasonable. It might be also a reasonable default stance.
I'll note the 0.0% probability looks like a bug. I first see it in
threadfull1,
but as
Removing basic block 60
;; basic block 60, loop depth 1
;; pred:
# iftmp.7_249 = PHI <>
dslv_e_250 = dslv_e_248 * iftmp.7_249;
_251 = r_radij_128 * distij_232;
_252 = 1.0e+0 - _251;
if (distbb_233 < 0.0)
goto <bb 62>; [100.00%]
else
goto <bb 61>; [0.00%]
;; succ: 62
;; 61
but the preceeding pass ends with
if (distbb_233 < 0.0)
goto <bb 62>; [41.00%]
else
goto <bb 61>; [59.00%]
this might be an artifact of CFG cleanup and the way it removes dominated
blocks.
Then after dom2 we have
;; basic block 15, loop depth 1, count 186884766 (estimated locally, freq
2.8164), maybe hot
;; Invalid sum of incoming counts 182536109 (estimated locally, freq 2.7509),
should be 186884766 (estimated locally, freq 2.8164)
;; prev block 14, next block 16, flags: (NEW, VISITED)
;; pred: 11 [68.0% (guessed)] count:182536109 (estimated locally,
freq 2.7509) (FALSE_VALUE,EXECUTABLE)
# l_hphb_282 = PHI <l_params$hphb_187(11)>
if (_41 != 0)
goto <bb 14>; [0.00%]
else
goto <bb 16>; [100.00%]
;; succ: 14 [never (guessed)] count:0 (estimated locally, freq
0.0000) (TRUE_VALUE,EXECUTABLE)
;; 16 [always (guessed)] count:186884766 (estimated locally,
freq 2.8164) (FALSE_VALUE,EXECUTABLE)
tracking down the way we arrive at 0/100% during DOM would be interesting.
The update is done via
#8 0x0000000002311872 in update_profile (
epath=<edge 0x7ffff6715fc0 (15 -> 14)>,
edup=<edge 0x7ffff67233b8 (30 -> 16)>, path_in_count=...,
path_out_count=...)
at /space/rguenther/src/gcc-clean/gcc/tree-ssa-threadupdate.cc:1006
#9 0x0000000002311bef in ssa_fix_duplicate_block_edges (rd=0x5b09770,
local_info=0x7fffffffd440)
at /space/rguenther/src/gcc-clean/gcc/tree-ssa-threadupdate.cc:1128
--Type <RET> for more, q to quit, c to continue without paging--
#10 0x000000000231639e in ssa_fixup_template_block (slot=0x5ae85b0,
local_info=0x7fffffffd440)
at /space/rguenther/src/gcc-clean/gcc/tree-ssa-threadupdate.cc:1308
#11 0x0000000002317560 in hash_table<redirection_data, false,
xcallocator>::traverse_noresize<ssa_local_info_t*,
&(ssa_fixup_template_block(redirection_data**, ssa_local_info_t*))>
(this=0x5b0bbc0, argument=0x7fffffffd440)
at /space/rguenther/src/gcc-clean/gcc/hash-table.h:1173
#12 0x0000000002316837 in hash_table<redirection_data, false,
xcallocator>::traverse<ssa_local_info_t*,
&(ssa_fixup_template_block(redirection_data**, ssa_local_info_t*))>
(this=0x5b0bbc0, argument=0x7fffffffd440)
at /space/rguenther/src/gcc-clean/gcc/hash-table.h:1194
#13 0x0000000002312bdd in fwd_jt_path_registry::thread_block_1 (
this=0x59da380, bb=<basic_block 0x7ffff6720ba0 (15)>, noloop_only=true,
joiners=false)
at /space/rguenther/src/gcc-clean/gcc/tree-ssa-threadupdate.cc:1581
0x0000000002311872 in update_profile (epath=<edge 0x7ffff6715fc0 (15 -> 14)>,
edup=<edge 0x7ffff67233b8 (30 -> 16)>, path_in_count=...,
path_out_count=...)
at /space/rguenther/src/gcc-clean/gcc/tree-ssa-threadupdate.cc:1006
1006 epath->probability = epath_prob;
(gdb) p epath_prob.debug()
never (guessed)
because 'final_count' is 0.
(gdb) p epath->count().debug()
0 (estimated locally, freq 0.0000)
(gdb) p path_out_count.debug()
129869073 (estimated locally, freq 1.9572)
and zero minus something is GIGO, yielding zero. The CFG at this point
is broken, there's unreachable blocks (edup->src).
epath.probability is originally 41%, path_in_count and path_out_count
are equal, leading to edup_prob being always.
Maybe a typo?
diff --git a/gcc/tree-ssa-threadupdate.cc b/gcc/tree-ssa-threadupdate.cc
index db3520b42fc..c8e165891ff 100644
--- a/gcc/tree-ssa-threadupdate.cc
+++ b/gcc/tree-ssa-threadupdate.cc
@@ -1126,7 +1126,7 @@ ssa_fix_duplicate_block_edges (struct redirection_data
*rd,
been updated at the end of that handling to the edge frequency
along the duplicated joiner path edge. */
update_profile (epath, EDGE_SUCC (rd->dup_blocks[count], 0),
- path_out_count, path_out_count);
+ path_in_count, path_out_count);
}
else
{
but the else case also has (but no edup passed there)
update_profile (epath, NULL, path_out_count, path_out_count);
Honza?