aboutsummaryrefslogtreecommitdiff
path: root/gcc/cfgloopanal.c
diff options
context:
space:
mode:
authorZdenek Dvorak <dvorakz@suse.cz>2007-04-17 18:42:29 +0200
committerZdenek Dvorak <rakdver@gcc.gnu.org>2007-04-17 16:42:29 +0000
commita154b43a811a710525c1da93ea4f97c97c9327f9 (patch)
tree0a31c59ebc8695e61c56119d3a3890c7117e0a43 /gcc/cfgloopanal.c
parentfaf28b3a89f32229935b0f60383423315121eb8d (diff)
downloadgcc-a154b43a811a710525c1da93ea4f97c97c9327f9.zip
gcc-a154b43a811a710525c1da93ea4f97c97c9327f9.tar.gz
gcc-a154b43a811a710525c1da93ea4f97c97c9327f9.tar.bz2
re PR rtl-optimization/31360 (RTL loop invariant is not aggressive enough)
PR rtl-optimization/31360 * cfgloopanal.c (target_small_cost, target_pres_cost): Removed. (target_reg_cost): New. (init_set_costs): Initialize target_reg_cost. Add comments regarding the rationale of the costs. (global_cost_for_size): Renamed to... (estimate_reg_pressure_cost): ... and simplify. Decrease importance of register pressure. * tree-ssa-loop-ivopts.c (ivopts_global_cost_for_size): Use estimate_reg_pressure_cost. Add number of ivs. (determine_set_costs): Dump target_reg_cost. * loop-invariant.c (gain_for_invariant): Use estimate_reg_pressure_cost. Removed n_inv_uses argument. (best_gain_for_invariant, find_invariants_to_move): Remove n_inv_uses. * cfgloop.h (target_small_cost, target_pres_cost): Removed. (target_reg_cost): Declare. (global_cost_for_size): Declaration removed. (estimate_reg_pressure_cost): Declare. * gcc.dg/loop-7.c: New test. From-SVN: r123919
Diffstat (limited to 'gcc/cfgloopanal.c')
-rw-r--r--gcc/cfgloopanal.c55
1 files changed, 31 insertions, 24 deletions
diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c
index 4612ab8..7baa30a 100644
--- a/gcc/cfgloopanal.c
+++ b/gcc/cfgloopanal.c
@@ -523,11 +523,13 @@ seq_cost (rtx seq)
/* The properties of the target. */
unsigned target_avail_regs; /* Number of available registers. */
-unsigned target_res_regs; /* Number of reserved registers. */
-unsigned target_small_cost; /* The cost for register when there is a free one. */
-unsigned target_pres_cost; /* The cost for register when there are not too many
- free ones. */
-unsigned target_spill_cost; /* The cost for register when we need to spill. */
+unsigned target_res_regs; /* Number of registers reserved for temporary
+ expressions. */
+unsigned target_reg_cost; /* The cost for register when there still
+ is some reserve, but we are approaching
+ the number of available registers. */
+unsigned target_spill_cost; /* The cost for register when we need
+ to spill. */
/* Initialize the constants for computing set costs. */
@@ -548,14 +550,20 @@ init_set_costs (void)
target_res_regs = 3;
- /* These are really just heuristic values. */
+ /* Set up the costs for using extra registers:
+
+ 1) If not many free registers remain, we should prefer having an
+ additional move to decreasing the number of available registers.
+ (TARGET_REG_COST).
+ 2) If no registers are available, we need to spill, which may require
+ storing the old value to memory and loading it back
+ (TARGET_SPILL_COST). */
start_sequence ();
emit_move_insn (reg1, reg2);
seq = get_insns ();
end_sequence ();
- target_small_cost = seq_cost (seq);
- target_pres_cost = 2 * target_small_cost;
+ target_reg_cost = seq_cost (seq);
start_sequence ();
emit_move_insn (mem, reg1);
@@ -565,27 +573,26 @@ init_set_costs (void)
target_spill_cost = seq_cost (seq);
}
-/* Calculates cost for having SIZE new loop global variables. REGS_USED is the
- number of global registers used in loop. N_USES is the number of relevant
- variable uses. */
+/* Estimates cost of increased register pressure caused by making N_NEW new
+ registers live around the loop. N_OLD is the number of registers live
+ around the loop. */
unsigned
-global_cost_for_size (unsigned size, unsigned regs_used, unsigned n_uses)
+estimate_reg_pressure_cost (unsigned n_new, unsigned n_old)
{
- unsigned regs_needed = regs_used + size;
- unsigned cost = 0;
+ unsigned regs_needed = n_new + n_old;
+ /* If we have enough registers, we should use them and not restrict
+ the transformations unnecessarily. */
if (regs_needed + target_res_regs <= target_avail_regs)
- cost += target_small_cost * size;
- else if (regs_needed <= target_avail_regs)
- cost += target_pres_cost * size;
- else
- {
- cost += target_pres_cost * size;
- cost += target_spill_cost * n_uses * (regs_needed - target_avail_regs) / regs_needed;
- }
-
- return cost;
+ return 0;
+
+ /* If we are close to running out of registers, try to preserve them. */
+ if (regs_needed <= target_avail_regs)
+ return target_reg_cost * n_new;
+
+ /* If we run out of registers, it is very expensive to add another one. */
+ return target_spill_cost * n_new;
}
/* Sets EDGE_LOOP_EXIT flag for all loop exits. */