aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa-utils.c
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2015-01-20 21:03:23 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2015-01-20 20:03:23 +0000
commitbefb1f36a71758c5fd645b1f08b8886e7f5808da (patch)
treee9d54a11212a674f38a2545167dedcd4148a8def /gcc/ipa-utils.c
parentbb1e543c64ff31a2e5d6959b0e4260c507c45b5b (diff)
downloadgcc-befb1f36a71758c5fd645b1f08b8886e7f5808da.zip
gcc-befb1f36a71758c5fd645b1f08b8886e7f5808da.tar.gz
gcc-befb1f36a71758c5fd645b1f08b8886e7f5808da.tar.bz2
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
Diffstat (limited to 'gcc/ipa-utils.c')
-rw-r--r--gcc/ipa-utils.c92
1 files changed, 84 insertions, 8 deletions
diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
index bc538c5..7612548 100644
--- a/gcc/ipa-utils.c
+++ b/gcc/ipa-utils.c
@@ -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);