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.
When invariants are spilled, only loading the invariant back to
registers should be taken into account, as we don't need to save them
more than once. This isn't the case for IV candidates which have to
be both loaded and stored for each iteration of the loop.
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 | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/gcc/tree-ssa-loop-ivopts.cc b/gcc/tree-ssa-loop-ivopts.cc
index ca06592190e0..40413c46f1b2 100644
--- a/gcc/tree-ssa-loop-ivopts.cc
+++ b/gcc/tree-ssa-loop-ivopts.cc
@@ -6096,15 +6096,17 @@ ivopts_estimate_reg_pressure (struct ivopts_data *data,
unsigned n_invs,
if (regs_needed <= available_regs)
cost = 0;
/* If we run out of available registers but the number of candidates
- does not, we penalize extra registers using target_spill_cost. */
+ does not, we penalize extra registers using target_spill_cost.
+ As we tend to spill invariants here, only take loading the
+ invariant into account, because the invariant won't change for the
+ duration of the loop and storing it every iteration is unnecessary. */
else if (n_cands <= available_regs)
- cost = 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. */
+ cost = target_spill_cost [speed] * (regs_needed - available_regs) / 2;
+ /* If both IV cands and invariants spill, calculate additional cost for
+ having to store spilled candidates. */
else
- cost = target_spill_cost [speed] * (n_cands - available_regs) * 2
- + target_spill_cost [speed] * (regs_needed - n_cands);
+ cost = target_spill_cost [speed] * (regs_needed - available_regs) / 2;
+ + target_spill_cost[speed] * (n_cands - available_regs) / 2;
return cost;
}
--
2.34.1