summaryrefslogtreecommitdiff
path: root/gcc/cfgloopanal.c
diff options
context:
space:
mode:
authorsandra <sandra@138bc75d-0d04-0410-961f-82ee72b054a4>2010-07-10 18:43:29 +0000
committersandra <sandra@138bc75d-0d04-0410-961f-82ee72b054a4>2010-07-10 18:43:29 +0000
commita6b74a67c831c6d371d91dbbeda762fb01ff180c (patch)
treeb3a38775af4396d2f1d30d5d0c41a80f2bf0e78f /gcc/cfgloopanal.c
parent4ce1f21050f9b1f9f5fb21ef4b5afa6fb60c7a00 (diff)
downloadgcc-a6b74a67c831c6d371d91dbbeda762fb01ff180c.tar.gz
2010-07-10 Sandra Loosemore <sandra@codesourcery.com>
PR middle-end/42505 gcc/ * tree-inline.c (estimate_num_insns): Refactor builtin complexity lookup code into.... * builtins.c (is_simple_builtin, is_inexpensive_builtin): ...these new functions. * tree.h (is_simple_builtin, is_inexpensive_builtin): Declare. * cfgloopanal.c (target_clobbered_regs): Define. (init_set_costs): Initialize target_clobbered_regs. (estimate_reg_pressure_cost): Add call_p argument. When true, adjust the number of available registers to exclude the call-clobbered registers. * cfgloop.h (target_clobbered_regs): Declare. (estimate_reg_pressure_cost): Adjust declaration. * tree-ssa-loop-ivopts.c (struct ivopts_data): Add body_includes_call. (ivopts_global_cost_for_size): Pass it to estimate_reg_pressure_cost. (determine_set_costs): Dump target_clobbered_regs. (loop_body_includes_call): New function. (tree_ssa_iv_optimize_loop): Use it to initialize new field. * loop-invariant.c (gain_for_invariant): Adjust arguments to pass call_p flag through. (best_gain_for_invariant): Likewise. (find_invariants_to_move): Likewise. (move_single_loop_invariants): Likewise, using already-computed has_call field. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@162043 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfgloopanal.c')
-rw-r--r--gcc/cfgloopanal.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c
index 129ec25a331..853e6f22dd4 100644
--- a/gcc/cfgloopanal.c
+++ b/gcc/cfgloopanal.c
@@ -320,6 +320,8 @@ seq_cost (const_rtx seq, bool speed)
/* The properties of the target. */
unsigned target_avail_regs; /* Number of available registers. */
+unsigned target_clobbered_regs; /* Number of available registers that are
+ call-clobbered. */
unsigned target_res_regs; /* Number of registers reserved for temporary
expressions. */
unsigned target_reg_cost[2]; /* The cost for register when there still
@@ -342,10 +344,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 +386,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;