reload.h (elimination_target_reg_p): Declare.

gcc/
	* reload.h (elimination_target_reg_p): Declare.
	* reload.c (find_reloads): Don't apply the reg_rtx move
	optimization if the SET_DEST satisfies elimination_target_reg_p.
	* reload1.c (elimination_target_reg_p): New function.
	(gen_reload): In the move/add2 fallback, make sure that op0
	does not overlap the destination register.

From-SVN: r124215
This commit is contained in:
Richard Sandiford 2007-04-27 11:39:47 +00:00 committed by Richard Sandiford
parent a9b77cd1f7
commit 8c74fb06c6
4 changed files with 27 additions and 1 deletions

View File

@ -1,3 +1,12 @@
2007-04-27 Richard Sandiford <richard@codesourcery.com>
* reload.h (elimination_target_reg_p): Declare.
* reload.c (find_reloads): Don't apply the reg_rtx move
optimization if the SET_DEST satisfies elimination_target_reg_p.
* reload1.c (elimination_target_reg_p): New function.
(gen_reload): In the move/add2 fallback, make sure that op0
does not overlap the destination register.
2007-04-27 Zdenek Dvorak <dvorakz@suse.cz>
* tree-ssa-loop-im.c (determine_invariantness_stmt): Attempt to

View File

@ -4465,7 +4465,8 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
if (rld[i].when_needed == RELOAD_FOR_INPUT
&& GET_CODE (PATTERN (insn)) == SET
&& REG_P (SET_DEST (PATTERN (insn)))
&& SET_SRC (PATTERN (insn)) == rld[i].in)
&& SET_SRC (PATTERN (insn)) == rld[i].in
&& !elimination_target_reg_p (SET_DEST (PATTERN (insn))))
{
rtx dest = SET_DEST (PATTERN (insn));
unsigned int regno = REGNO (dest);

View File

@ -342,6 +342,7 @@ extern void mark_home_live (int);
/* Scan X and replace any eliminable registers (such as fp) with a
replacement (such as sp), plus an offset. */
extern rtx eliminate_regs (rtx, enum machine_mode, rtx);
extern bool elimination_target_reg_p (rtx);
/* Deallocate the reload register used by reload number R. */
extern void deallocate_reload_reg (int r);

View File

@ -3607,6 +3607,20 @@ update_eliminables (HARD_REG_SET *pset)
SET_HARD_REG_BIT (*pset, HARD_FRAME_POINTER_REGNUM);
}
/* Return true if X is used as the target register of an elimination. */
bool
elimination_target_reg_p (rtx x)
{
struct elim_table *ep;
for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
if (ep->to_rtx == x && ep->can_eliminate)
return true;
return false;
}
/* Initialize the table of registers to eliminate. */
static void
@ -7873,6 +7887,7 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
/* If that failed, copy the address register to the reload register.
Then add the constant to the reload register. */
gcc_assert (!reg_overlap_mentioned_p (out, op0));
gen_reload (out, op1, opnum, type);
insn = emit_insn (gen_add2_insn (out, op0));
set_unique_reg_note (insn, REG_EQUIV, in);