aboutsummaryrefslogtreecommitdiff
path: root/gcc/cfgloopanal.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cfgloopanal.c')
-rw-r--r--gcc/cfgloopanal.c40
1 files changed, 24 insertions, 16 deletions
diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c
index 129ec25a331..48a44d2a3f0 100644
--- a/gcc/cfgloopanal.c
+++ b/gcc/cfgloopanal.c
@@ -32,6 +32,11 @@ along with GCC; see the file COPYING3. If not see
#include "graphds.h"
#include "params.h"
+struct target_cfgloop default_target_cfgloop;
+#if SWITCHABLE_TARGET
+struct target_cfgloop *this_target_cfgloop = &default_target_cfgloop;
+#endif
+
/* Checks whether BB is executed exactly once in each LOOP iteration. */
bool
@@ -317,17 +322,6 @@ seq_cost (const_rtx seq, bool speed)
return cost;
}
-/* The properties of the target. */
-
-unsigned target_avail_regs; /* Number of available registers. */
-unsigned target_res_regs; /* Number of registers reserved for temporary
- expressions. */
-unsigned target_reg_cost[2]; /* The cost for register when there still
- is some reserve, but we are approaching
- the number of available registers. */
-unsigned target_spill_cost[2]; /* The cost for register when we need
- to spill. */
-
/* Initialize the constants for computing set costs. */
void
@@ -342,10 +336,15 @@ init_set_costs (void)
unsigned i;
target_avail_regs = 0;
+ target_clobbered_regs = 0;
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i)
&& !fixed_regs[i])
- target_avail_regs++;
+ {
+ target_avail_regs++;
+ if (call_used_regs[i])
+ target_clobbered_regs++;
+ }
target_res_regs = 3;
@@ -379,20 +378,29 @@ init_set_costs (void)
/* 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. */
+ around the loop. If CALL_P is true, also take into account that
+ call-used registers may be clobbered in the loop body, reducing the
+ number of available registers before we spill. */
unsigned
-estimate_reg_pressure_cost (unsigned n_new, unsigned n_old, bool speed)
+estimate_reg_pressure_cost (unsigned n_new, unsigned n_old, bool speed,
+ bool call_p)
{
unsigned cost;
unsigned regs_needed = n_new + n_old;
+ unsigned available_regs = target_avail_regs;
+
+ /* If there is a call in the loop body, the call-clobbered registers
+ are not available for loop invariants. */
+ if (call_p)
+ available_regs = available_regs - target_clobbered_regs;
/* If we have enough registers, we should use them and not restrict
the transformations unnecessarily. */
- if (regs_needed + target_res_regs <= target_avail_regs)
+ if (regs_needed + target_res_regs <= available_regs)
return 0;
- if (regs_needed <= target_avail_regs)
+ if (regs_needed <= available_regs)
/* If we are close to running out of registers, try to preserve
them. */
cost = target_reg_cost [speed] * n_new;