summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2007-04-27 11:39:47 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2007-04-27 11:39:47 +0000
commiteca883d12f3f5835c7ce868b38d847d4e506e823 (patch)
treea4840b670d6361a1ddbbb4b10ca1921ee3bb7e7c /gcc
parent63f88450d46e1453137aa58c1808134fe68a8f18 (diff)
downloadgcc-eca883d12f3f5835c7ce868b38d847d4e506e823.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@124215 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/reload.c3
-rw-r--r--gcc/reload.h1
-rw-r--r--gcc/reload1.c15
4 files changed, 27 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 447dc85588b..d56233977f6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/reload.c b/gcc/reload.c
index de6093b0339..8ed2f4b3880 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -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);
diff --git a/gcc/reload.h b/gcc/reload.h
index 6de5e8471bf..38d340fd5cd 100644
--- a/gcc/reload.h
+++ b/gcc/reload.h
@@ -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);
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 9ee046ae1ec..4d2dea520b8 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -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);