re PR ipa/63576 (ICE : in ipa_merge_profiles, at ipa-utils.c:540 during Firefox LTO/PGO build)
PR ipa/63576 * ipa-utils.c (ipa_merge_profiles): Merge speculative edges. From-SVN: r219910
This commit is contained in:
parent
bb1e543c64
commit
befb1f36a7
@ -1,3 +1,8 @@
|
||||
2015-01-19 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
PR ipa/63576
|
||||
* ipa-utils.c (ipa_merge_profiles): Merge speculative edges.
|
||||
|
||||
2015-01-19 Jan Hubicka <hubicka@ucw.cz>
|
||||
|
||||
PR lto/45375
|
||||
|
@ -539,7 +539,7 @@ ipa_merge_profiles (struct cgraph_node *dst,
|
||||
}
|
||||
if (match)
|
||||
{
|
||||
struct cgraph_edge *e;
|
||||
struct cgraph_edge *e, *e2;
|
||||
basic_block srcbb, dstbb;
|
||||
|
||||
/* TODO: merge also statement histograms. */
|
||||
@ -562,19 +562,95 @@ ipa_merge_profiles (struct cgraph_node *dst,
|
||||
pop_cfun ();
|
||||
for (e = dst->callees; e; e = e->next_callee)
|
||||
{
|
||||
gcc_assert (!e->speculative);
|
||||
if (e->speculative)
|
||||
continue;
|
||||
e->count = gimple_bb (e->call_stmt)->count;
|
||||
e->frequency = compute_call_stmt_bb_frequency
|
||||
(dst->decl,
|
||||
gimple_bb (e->call_stmt));
|
||||
}
|
||||
for (e = dst->indirect_calls; e; e = e->next_callee)
|
||||
for (e = dst->indirect_calls, e2 = src->indirect_calls; e;
|
||||
e2 = (e2 ? e2->next_callee : NULL), e = e->next_callee)
|
||||
{
|
||||
gcc_assert (!e->speculative);
|
||||
e->count = gimple_bb (e->call_stmt)->count;
|
||||
e->frequency = compute_call_stmt_bb_frequency
|
||||
(dst->decl,
|
||||
gimple_bb (e->call_stmt));
|
||||
gcov_type count = gimple_bb (e->call_stmt)->count;
|
||||
int freq = compute_call_stmt_bb_frequency
|
||||
(dst->decl,
|
||||
gimple_bb (e->call_stmt));
|
||||
/* When call is speculative, we need to re-distribute probabilities
|
||||
the same way as they was. This is not really correct because
|
||||
in the other copy the speculation may differ; but probably it
|
||||
is not really worth the effort. */
|
||||
if (e->speculative)
|
||||
{
|
||||
cgraph_edge *direct, *indirect;
|
||||
cgraph_edge *direct2 = NULL, *indirect2 = NULL;
|
||||
ipa_ref *ref;
|
||||
|
||||
e->speculative_call_info (direct, indirect, ref);
|
||||
gcc_assert (e == indirect);
|
||||
if (e2 && e2->speculative)
|
||||
e2->speculative_call_info (direct2, indirect2, ref);
|
||||
if (indirect->count || direct->count)
|
||||
{
|
||||
/* We should mismatch earlier if there is no matching
|
||||
indirect edge. */
|
||||
if (!e2)
|
||||
{
|
||||
if (dump_file)
|
||||
fprintf (dump_file,
|
||||
"Mismatch in merging indirect edges\n");
|
||||
}
|
||||
else if (!e2->speculative)
|
||||
indirect->count += e2->count;
|
||||
else if (e2->speculative)
|
||||
{
|
||||
if (DECL_ASSEMBLER_NAME (direct2->callee->decl)
|
||||
!= DECL_ASSEMBLER_NAME (direct->callee->decl))
|
||||
{
|
||||
if (direct2->count >= direct->count)
|
||||
{
|
||||
direct->redirect_callee (direct2->callee);
|
||||
indirect->count += indirect2->count
|
||||
+ direct->count;
|
||||
direct->count = direct2->count;
|
||||
}
|
||||
else
|
||||
indirect->count += indirect2->count + direct2->count;
|
||||
}
|
||||
else
|
||||
{
|
||||
direct->count += direct2->count;
|
||||
indirect->count += indirect2->count;
|
||||
}
|
||||
}
|
||||
int prob = RDIV (direct->count * REG_BR_PROB_BASE ,
|
||||
direct->count + indirect->count);
|
||||
direct->frequency = RDIV (freq * prob, REG_BR_PROB_BASE);
|
||||
indirect->frequency = RDIV (freq * (REG_BR_PROB_BASE - prob),
|
||||
REG_BR_PROB_BASE);
|
||||
}
|
||||
else
|
||||
/* At the moment we should have only profile feedback based
|
||||
speculations when merging. */
|
||||
gcc_unreachable ();
|
||||
}
|
||||
else if (e2->speculative)
|
||||
{
|
||||
cgraph_edge *direct, *indirect;
|
||||
ipa_ref *ref;
|
||||
|
||||
e2->speculative_call_info (direct, indirect, ref);
|
||||
e->count = count;
|
||||
e->frequency = freq;
|
||||
int prob = RDIV (direct->count * REG_BR_PROB_BASE, e->count);
|
||||
e->make_speculative (direct->callee, direct->count,
|
||||
RDIV (freq * prob, REG_BR_PROB_BASE));
|
||||
}
|
||||
else
|
||||
{
|
||||
e->count = count;
|
||||
e->frequency = freq;
|
||||
}
|
||||
}
|
||||
src->release_body ();
|
||||
inline_update_overall_summary (dst);
|
||||
|
Loading…
Reference in New Issue
Block a user