reload.c (find_reloads_address_1): Handle PLUS expressions resulting from register...
authorUlrich Weigand <uweigand@de.ibm.com>
Sun, 25 Feb 2007 20:56:46 +0000 (20:56 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Sun, 25 Feb 2007 20:56:46 +0000 (20:56 +0000)
* reload.c (find_reloads_address_1): Handle PLUS expressions resulting
from register elimination as PRE_MODIFY / POST_MODIFY increments.
Do not attempt to handle MEM inside auto-inc expressions.
* reload1.c (eliminate_regs_1): Do not attempt to handle elimination
of a register modified by an auto-inc expression.  However, do handle
elimination of a register used as PRE_MODIFY / POST_MODIFY increment.
(elimination_effects): Prohibit elimination of a register modified
by an auto-inc expression.  Disable register elimination rules whose
target register is modified by an auto-inc expression with variable
increment.

From-SVN: r122318

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

index e835441..2ed4912 100644 (file)
@@ -1,3 +1,16 @@
+2007-02-25  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * reload.c (find_reloads_address_1): Handle PLUS expressions resulting
+       from register elimination as PRE_MODIFY / POST_MODIFY increments.
+       Do not attempt to handle MEM inside auto-inc expressions.
+       * reload1.c (eliminate_regs_1): Do not attempt to handle elimination
+       of a register modified by an auto-inc expression.  However, do handle
+       elimination of a register used as PRE_MODIFY / POST_MODIFY increment.
+       (elimination_effects): Prohibit elimination of a register modified
+       by an auto-inc expression.  Disable register elimination rules whose
+       target register is modified by an auto-inc expression with variable
+       increment.
+
 2007-02-25  Zdenek Dvorak  <dvorakz@suse.cz>
 
        * tree-ssa-loop-niter.c (compute_estimated_nb_iterations): Fix
index 21c5ed2..c297494 100644 (file)
@@ -5543,16 +5543,20 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
           auto-modify by a constant then we could try replacing a pseudo
           register with its equivalent constant where applicable.
 
+          We also handle the case where the register was eliminated
+          resulting in a PLUS subexpression.
+
           If we later decide to reload the whole PRE_MODIFY or
           POST_MODIFY, inc_for_reload might clobber the reload register
           before reading the index.  The index register might therefore
           need to live longer than a TYPE reload normally would, so be
           conservative and class it as RELOAD_OTHER.  */
-       if (REG_P (XEXP (op1, 1)))
-         if (!REGNO_OK_FOR_INDEX_P (REGNO (XEXP (op1, 1))))
-           find_reloads_address_1 (mode, XEXP (op1, 1), 1, code, SCRATCH,
-                                   &XEXP (op1, 1), opnum, RELOAD_OTHER,
-                                   ind_levels, insn);
+       if ((REG_P (XEXP (op1, 1))
+            && !REGNO_OK_FOR_INDEX_P (REGNO (XEXP (op1, 1))))
+           || GET_CODE (XEXP (op1, 1)) == PLUS)
+         find_reloads_address_1 (mode, XEXP (op1, 1), 1, code, SCRATCH,
+                                 &XEXP (op1, 1), opnum, RELOAD_OTHER,
+                                 ind_levels, insn);
 
        gcc_assert (REG_P (XEXP (op1, 0)));
 
@@ -5733,43 +5737,6 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
            }
          return value;
        }
