Hello everyone,
I wanted to add that this patch makes ssa-sink-18.c test fail on x86, 
due to the
similar reasons this test was expected to fail for some architectures;
namely, if the ivopt uses two candidates for the testcase,
that cuts down the amount of sinking optimizations we can do,
making the test fail.

As this change is architecture-agnostic, I suspect this test will
fail in general, due to the ivopt candidate selection  being changed
with this patch.
I didn't want to mark the test as XFAIL until consulting the community
on the proper course of action.

All suggestions will be greatly appreciated.

Thanks,
Jovan

On 5/20/26 14:37, Jovan Dmitrović wrote:
> Currently, ivopt calculates register pressure cost so that the cost of
> spilling induction variables is exactly double the cost of spilling
> loop invariants, which is not exactly right.
> As ivopts already has `adjust_setup_cost` function, we can use it
> in order to make the invariant part of the cost relatively cheaper.
>
> Tested with CoreMark PRO on RISC-V P8700 CPU (~1.2% improvement),
> and on x86-64 Intel Core i7-12700H CPU (~0.4% improvement).
>
> gcc/ChangeLog:
>
>          * tree-ssa-loop-ivopts.cc (ivopts_estimate_reg_pressure):
>          Change register pressure estimate in order to respect
>          the impact of spilling induction variables, compared
>          to spilling loop invariants.
>
> Co-authored-by: Radosav Krunić <[email protected]>
> Signed-off-by: Djordje Todorović <[email protected]>
> Signed-off-by: Chao-Ying Fu <[email protected]>
> Signed-off-by: Jovan Dmitrović <[email protected]>
> Signed-off-by: Radosav Krunić <[email protected]>
> ---
>   gcc/tree-ssa-loop-ivopts.cc | 23 +++++++++++++----------
>   1 file changed, 13 insertions(+), 10 deletions(-)
>
> diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc
> index 776487d0f8b1..19ba620fb070 100644
> --- a/gcc/tree-ssa-loop-ivopts.cc
> +++ b/gcc/tree-ssa-loop-ivopts.cc
> @@ -6085,6 +6085,7 @@ ivopts_estimate_reg_pressure (struct ivopts_data *data, 
> unsigned n_invs,
>     unsigned cost;
>     unsigned n_old = data->regs_used, n_new = n_invs + n_cands;
>     unsigned regs_needed = n_new + n_old, available_regs = target_avail_regs;
> +  unsigned iv_spill_cost = 0;
>     bool speed = data->speed;
>   
>     /* If there is a call in the loop body, the call-clobbered registers
> @@ -6094,7 +6095,7 @@ ivopts_estimate_reg_pressure (struct ivopts_data *data, 
> unsigned n_invs,
>   
>     /* If we have enough registers.  */
>     if (regs_needed + target_res_regs < available_regs)
> -    cost = n_new;
> +    cost = 0;
>     /* If close to running out of registers, try to preserve them.  */
>     else if (regs_needed <= available_regs)
>       cost = target_reg_cost [speed] * regs_needed;
> @@ -6103,17 +6104,19 @@ ivopts_estimate_reg_pressure (struct ivopts_data 
> *data, unsigned n_invs,
>     else if (n_cands <= available_regs)
>       cost = target_reg_cost [speed] * available_regs
>          + target_spill_cost [speed] * (regs_needed - available_regs);
> -  /* If the number of candidates runs out available registers, we penalize
> -     extra candidate registers using target_spill_cost * 2.  Because it is
> -     more expensive to spill induction variable than invariant.  */
> +  /* If the number of candidates runs out available registers,
> +      save the spill cost as separate variable iv_spill_cost. */
>     else
> -    cost = target_reg_cost [speed] * available_regs
> -        + target_spill_cost [speed] * (n_cands - available_regs) * 2
> -        + target_spill_cost [speed] * (regs_needed - n_cands);
> +    {
> +       cost = target_reg_cost [speed] * available_regs
> +               + target_spill_cost [speed] * (regs_needed - n_cands);
> +       iv_spill_cost = target_spill_cost[speed] *
> +               (n_cands - available_regs);
> +    }
>   
> -  /* Finally, add the number of candidates, so that we prefer eliminating
> -     induction variables if possible.  */
> -  return cost + n_cands;
> +  /* Adjust cost of invariant register pressure in order to make
> +     the spilling of induction variables the most taxing. */
> +  return adjust_setup_cost(data, cost) + iv_spill_cost;
>   }
>   
>   /* For each size of the induction variable set determine the penalty.  */

Reply via email to