diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-09-01 05:29:03 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-09-01 05:29:03 +0000 |
commit | d9903bcbbe19100d94f5dd9dcdb1a5276e7dfbe5 (patch) | |
tree | 51f172c784c1a0fb89978ba5eedd01b262b307a4 | |
parent | ef07ff3370aa4c7a31df6187583111c0e1b3b63a (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/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/global.c | 13 | ||||
-rw-r--r-- | gcc/local-alloc.c | 13 |
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)) { |