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.
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 | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc
index 00d5031893c1..95c6dcf767ab 100644
--- a/gcc/tree-ssa-loop-ivopts.cc
+++ b/gcc/tree-ssa-loop-ivopts.cc
@@ -6083,6 +6083,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
@@ -6101,17 +6102,21 @@ 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
+ /* Adjust cost of invariant register pressure in order to make
+ the spilling of induction variables the most taxing.
+ Finally, add the number of candidates, so that we prefer eliminating
induction variables if possible. */
- return cost + n_cands;
+ return adjust_setup_cost(data, cost) + iv_spill_cost + n_cands;
}
/* For each size of the induction variable set determine the penalty. */
--
2.34.1