aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2005-09-01 05:29:03 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2005-09-01 05:29:03 +0000
commitd9903bcbbe19100d94f5dd9dcdb1a5276e7dfbe5 (patch)
tree51f172c784c1a0fb89978ba5eedd01b262b307a4
parentef07ff3370aa4c7a31df6187583111c0e1b3b63a (diff)
PR rtl-optimization/23478
* local-alloc.c (struct qty): Add n_throwing_calls_crossed field. (alloc_qty): Initialize it. (update_equiv_regs): Clear REG_N_THROWING_CALLS_CROSSED. (combine_regs): Combine also n_throwing_calls_crossed fields. (find_free_reg): Don't attempt to caller-save pseudos crossing calls that might throw. * global.c (struct allocno): Add throwing_calls_crossed field. (global_alloc): Revert 2005-08-22 change. Initialize throwing_calls_crossed. (find_reg): Don't attempt to caller-save pseudos crossing calls that might throw. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@103718 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/global.c13
-rw-r--r--gcc/local-alloc.c13
3 files changed, 36 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0d1946573d4..b30b116d4f1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2005-09-01 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/23478
+ * local-alloc.c (struct qty): Add n_throwing_calls_crossed field.
+ (alloc_qty): Initialize it.
+ (update_equiv_regs): Clear REG_N_THROWING_CALLS_CROSSED.
+ (combine_regs): Combine also n_throwing_calls_crossed fields.
+ (find_free_reg): Don't attempt to caller-save pseudos crossing
+ calls that might throw.
+ * global.c (struct allocno): Add throwing_calls_crossed field.
+ (global_alloc): Revert 2005-08-22 change. Initialize
+ throwing_calls_crossed.
+ (find_reg): Don't attempt to caller-save pseudos crossing calls that
+ might throw.
+
2005-09-01 Alan Modra <amodra@bigpond.net.au>
PR target/23649
diff --git a/gcc/global.c b/gcc/global.c
index f82cd08017a..d4e2b773559 100644
--- a/gcc/global.c
+++ b/gcc/global.c
@@ -97,6 +97,9 @@ struct allocno
/* Number of calls crossed by each allocno. */
int calls_crossed;
+ /* Number of calls that might throw crossed by each allocno. */
+ int throwing_calls_crossed;
+
/* Number of refs to each allocno. */
int n_refs;
@@ -465,9 +468,7 @@ global_alloc (FILE *file)
/* Don't allocate pseudos that cross calls,
if this function receives a nonlocal goto. */
&& (! current_function_has_nonlocal_label
- || REG_N_CALLS_CROSSED (i) == 0)
- /* Don't allocate pseudos that cross calls that may throw. */
- && REG_N_THROWING_CALLS_CROSSED (i) == 0)
+ || REG_N_CALLS_CROSSED (i) == 0))
{
if (reg_renumber[i] < 0
&& reg_may_share[i] && reg_allocno[reg_may_share[i]] >= 0)
@@ -488,6 +489,8 @@ global_alloc (FILE *file)
allocno[num].reg = i;
allocno[num].size = PSEUDO_REGNO_SIZE (i);
allocno[num].calls_crossed += REG_N_CALLS_CROSSED (i);
+ allocno[num].throwing_calls_crossed
+ += REG_N_THROWING_CALLS_CROSSED (i);
allocno[num].n_refs += REG_N_REFS (i);
allocno[num].freq += REG_FREQ (i);
if (allocno[num].live_length < REG_LIVE_LENGTH (i))
@@ -1207,9 +1210,11 @@ find_reg (int num, HARD_REG_SET losers, int alt_regs_p, int accept_call_clobbere
{
/* Did not find a register. If it would be profitable to
allocate a call-clobbered register and save and restore it
- around calls, do that. */
+ around calls, do that. Don't do this if it crosses any calls
+ that might throw. */
if (! accept_call_clobbered
&& allocno[num].calls_crossed != 0
+ && allocno[num].throwing_calls_crossed == 0
&& CALLER_SAVE_PROFITABLE (allocno[num].n_refs,
allocno[num].calls_crossed))
{
diff --git a/gcc/local-alloc.c b/gcc/local-alloc.c
index cd26174fa6a..4ee4991d0cd 100644
--- a/gcc/local-alloc.c
+++ b/gcc/local-alloc.c
@@ -123,6 +123,11 @@ struct qty
int n_calls_crossed;
+ /* Number of times a reg tied to given qty lives across a CALL_INSN
+ that might throw. */
+
+ int n_throwing_calls_crossed;
+
/* The register number of one pseudo register whose reg_qty value is Q.
This register should be the head of the chain
maintained in reg_next_in_qty. */
@@ -324,6 +329,7 @@ alloc_qty (int regno, enum machine_mode mode, int size, int birth)
qty[qtyno].mode = mode;
qty[qtyno].birth = birth;
qty[qtyno].n_calls_crossed = REG_N_CALLS_CROSSED (regno);
+ qty[qtyno].n_throwing_calls_crossed = REG_N_THROWING_CALLS_CROSSED (regno);
qty[qtyno].min_class = reg_preferred_class (regno);
qty[qtyno].alternate_class = reg_alternate_class (regno);
qty[qtyno].n_refs = REG_N_REFS (regno);
@@ -1170,6 +1176,7 @@ update_equiv_regs (void)
REG_BASIC_BLOCK (regno) = bb->index;
REG_N_CALLS_CROSSED (regno) = 0;
+ REG_N_THROWING_CALLS_CROSSED (regno) = 0;
REG_LIVE_LENGTH (regno) = 2;
if (insn == BB_HEAD (bb))
@@ -2011,6 +2018,8 @@ combine_regs (rtx usedreg, rtx setreg, int may_save_copy, int insn_number,
/* Update info about quantity SQTY. */
qty[sqty].n_calls_crossed += REG_N_CALLS_CROSSED (sreg);
+ qty[sqty].n_throwing_calls_crossed
+ += REG_N_THROWING_CALLS_CROSSED (sreg);
qty[sqty].n_refs += REG_N_REFS (sreg);
qty[sqty].freq += REG_FREQ (sreg);
if (usize < ssize)
@@ -2315,12 +2324,14 @@ find_free_reg (enum reg_class class, enum machine_mode mode, int qtyno,
/* We need not check to see if the current function has nonlocal
labels because we don't put any pseudos that are live over calls in
- registers in that case. */
+ registers in that case. Avoid putting pseudos crossing calls that
+ might throw into call used registers. */
if (! accept_call_clobbered
&& flag_caller_saves
&& ! just_try_suggested
&& qty[qtyno].n_calls_crossed != 0
+ && qty[qtyno].n_throwing_calls_crossed == 0
&& CALLER_SAVE_PROFITABLE (qty[qtyno].n_refs,
qty[qtyno].n_calls_crossed))
{