Hi, this patch adds two static methods to ipa_call_context which construct and return the object in the two scenarios where we use them (what if an edge was inlined, what if a node wascloned) which saves callers a bit work and are more intuitive.
The next step is to make ipa_call_context::estimate_size_and_time store its results directly into the object. Ideally, these construction functions would immediately invoke it, but that would not work with caching in do_estimate_edge_time. I guess ideally for_inlined_edge would do the caching... but this patch is a move in the right direction. Anyway, assuming it passes bootstrap and testing (on x86_64-linux) and the previous patch is ACKed, is this one on top of it OK too? Thanks, Martin gcc/ChangeLog: 2020-08-28 Martin Jambor <mjam...@suse.cz> * ipa-fnsummary.h (class ipa_call_context): New static member methods for_inlined_edge and for_cloned_node. (estimate_ipcp_clone_size_and_time): Remove declaration. (evaluate_properties_for_edge): Remove declaration. * ipa-cp.c (perform_estimation_of_a_value): Use directly ipa_call_context instead of estimate_ipcp_clone_size_and_time. (estimate_local_effects): Likewise. * ipa-fnsummary.c (evaluate_properties_for_edge): Make static. (ipa_call_context::for_inlined_edge): New function. (ipa_call_context::for_cloned_node): Likewise. (estimate_ipcp_clone_size_and_time): Removed. * ipa-inline-analysis.c (do_estimate_edge_time): Use ipa_call_context::for_inlined_edge. (do_estimate_edge_size): Likewise. (do_estimate_edge_hints): Likewise. --- gcc/ipa-cp.c | 10 +++++---- gcc/ipa-fnsummary.c | 45 +++++++++++++++++++++++++-------------- gcc/ipa-fnsummary.h | 19 ++++++----------- gcc/ipa-inline-analysis.c | 24 ++++++--------------- 4 files changed, 48 insertions(+), 50 deletions(-) diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index 970675efe49..82875e89a92 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -3391,8 +3391,9 @@ perform_estimation_of_a_value (cgraph_node *node, ipa_call_arg_values *avals, sreal time, base_time; ipa_hints hints; - estimate_ipcp_clone_size_and_time (node, avals, &size, &time, - &base_time, &hints); + ipa_call_context ctx = ipa_call_context::for_cloned_node (node, avals); + ctx.estimate_size_and_time (&size, NULL, &time, &base_time, &hints); + base_time -= time; if (base_time > 65535) base_time = 65535; @@ -3469,8 +3470,9 @@ estimate_local_effects (struct cgraph_node *node) init_caller_stats (&stats); node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats, false); - estimate_ipcp_clone_size_and_time (node, &avals, &size, &time, - &base_time, &hints); + ipa_call_context ctx = ipa_call_context::for_cloned_node (node, &avals); + ctx.estimate_size_and_time (&size, NULL, &time, &base_time, &hints); + time -= devirt_bonus; time -= hint_time_bonus (node, hints); time -= removable_params_cost; diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c index f154d5ee9fc..2a0f8ad37b2 100644 --- a/gcc/ipa-fnsummary.c +++ b/gcc/ipa-fnsummary.c @@ -539,7 +539,7 @@ fre_will_run_p (struct cgraph_node *node) except for m_known_contexts which will only be calculated if COMPUTE_CONTEXTS is true. */ -void +static void evaluate_properties_for_edge (struct cgraph_edge *e, bool inline_p, clause_t *clause_ptr, clause_t *nonspec_clause_ptr, @@ -3423,27 +3423,40 @@ ipa_call_context::estimate_size_and_time (int *ret_size, return; } +/* Construct and create a context object representing the context of E, if it + were inlined. INLINE_PARAM_SUMMARY must be an existing summary with change + probabilities of individual parameters. ARG_VALUES will be computed, this is + but this structure will be used to hold the result throughout the life of + the result context. */ -/* Estimate size and time needed to execute callee of EDGE assuming that - parameters known to be constant at caller of EDGE are propagated. - KNOWN_VALS and KNOWN_CONTEXTS are vectors of assumed known constant values - and types for parameters. */ +ipa_call_context +ipa_call_context +::for_inlined_edge (cgraph_edge *e, + vec<inline_param_summary> inline_param_summary, + ipa_call_arg_values *arg_values) +{ + clause_t clause, nonspec_clause; + evaluate_properties_for_edge (e, true, &clause, &nonspec_clause, + arg_values, true); + return ipa_call_context (e->callee->ultimate_alias_target (), + clause, nonspec_clause, inline_param_summary, + arg_values); +} -void -estimate_ipcp_clone_size_and_time (struct cgraph_node *node, - ipa_call_arg_values *avals, - int *ret_size, sreal *ret_time, - sreal *ret_nonspec_time, - ipa_hints *hints) +/* Construct and create a context object representing calls to a presumed + specialized clone of NODE if information about arguments in ARG_VALUES as + passed to this function are true. The resulting context will point to + ARG_VALUES throughout its lifetime. */ + +ipa_call_context +ipa_call_context::for_cloned_node (cgraph_node *node, + ipa_call_arg_values *arg_values) { clause_t clause, nonspec_clause; - evaluate_conditions_for_known_args (node, false, avals, &clause, + evaluate_conditions_for_known_args (node, false, arg_values, &clause, &nonspec_clause); - ipa_call_context ctx (node, clause, nonspec_clause, - vNULL, avals); - ctx.estimate_size_and_time (ret_size, NULL, ret_time, - ret_nonspec_time, hints); + return ipa_call_context (node, clause, nonspec_clause, vNULL, arg_values); } /* Return stack frame offset where frame of NODE is supposed to start inside diff --git a/gcc/ipa-fnsummary.h b/gcc/ipa-fnsummary.h index 34050516d91..74a78d31391 100644 --- a/gcc/ipa-fnsummary.h +++ b/gcc/ipa-fnsummary.h @@ -296,6 +296,13 @@ class ipa_node_context_cache_entry; class ipa_call_context { public: + static ipa_call_context for_inlined_edge (cgraph_edge *e, + vec<inline_param_summary> + inline_param_summary, + ipa_call_arg_values *arg_values); + static ipa_call_context for_cloned_node (cgraph_node *node, + ipa_call_arg_values *arg_values); + ipa_call_context (cgraph_node *node, clause_t possible_truths, clause_t nonspec_possible_truths, @@ -342,22 +349,10 @@ void ipa_dump_hints (FILE *f, ipa_hints); void ipa_free_fn_summary (void); void ipa_free_size_summary (void); void inline_analyze_function (struct cgraph_node *node); -void estimate_ipcp_clone_size_and_time (struct cgraph_node *, - ipa_call_arg_values *, - int *, sreal *, sreal *, - ipa_hints *); void ipa_merge_fn_summary_after_inlining (struct cgraph_edge *edge); void ipa_update_overall_fn_summary (struct cgraph_node *node, bool reset = true); void compute_fn_summary (struct cgraph_node *, bool); - -void evaluate_properties_for_edge (struct cgraph_edge *e, - bool inline_p, - clause_t *clause_ptr, - clause_t *nonspec_clause_ptr, - ipa_call_arg_values *avals, - bool compute_contexts); - void ipa_fnsummary_c_finalize (void); HOST_WIDE_INT ipa_get_stack_frame_offset (struct cgraph_node *node); void ipa_remove_from_growth_caches (struct cgraph_edge *edge); diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index d8cb9294c36..9788ee346ac 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -405,7 +405,6 @@ do_estimate_edge_time (struct cgraph_edge *edge, sreal *ret_nonspec_time) int size; ipa_hints hints; struct cgraph_node *callee; - clause_t clause, nonspec_clause; ipa_call_arg_values avals; class ipa_call_summary *es = ipa_call_summaries->get (edge); int min_size = -1; @@ -413,9 +412,8 @@ do_estimate_edge_time (struct cgraph_edge *edge, sreal *ret_nonspec_time) callee = edge->callee->ultimate_alias_target (); gcc_checking_assert (edge->inline_failed); - evaluate_properties_for_edge (edge, true, &clause, &nonspec_clause, - &avals, true); - ipa_call_context ctx (callee, clause, nonspec_clause, es->param, &avals); + ipa_call_context ctx = ipa_call_context::for_inlined_edge (edge, es->param, + &avals); if (node_context_cache != NULL) { node_context_summary *e = node_context_cache->get (callee); @@ -527,8 +525,6 @@ int do_estimate_edge_size (struct cgraph_edge *edge) { int size; - struct cgraph_node *callee; - clause_t clause, nonspec_clause; ipa_call_arg_values avals; /* When we do caching, use do_estimate_edge_time to populate the entry. */ @@ -541,13 +537,10 @@ do_estimate_edge_size (struct cgraph_edge *edge) return size - (size > 0); } - callee = edge->callee->ultimate_alias_target (); - /* Early inliner runs without caching, go ahead and do the dirty work. */ gcc_checking_assert (edge->inline_failed); - evaluate_properties_for_edge (edge, true, &clause, &nonspec_clause, &avals, - true); - ipa_call_context ctx (callee, clause, nonspec_clause, vNULL, &avals); + ipa_call_context ctx = ipa_call_context::for_inlined_edge (edge, vNULL, + &avals); ctx.estimate_size_and_time (&size, NULL, NULL, NULL, NULL); return size; } @@ -560,8 +553,6 @@ ipa_hints do_estimate_edge_hints (struct cgraph_edge *edge) { ipa_hints hints; - struct cgraph_node *callee; - clause_t clause, nonspec_clause; ipa_call_arg_values avals; /* When we do caching, use do_estimate_edge_time to populate the entry. */ @@ -574,13 +565,10 @@ do_estimate_edge_hints (struct cgraph_edge *edge) return hints - 1; } - callee = edge->callee->ultimate_alias_target (); - /* Early inliner runs without caching, go ahead and do the dirty work. */ gcc_checking_assert (edge->inline_failed); - evaluate_properties_for_edge (edge, true, &clause, &nonspec_clause, &avals, - true); - ipa_call_context ctx (callee, clause, nonspec_clause, vNULL, &avals); + ipa_call_context ctx = ipa_call_context::for_inlined_edge (edge, vNULL, + &avals); ctx.estimate_size_and_time (NULL, NULL, NULL, NULL, &hints); hints |= simple_edge_hints (edge); return hints; -- 2.28.0