Hi,

On Mon, Sep 21 2026, Josef Melcr wrote:
> Assume bodies don't fit in most of the heuristics of the IPA passes.
> They are usually not profitable, but since they are purely an
> optimization tool and don't make it into the binary anyway , we want to
> make the most of them.  This patch introduces several bypasses for
> checks which would prevent their optimizations, be it cloning or
> parameter splitting.
>
> gcc/ChangeLog:
>
>       * ipa-cp.cc (good_cloning_opportunity_p): Special case assume
>       functions.
>       * ipa-sra.cc (adjust_parameter_descriptions): Likewise.
>       * tree-sra.cc (analyze_all_variable_accesses): Likewise.
>
> Signed-off-by: Josef Melcr <[email protected]>
> ---
>  gcc/ipa-cp.cc   | 10 ++++++++++
>  gcc/ipa-sra.cc  | 12 +++++++++---
>  gcc/tree-sra.cc |  4 +++-
>  3 files changed, 22 insertions(+), 4 deletions(-)
>
> diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
> index d0428d04684..71cac065cce 100644
> --- a/gcc/ipa-cp.cc
> +++ b/gcc/ipa-cp.cc
> @@ -3463,6 +3463,16 @@ good_cloning_opportunity_p (struct cgraph_node *node, 
> sreal time_benefit,
>        return false;
>      }
>  
> +  /* Assume bodies don't make it into the final binary, so they have no real
> +     size.  Special case them, as cloning them is always a good idea.  */
> +  if (node->assume_function)
> +    {
> +      if (dump_file && (dump_flags & TDF_DETAILS))
> +     fprintf (dump_file, "     good_cloning_opportunity_p: Always clone "
> +                         "assume body functions.\n");
> +      return true;
> +    }
> +

I'm afraid you also need to split the check above this because the check
for !opt_for_fn (node->decl, flag_ipa_cp_clone) should remain to be the
first (the "prohibited" case) but the other ones ("definitely not good")
need to be below this, otherwise this would never trigger in PGO builds?


>    gcc_assert (size_cost > 0);
>  
>    ipa_node_params *info = ipa_node_params_sum->get (node);
> diff --git a/gcc/ipa-sra.cc b/gcc/ipa-sra.cc
> index a663900fc1d..f26a7ee3ee5 100644
> --- a/gcc/ipa-sra.cc
> +++ b/gcc/ipa-sra.cc
> @@ -2574,8 +2574,11 @@ process_scan_results (cgraph_node *node, struct 
> function *fun,
>              * param_size_limit);
>       }
>  
> -      if (nonarg_acc_size > optimistic_limit
> -       || (!desc->by_ref && nonarg_acc_size == param_size_limit))
> +      /* Assume functions have no real replacements, no calls to them will 
> make
> +      it into the binary, so limits don't matter.  */
> +      if (!node->assume_function
> +       && (nonarg_acc_size > optimistic_limit
> +           || (!desc->by_ref && nonarg_acc_size == param_size_limit)))
>       {
>         disqualify_split_candidate (desc, "Would result into a too big set "
>                                     "of replacements even in best "

OK


> @@ -4439,7 +4442,10 @@ adjust_parameter_descriptions (cgraph_node *node, 
> isra_func_summary *ifs)
>                             param_ipa_sra_ptrwrap_growth_factor);
>             desc->param_size_limit = extra_factor * desc->param_size_limit;
>           }
> -       if (size_would_violate_limit_p (desc, desc->size_reached))
> +       /* Don't disqualify assume bodies, as they don't make into the final
> +          binary anyway.  */
> +       if (!node->assume_function
> +           && size_would_violate_limit_p (desc, desc->size_reached))
>           desc->split_candidate = false;
>       }
>  

OK

> diff --git a/gcc/tree-sra.cc b/gcc/tree-sra.cc
> index f951a38442a..0adf6c7b6c7 100644
> --- a/gcc/tree-sra.cc
> +++ b/gcc/tree-sra.cc
> @@ -3915,7 +3915,9 @@ analyze_all_variable_accesses (void)
>             fprintf (dump_file, "\n");
>           }
>       }
> -      else
> +      /* Don't disqualify assume bodies.  Assumes don't have any writes, but
> +      scalarizing their arguments is important for later IPA.  */
> +      else if (!cfun->assume_function)
>       disqualify_candidate (var, "No scalar replacements to be created.");
>      }

This is quite unexpected, what is the reason to do this?

Martin

Reply via email to