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>
PR target/23649
......
......@@ -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))
{
......
......@@ -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))
{
......
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