https://gcc.gnu.org/g:f9b60a8bd7569f59534a42d1383c1f66a37542cf
commit r17-4901-gf9b60a8bd7569f59534a42d1383c1f66a37542cf Author: Martin Jambor <[email protected]> Date: Mon Oct 5 16:59:12 2026 +0200 ipa-cp: Adjust PGO IPA-CP cloning heuristics With profile-feedback, the run-times used for opportunity evaluations is not currently scaled to the total measured run time of the program/compilation unit, which is an obvious mistake. This patch adds such scaling by run-time which is however itself also scaled down so that the resulting scores rougly fall in line with the scores on hot loops we get using guessed profile. gcc/ChangeLog: 2026-05-15 Martin Jambor <[email protected]> * ipa-cp.cc (overall_scaled_runtime): New. (good_cloning_opportunity_p): Scale PGO evaluations by overall_scaled_runtime. (ipcp_propagate_stage): Calculate also overall_scaled_runtime and print it and unscaled time. (ipa_cp_cc_finalize): Set overall_scaled_runtime to zero. * params.opt (ipa-cp-profile-runtime-scaling): New. * doc/params.texi (ipa-cp-profile-runtime-scaling): New. Diff: --- gcc/doc/params.texi | 5 +++++ gcc/ipa-cp.cc | 40 ++++++++++++++++++++++++++++++++++------ gcc/params.opt | 4 ++++ 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/gcc/doc/params.texi b/gcc/doc/params.texi index 8d8e5926cb10..7393711a92ea 100644 --- a/gcc/doc/params.texi +++ b/gcc/doc/params.texi @@ -1292,6 +1292,11 @@ of iterations of a loop known, it adds a bonus of @option{ipa-cp-loop-hint-bonus} to the profitability score of the candidate. +@paindex ipa-cp-profile-runtime-scaling +@item ipa-cp-profile-runtime-scaling +When using profile feedback, by how many bits to shift the run-time +before it is used as the basis for IPA-CP evaluations. + @paindex ipa-max-loop-predicates @item ipa-max-loop-predicates The maximum number of different predicates IPA uses to describe when diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc index 574b109bad52..cecc8d17f17c 100644 --- a/gcc/ipa-cp.cc +++ b/gcc/ipa-cp.cc @@ -153,6 +153,12 @@ object_allocator<ipcp_agg_lattice> ipcp_agg_lattice_pool static long overall_size, orig_overall_size; +/* Overall run-time of the part of the program or the compilation unit for + which profile information is available, scaled by + param_ipa_cp_min_recursive_probability. */ + +static sreal overall_scaled_runtime; + /* The maximum number of IPA-CP decision sweeps that any node requested in its param. */ static int max_number_sweeps; @@ -3477,8 +3483,8 @@ good_cloning_opportunity_p (struct cgraph_node *node, sreal time_benefit, if (count_sum.nonzero_p ()) { profile_count saved_time = count_sum * time_benefit; - sreal evaluation = saved_time.to_sreal_scale (profile_count::one ()) - / size_cost; + sreal evaluation = (saved_time.to_sreal_scale (profile_count::one ()) + / overall_scaled_runtime) / size_cost; evaluation = incorporate_penalties (node, info, evaluation); if (dump_file && (dump_flags & TDF_DETAILS)) @@ -4082,6 +4088,8 @@ static void ipcp_propagate_stage (class ipa_topo_info *topo) { struct cgraph_node *node; + sreal overall_runtime = 0; + overall_scaled_runtime = 0; if (dump_file) fprintf (dump_file, "\n Propagating constants:\n\n"); @@ -4103,15 +4111,34 @@ ipcp_propagate_stage (class ipa_topo_info *topo) if (max_number_sweeps < num_sweeps) max_number_sweeps = num_sweeps; } - ipa_size_summary *s = ipa_size_summaries->get (node); - if (node->definition && !node->alias && s != NULL) - overall_size += s->self_size; + + if (!node->alias) + { + ipa_size_summary *szs = ipa_size_summaries->get (node); + if (szs) + overall_size += szs->self_size; + ipa_fn_summary *fns = ipa_fn_summaries->get (node); + if (fns) + { + int shift = opt_for_fn (node->decl, + param_ipa_cp_profile_runtime_scaling); + sreal frt = fns->time; + overall_runtime += frt; + overall_scaled_runtime += frt.shift(-shift); + } + } } orig_overall_size = overall_size; if (dump_file) - fprintf (dump_file, "\noverall_size: %li\n", overall_size); + { + fprintf (dump_file, "\noverall_size: %li\n", overall_size); + fprintf (dump_file, "overall_runtime: %.2e\n", + overall_runtime.to_double ()); + fprintf (dump_file, "overall_scaled_runtime: %.2e\n", + overall_scaled_runtime.to_double ()); + } propagate_constants_topo (topo); if (flag_checking) @@ -6872,6 +6899,7 @@ ipa_cp_cc_finalize (void) { overall_size = 0; orig_overall_size = 0; + overall_scaled_runtime = 0; ipcp_free_transformation_sum (); } diff --git a/gcc/params.opt b/gcc/params.opt index 053fdfdb97c2..29a5c7018a80 100644 --- a/gcc/params.opt +++ b/gcc/params.opt @@ -261,6 +261,10 @@ Threshold ipa-cp opportunity evaluation that is still considered beneficial to c Common Joined UInteger Var(param_ipa_cp_loop_hint_bonus) Init(64) Param Optimization Compile-time bonus IPA-CP assigns to candidates which make loop bounds or strides known. +-param=ipa-cp-profile-runtime-scaling= +Common Joined UInteger Var(param_ipa_cp_profile_runtime_scaling) Init(19) Param Optimization +With profile feedback, by how many bits to shift the run-time before it is used as the basis for IPA-CP evaluations. + -param=ipa-cp-max-recursive-depth= Common Joined UInteger Var(param_ipa_cp_max_recursive_depth) Init(8) Param Optimization Maximum depth of recursive cloning for self-recursive function.
