Hi all, The attached patch is an attempt to fix the bug PR ipa/63576. As it is said in the comment to the bug,
Jan Hubicka wrote: > THen you need to sum counts (instead of taking ones from BB) and > turn them back to frequencies (because it is profile only counts > should be non-0) It seems that counts and frequencies are gathered in some special manner, and this patch simply adds counts from speculative edges and from basic blocks. Of course, I don't know whether this way is proper one, so please correct me or redirect to right place where it is documented :) Anyway, the patch was bootstrapped and regtested on x86_64-unknown-linux-gnu. Ok for trunk? gcc/ 2014-10-22 Ilya Palachev <i.palac...@samsung.com> * ipa-utils.c (compute_edge_count_and_frequency): New function (ipa_merge_profiles): handle speculative case --- gcc/ipa-utils.c | 52 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c index 552071e..335ab05 100644 --- a/gcc/ipa-utils.c +++ b/gcc/ipa-utils.c @@ -380,6 +380,46 @@ get_base_var (tree t) return t; } +/* Computes count and frequency for edges. */ + +static void +compute_edge_count_and_frequency(struct cgraph_edge *e, + struct cgraph_node *dst) +{ + basic_block bb = gimple_bb (e->call_stmt); + if (!e->speculative) + { + e->count = bb->count; + e->frequency = compute_call_stmt_bb_frequency (dst->decl, bb); + } + else + { + if (profile_status_for_fn (DECL_STRUCT_FUNCTION (dst->decl)) + == PROFILE_ABSENT) + { + e->count = bb->count; + e->frequency = CGRAPH_FREQ_BASE; + } + else + { + gcc_assert (e->count >= 0); + e->count += bb->count; + gcc_assert (e->frequency >= 0); + + int entry_freq = ENTRY_BLOCK_PTR_FOR_FN + (DECL_STRUCT_FUNCTION (dst->decl))->frequency; + int freq = e->frequency + bb->frequency; + + if (!entry_freq) + entry_freq = 1, freq++; + + freq = freq * CGRAPH_FREQ_BASE / entry_freq; + if (freq > CGRAPH_FREQ_MAX) + freq = CGRAPH_FREQ_MAX; + e->frequency = freq; + } + } +} /* SRC and DST are going to be merged. Take SRC's profile and merge it into DST so it is not going to be lost. Destroy SRC's body on the way. */ @@ -537,19 +577,11 @@ ipa_merge_profiles (struct cgraph_node *dst, pop_cfun (); for (e = dst->callees; e; 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)); + compute_edge_count_and_frequency(e, dst); } for (e = dst->indirect_calls; e; 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)); + compute_edge_count_and_frequency(e, dst); } src->release_body (); inline_update_overall_summary (dst); -- 2.1.1