Commit db4c7386 by Jan Hubicka Committed by Jan Hubicka

re PR tree-optimization/27865 (tree check failure building FreePOOMA)

	PR tree-optimization/27865
	* reload1.c (forget_marked_reloads): New function.
	(forget_old_reloads_1): When data are passed, just mark the registers
	for later removal.
	(reload_as_needed): Use the new mechanizm.

From-SVN: r116220
parent 04499540
2006-08-17 Jan Hubicka <jh@suse.cz>
PR tree-optimization/27865
* reload1.c (forget_marked_reloads): New function.
(forget_old_reloads_1): When data are passed, just mark the registers
for later removal.
(reload_as_needed): Use the new mechanizm.
2006-08-17 Alexandre Oliva <aoliva@redhat.com> 2006-08-17 Alexandre Oliva <aoliva@redhat.com>
PR target/28146 PR target/28146
......
...@@ -408,6 +408,7 @@ static void count_pseudo (int); ...@@ -408,6 +408,7 @@ static void count_pseudo (int);
static void order_regs_for_reload (struct insn_chain *); static void order_regs_for_reload (struct insn_chain *);
static void reload_as_needed (int); static void reload_as_needed (int);
static void forget_old_reloads_1 (rtx, rtx, void *); static void forget_old_reloads_1 (rtx, rtx, void *);
static void forget_marked_reloads (regset);
static int reload_reg_class_lower (const void *, const void *); static int reload_reg_class_lower (const void *, const void *);
static void mark_reload_reg_in_use (unsigned int, int, enum reload_type, static void mark_reload_reg_in_use (unsigned int, int, enum reload_type,
enum machine_mode); enum machine_mode);
...@@ -3907,8 +3908,9 @@ reload_as_needed (int live_known) ...@@ -3907,8 +3908,9 @@ reload_as_needed (int live_known)
else if (INSN_P (insn)) else if (INSN_P (insn))
{ {
rtx oldpat = copy_rtx (PATTERN (insn)); regset_head regs_to_forget;
INIT_REG_SET (&regs_to_forget);
note_stores (PATTERN (insn), forget_old_reloads_1, &regs_to_forget);
/* If this is a USE and CLOBBER of a MEM, ensure that any /* If this is a USE and CLOBBER of a MEM, ensure that any
references to eliminable registers have been removed. */ references to eliminable registers have been removed. */
...@@ -3928,6 +3930,7 @@ reload_as_needed (int live_known) ...@@ -3928,6 +3930,7 @@ reload_as_needed (int live_known)
if (NOTE_P (insn)) if (NOTE_P (insn))
{ {
update_eliminable_offsets (); update_eliminable_offsets ();
CLEAR_REG_SET (&regs_to_forget);
continue; continue;
} }
} }
...@@ -4014,7 +4017,8 @@ reload_as_needed (int live_known) ...@@ -4014,7 +4017,8 @@ reload_as_needed (int live_known)
for this insn in order to be stored in for this insn in order to be stored in
(obeying register constraints). That is correct; such reload (obeying register constraints). That is correct; such reload
registers ARE still valid. */ registers ARE still valid. */
note_stores (oldpat, forget_old_reloads_1, NULL); forget_marked_reloads (&regs_to_forget);
CLEAR_REG_SET (&regs_to_forget);
/* There may have been CLOBBER insns placed after INSN. So scan /* There may have been CLOBBER insns placed after INSN. So scan
between INSN and NEXT and use them to forget old reloads. */ between INSN and NEXT and use them to forget old reloads. */
...@@ -4163,14 +4167,18 @@ reload_as_needed (int live_known) ...@@ -4163,14 +4167,18 @@ reload_as_needed (int live_known)
unless X is an output reload reg of the current insn. unless X is an output reload reg of the current insn.
X may be a hard reg (the reload reg) X may be a hard reg (the reload reg)
or it may be a pseudo reg that was reloaded from. */ or it may be a pseudo reg that was reloaded from.
When DATA is non-NULL just mark the registers in regset
to be forgotten later. */
static void static void
forget_old_reloads_1 (rtx x, rtx ignored ATTRIBUTE_UNUSED, forget_old_reloads_1 (rtx x, rtx ignored ATTRIBUTE_UNUSED,
void *data ATTRIBUTE_UNUSED) void *data)
{ {
unsigned int regno; unsigned int regno;
unsigned int nr; unsigned int nr;
regset regs = (regset) data;
/* note_stores does give us subregs of hard regs, /* note_stores does give us subregs of hard regs,
subreg_regno_offset requires a hard reg. */ subreg_regno_offset requires a hard reg. */
...@@ -4198,26 +4206,56 @@ forget_old_reloads_1 (rtx x, rtx ignored ATTRIBUTE_UNUSED, ...@@ -4198,26 +4206,56 @@ forget_old_reloads_1 (rtx x, rtx ignored ATTRIBUTE_UNUSED,
This can happen if a block-local pseudo is allocated to that reg This can happen if a block-local pseudo is allocated to that reg
and it wasn't spilled because this block's total need is 0. and it wasn't spilled because this block's total need is 0.
Then some insn might have an optional reload and use this reg. */ Then some insn might have an optional reload and use this reg. */
for (i = 0; i < nr; i++) if (!regs)
/* But don't do this if the reg actually serves as an output for (i = 0; i < nr; i++)
reload reg in the current instruction. */ /* But don't do this if the reg actually serves as an output
if (n_reloads == 0 reload reg in the current instruction. */
|| ! TEST_HARD_REG_BIT (reg_is_output_reload, regno + i)) if (n_reloads == 0
{ || ! TEST_HARD_REG_BIT (reg_is_output_reload, regno + i))
CLEAR_HARD_REG_BIT (reg_reloaded_valid, regno + i); {
CLEAR_HARD_REG_BIT (reg_reloaded_call_part_clobbered, regno + i); CLEAR_HARD_REG_BIT (reg_reloaded_valid, regno + i);
spill_reg_store[regno + i] = 0; CLEAR_HARD_REG_BIT (reg_reloaded_call_part_clobbered, regno + i);
} spill_reg_store[regno + i] = 0;
}
} }
/* Since value of X has changed, if (regs)
forget any value previously copied from it. */ while (nr-- > 0)
SET_REGNO_REG_SET (regs, regno + nr);
else
{
/* Since value of X has changed,
forget any value previously copied from it. */
while (nr-- > 0)
/* But don't forget a copy if this is the output reload
that establishes the copy's validity. */
if (n_reloads == 0 || reg_has_output_reload[regno + nr] == 0)
reg_last_reload_reg[regno + nr] = 0;
}
}
while (nr-- > 0) /* Forget the reloads marked in regset by previous function. */
/* But don't forget a copy if this is the output reload static void
that establishes the copy's validity. */ forget_marked_reloads (regset regs)
if (n_reloads == 0 || reg_has_output_reload[regno + nr] == 0) {
reg_last_reload_reg[regno + nr] = 0; unsigned int reg;
reg_set_iterator rsi;
EXECUTE_IF_SET_IN_REG_SET (regs, 0, reg, rsi)
{
if (reg < FIRST_PSEUDO_REGISTER
/* But don't do this if the reg actually serves as an output
reload reg in the current instruction. */
&& (n_reloads == 0
|| ! TEST_HARD_REG_BIT (reg_is_output_reload, reg)))
{
CLEAR_HARD_REG_BIT (reg_reloaded_valid, reg);
CLEAR_HARD_REG_BIT (reg_reloaded_call_part_clobbered, reg);
spill_reg_store[reg] = 0;
}
if (n_reloads == 0 || reg_has_output_reload[reg] == 0)
reg_last_reload_reg[reg] = 0;
}
} }
/* The following HARD_REG_SETs indicate when each hard register is /* The following HARD_REG_SETs indicate when each hard register is
......
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