Commit 95c37cdb by Jakub Jelinek Committed by Jakub Jelinek

re PR rtl-optimization/23478 (Miscompilation due to reloading of a var that is also used in EH pad)

	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.

From-SVN: r103718
parent 1990cd79
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> 2005-09-01 Alan Modra <amodra@bigpond.net.au>
PR target/23649 PR target/23649
......
...@@ -97,6 +97,9 @@ struct allocno ...@@ -97,6 +97,9 @@ struct allocno
/* Number of calls crossed by each allocno. */ /* Number of calls crossed by each allocno. */
int calls_crossed; int calls_crossed;
/* Number of calls that might throw crossed by each allocno. */
int throwing_calls_crossed;
/* Number of refs to each allocno. */ /* Number of refs to each allocno. */
int n_refs; int n_refs;
...@@ -465,9 +468,7 @@ global_alloc (FILE *file) ...@@ -465,9 +468,7 @@ global_alloc (FILE *file)
/* Don't allocate pseudos that cross calls, /* Don't allocate pseudos that cross calls,
if this function receives a nonlocal goto. */ if this function receives a nonlocal goto. */
&& (! current_function_has_nonlocal_label && (! current_function_has_nonlocal_label
|| REG_N_CALLS_CROSSED (i) == 0) || REG_N_CALLS_CROSSED (i) == 0))
/* Don't allocate pseudos that cross calls that may throw. */
&& REG_N_THROWING_CALLS_CROSSED (i) == 0)
{ {
if (reg_renumber[i] < 0 if (reg_renumber[i] < 0
&& reg_may_share[i] && reg_allocno[reg_may_share[i]] >= 0) && reg_may_share[i] && reg_allocno[reg_may_share[i]] >= 0)
...@@ -488,6 +489,8 @@ global_alloc (FILE *file) ...@@ -488,6 +489,8 @@ global_alloc (FILE *file)
allocno[num].reg = i; allocno[num].reg = i;
allocno[num].size = PSEUDO_REGNO_SIZE (i); allocno[num].size = PSEUDO_REGNO_SIZE (i);
allocno[num].calls_crossed += REG_N_CALLS_CROSSED (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].n_refs += REG_N_REFS (i);
allocno[num].freq += REG_FREQ (i); allocno[num].freq += REG_FREQ (i);
if (allocno[num].live_length < REG_LIVE_LENGTH (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 ...@@ -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 /* Did not find a register. If it would be profitable to
allocate a call-clobbered register and save and restore it 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 if (! accept_call_clobbered
&& allocno[num].calls_crossed != 0 && allocno[num].calls_crossed != 0
&& allocno[num].throwing_calls_crossed == 0
&& CALLER_SAVE_PROFITABLE (allocno[num].n_refs, && CALLER_SAVE_PROFITABLE (allocno[num].n_refs,
allocno[num].calls_crossed)) allocno[num].calls_crossed))
{ {
......
...@@ -123,6 +123,11 @@ struct qty ...@@ -123,6 +123,11 @@ struct qty
int n_calls_crossed; 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. /* The register number of one pseudo register whose reg_qty value is Q.
This register should be the head of the chain This register should be the head of the chain
maintained in reg_next_in_qty. */ maintained in reg_next_in_qty. */
...@@ -324,6 +329,7 @@ alloc_qty (int regno, enum machine_mode mode, int size, int birth) ...@@ -324,6 +329,7 @@ alloc_qty (int regno, enum machine_mode mode, int size, int birth)
qty[qtyno].mode = mode; qty[qtyno].mode = mode;
qty[qtyno].birth = birth; qty[qtyno].birth = birth;
qty[qtyno].n_calls_crossed = REG_N_CALLS_CROSSED (regno); 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].min_class = reg_preferred_class (regno);
qty[qtyno].alternate_class = reg_alternate_class (regno); qty[qtyno].alternate_class = reg_alternate_class (regno);
qty[qtyno].n_refs = REG_N_REFS (regno); qty[qtyno].n_refs = REG_N_REFS (regno);
...@@ -1170,6 +1176,7 @@ update_equiv_regs (void) ...@@ -1170,6 +1176,7 @@ update_equiv_regs (void)
REG_BASIC_BLOCK (regno) = bb->index; REG_BASIC_BLOCK (regno) = bb->index;
REG_N_CALLS_CROSSED (regno) = 0; REG_N_CALLS_CROSSED (regno) = 0;
REG_N_THROWING_CALLS_CROSSED (regno) = 0;
REG_LIVE_LENGTH (regno) = 2; REG_LIVE_LENGTH (regno) = 2;
if (insn == BB_HEAD (bb)) if (insn == BB_HEAD (bb))
...@@ -2011,6 +2018,8 @@ combine_regs (rtx usedreg, rtx setreg, int may_save_copy, int insn_number, ...@@ -2011,6 +2018,8 @@ combine_regs (rtx usedreg, rtx setreg, int may_save_copy, int insn_number,
/* Update info about quantity SQTY. */ /* Update info about quantity SQTY. */
qty[sqty].n_calls_crossed += REG_N_CALLS_CROSSED (sreg); 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].n_refs += REG_N_REFS (sreg);
qty[sqty].freq += REG_FREQ (sreg); qty[sqty].freq += REG_FREQ (sreg);
if (usize < ssize) if (usize < ssize)
...@@ -2315,12 +2324,14 @@ find_free_reg (enum reg_class class, enum machine_mode mode, int qtyno, ...@@ -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 /* 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 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 if (! accept_call_clobbered
&& flag_caller_saves && flag_caller_saves
&& ! just_try_suggested && ! just_try_suggested
&& qty[qtyno].n_calls_crossed != 0 && qty[qtyno].n_calls_crossed != 0
&& qty[qtyno].n_throwing_calls_crossed == 0
&& CALLER_SAVE_PROFITABLE (qty[qtyno].n_refs, && CALLER_SAVE_PROFITABLE (qty[qtyno].n_refs,
qty[qtyno].n_calls_crossed)) qty[qtyno].n_calls_crossed))
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment