reload.h (elimination_target_reg_p): Declare.
authorRichard Sandiford <richard@codesourcery.com>
Fri, 27 Apr 2007 11:39:47 +0000 (11:39 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Fri, 27 Apr 2007 11:39:47 +0000 (11:39 +0000)
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

gcc/ChangeLog
gcc/reload.c
gcc/reload.h
gcc/reload1.c

index 447dc85588b72082d7109efbfa8ab7b7de293ad9..d56233977f6dda76728580387aad30fea9a648b7 100644 (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
index de6093b03395140fbac8039580ffc9cbbc3c6e72..8ed2f4b38804a1f8df7739b8e527217ddaed3fab 100644 (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);
index 6de5e8471bfce4216b34a09ef86aa11b0923a2f4..38d340fd5cd63f17e7c17430c02ddfa31dbfde85 100644 (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);
index 9ee046ae1ecb794733a25deadffa11fd9a013577..4d2dea520b8363c459c8c4d4118bcfd1b5072466 100644 (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);