-
-      else if (MEM_P (XEXP (x, 0)))
-       {
-         /* This is probably the result of a substitution, by eliminate_regs,
-            of an equivalent address for a pseudo that was not allocated to a
-            hard register.  Verify that the specified address is valid and
-            reload it into a register.  */
-         /* Variable `tem' might or might not be used in FIND_REG_INC_NOTE.  */
-         rtx tem ATTRIBUTE_UNUSED = XEXP (x, 0);
-         rtx link;
-         int reloadnum;
-
-         /* Since we know we are going to reload this item, don't decrement
-            for the indirection level.
-
-            Note that this is actually conservative:  it would be slightly
-            more efficient to use the value of SPILL_INDIRECT_LEVELS from
-            reload1.c here.  */
-         /* We can't use ADDR_TYPE (type) here, because we need to
-            write back the value after reading it, hence we actually
-            need two registers.  */
-         find_reloads_address (GET_MODE (x), &XEXP (x, 0),
-                               XEXP (XEXP (x, 0), 0), &XEXP (XEXP (x, 0), 0),
-                               opnum, type, ind_levels, insn);
-
-         reloadnum = push_reload (x, NULL_RTX, loc, (rtx*) 0,
-                                  context_reg_class,
-                                  GET_MODE (x), VOIDmode, 0, 0, opnum, type);
-         rld[reloadnum].inc
-           = find_inc_amount (PATTERN (this_insn), XEXP (x, 0));
-
-         link = FIND_REG_INC_NOTE (this_insn, tem);
-         if (link != 0)
-           push_replacement (&XEXP (link, 0), reloadnum, VOIDmode);
-
-         return 1;
-       }
       return 0;
 
     case TRUNCATE:
index c86b2bd..c469fb0 100644 (file)
@@ -2548,6 +2548,30 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
     case POST_INC:
     case PRE_DEC:
     case POST_DEC:
+      /* We do not support elimination of a register that is modified.
+        elimination_effects has already make sure that this does not
+        happen.  */
+      return x;
+
+    case PRE_MODIFY:
+    case POST_MODIFY:
+      /* We do not support elimination of a register that is modified.
+        elimination_effects has already make sure that this does not
+        happen.  The only remaining case we need to consider here is
+        that the increment value may be an eliminable register.  */
+      if (GET_CODE (XEXP (x, 1)) == PLUS
+         && XEXP (XEXP (x, 1), 0) == XEXP (x, 0))
+       {
+         rtx new = eliminate_regs_1 (XEXP (XEXP (x, 1), 1), mem_mode,
+                                     insn, true);
+
+         if (new != XEXP (XEXP (x, 1), 1))
+           return gen_rtx_fmt_ee (code, GET_MODE (x), XEXP (x, 0),
+                                  gen_rtx_PLUS (GET_MODE (x),
+                                                XEXP (x, 0), new));
+       }
+      return x;
+
     case STRICT_LOW_PART:
     case NEG:          case NOT:
     case SIGN_EXTEND:  case ZERO_EXTEND:
@@ -2743,6 +2767,14 @@ elimination_effects (rtx x, enum machine_mode mem_mode)
     case POST_DEC:
     case POST_MODIFY:
     case PRE_MODIFY:
+      /* If we modify the source of an elimination rule, disable it.  */
+      for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
+       if (ep->from_rtx == XEXP (x, 0))
+         ep->can_eliminate = 0;
+
+      /* If we modify the target of an elimination rule by adding a constant,
+        update its offset.  If we modify the target in any other way, we'll
+        have to disable the rule as well.  */
       for (ep = reg_eliminate; ep < &reg_eliminate[NUM_ELIMINABLE_REGS]; ep++)
        if (ep->to_rtx == XEXP (x, 0))
          {
@@ -2757,11 +2789,15 @@ elimination_effects (rtx x, enum machine_mode mem_mode)
              ep->offset += size;
            else if (code == PRE_INC || code == POST_INC)
              ep->offset -= size;
-           else if ((code == PRE_MODIFY || code == POST_MODIFY)
-                    && GET_CODE (XEXP (x, 1)) == PLUS
-                    && XEXP (x, 0) == XEXP (XEXP (x, 1), 0)
-                    && CONSTANT_P (XEXP (XEXP (x, 1), 1)))
-             ep->offset -= INTVAL (XEXP (XEXP (x, 1), 1));
+           else if (code == PRE_MODIFY || code == POST_MODIFY)
+             {
+               if (GET_CODE (XEXP (x, 1)) == PLUS
+                   && XEXP (x, 0) == XEXP (XEXP (x, 1), 0)
+                   && CONST_INT_P (XEXP (XEXP (x, 1), 1)))
+                 ep->offset -= INTVAL (XEXP (XEXP (x, 1), 1));
+               else
+                 ep->can_eliminate = 0;
+             }
          }
 
       /* These two aren't unary operators.  */