Hi, estimate_edge_time was originally derrived from estimate_edge_growth. estimate_edge_growth returns estimated function body growth by inlining. That is size_of_inlined_body-size_of_call_stmt. For estimate_edge_time it is kind of confusing and led me to double account time of call stmt in the badness computation.
This patch fixes estimate_edge_time to actually return time of inlined sequence and adds estimate_edge_size that is the size variant + makes do_estimate_edge_growth a wrapper about it (because at most places the inline heuristic really care about growth) Bootstrapped/regtested x86_64-linux, comitted. Honza * ipa-inline-analysis.c (do_estimate_edge_time): Return actual time spent by the inlined sequence. (do_estimate_edge_growth): Rename to ... (do_estimate_edge_time): ... this one; return size of inlined sequence. * ipa-inline.h (do_estimate_edge_size): New. (do_estimate_edge_growth): Remove. (estimate_edge_size): New function. (estimate_edge_growth): Use it. Index: ipa-inline-analysis.c =================================================================== --- ipa-inline-analysis.c (revision 192116) +++ ipa-inline-analysis.c (working copy) @@ -3312,14 +3312,12 @@ do_estimate_edge_time (struct cgraph_edg VEC_free (tree, heap, known_binfos); VEC_free (ipa_agg_jump_function_p, heap, known_aggs); - ret = (((gcov_type)time - - es->call_stmt_time) * edge->frequency - + CGRAPH_FREQ_BASE / 2) / CGRAPH_FREQ_BASE; + ret = RDIV ((gcov_type)time * edge->frequency, + CGRAPH_FREQ_BASE); /* When caching, update the cache entry. */ if (edge_growth_cache) { - int ret_size; if ((int)VEC_length (edge_growth_cache_entry, edge_growth_cache) <= edge->uid) VEC_safe_grow_cleared (edge_growth_cache_entry, heap, edge_growth_cache, @@ -3327,10 +3325,8 @@ do_estimate_edge_time (struct cgraph_edg VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).time = ret + (ret >= 0); - ret_size = size - es->call_stmt_size; - gcc_checking_assert (es->call_stmt_size); VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).size - = ret_size + (ret_size >= 0); + = size + (size >= 0); VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).hints = hints + 1; } @@ -3338,11 +3334,11 @@ do_estimate_edge_time (struct cgraph_edg } -/* Estimate the growth of the caller when inlining EDGE. +/* Return estimated callee growth after inlining EDGE. Only to be called via estimate_edge_size. */ int -do_estimate_edge_growth (struct cgraph_edge *edge) +do_estimate_edge_size (struct cgraph_edge *edge) { int size; struct cgraph_node *callee; @@ -3375,8 +3371,7 @@ do_estimate_edge_growth (struct cgraph_e VEC_free (tree, heap, known_vals); VEC_free (tree, heap, known_binfos); VEC_free (ipa_agg_jump_function_p, heap, known_aggs); - gcc_checking_assert (inline_edge_summary (edge)->call_stmt_size); - return size - inline_edge_summary (edge)->call_stmt_size; + return size; } Index: ipa-inline.h =================================================================== --- ipa-inline.h (revision 192116) +++ ipa-inline.h (working copy) @@ -201,7 +201,7 @@ void estimate_ipcp_clone_size_and_time ( int do_estimate_growth (struct cgraph_node *); void inline_merge_summary (struct cgraph_edge *edge); void inline_update_overall_summary (struct cgraph_node *node); -int do_estimate_edge_growth (struct cgraph_edge *edge); +int do_estimate_edge_size (struct cgraph_edge *edge); int do_estimate_edge_time (struct cgraph_edge *edge); inline_hints do_estimate_edge_hints (struct cgraph_edge *edge); void initialize_growth_caches (void); @@ -245,20 +245,31 @@ estimate_growth (struct cgraph_node *nod } -/* Return estimated callee growth after inlining EDGE. */ +/* Return estimated size of the inline sequence of EDGE. */ static inline int -estimate_edge_growth (struct cgraph_edge *edge) +estimate_edge_size (struct cgraph_edge *edge) { int ret; if ((int)VEC_length (edge_growth_cache_entry, edge_growth_cache) <= edge->uid || !(ret = VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).size)) - return do_estimate_edge_growth (edge); + return do_estimate_edge_size (edge); return ret - (ret > 0); } +/* Return estimated callee growth after inlining EDGE. */ + +static inline int +estimate_edge_growth (struct cgraph_edge *edge) +{ +#ifdef ENABLE_CHECKING + gcc_checking_assert (inline_edge_summary (edge)->call_stmt_size); +#endif + return (estimate_edge_size (edge) + - inline_edge_summary (edge)->call_stmt_size); +} /* Return estimated callee runtime increase after inlning EDGE. */