OSDN Git Service

- add missing ChangeLog entry, see PR27334
[pf3gnuchains/gcc-fork.git] / gcc / reload1.c
index 87cc425..d791da6 100644 (file)
@@ -36,6 +36,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "expr.h"
 #include "optabs.h"
 #include "regs.h"
+#include "addresses.h"
 #include "basic-block.h"
 #include "reload.h"
 #include "recog.h"
@@ -111,7 +112,7 @@ rtx *reg_equiv_memory_loc;
 
 /* We allocate reg_equiv_memory_loc inside a varray so that the garbage
    collector can keep track of what is inside.  */
-varray_type reg_equiv_memory_loc_varray;
+VEC(rtx,gc) *reg_equiv_memory_loc_vec;
 
 /* Element N is the address of stack slot to which pseudo reg N is equivalent.
    This is used when the address is not valid as a memory address
@@ -495,7 +496,6 @@ init_reload (void)
 
   INIT_REG_SET (&spilled_pseudos);
   INIT_REG_SET (&pseudos_counted);
-  VARRAY_RTX_INIT (reg_equiv_memory_loc_varray, 0, "reg_equiv_memory_loc");
 }
 
 /* List of insn chains that are currently unused.  */
@@ -1250,7 +1250,7 @@ reload (rtx first, int global)
     free (reg_equiv_invariant);
   reg_equiv_constant = 0;
   reg_equiv_invariant = 0;
-  VARRAY_GROW (reg_equiv_memory_loc_varray, 0);
+  VEC_free (rtx, gc, reg_equiv_memory_loc_vec);
   reg_equiv_memory_loc = 0;
 
   if (offsets_known_at)
@@ -1375,7 +1375,7 @@ maybe_fix_stack_asms (void)
 
                case 'p':
                  cls = (int) reg_class_subunion[cls]
-                   [(int) MODE_BASE_REG_CLASS (VOIDmode)];
+                     [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
                  break;
 
                case 'g':
@@ -1386,7 +1386,7 @@ maybe_fix_stack_asms (void)
                default:
                  if (EXTRA_ADDRESS_CONSTRAINT (c, p))
                    cls = (int) reg_class_subunion[cls]
-                     [(int) MODE_BASE_REG_CLASS (VOIDmode)];
+                     [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
                  else
                    cls = (int) reg_class_subunion[cls]
                      [(int) REG_CLASS_FROM_CONSTRAINT (c, p)];
@@ -2607,9 +2607,7 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
          new = eliminate_regs_1 (XEXP (x, i), mem_mode, insn, false);
          if (new != XEXP (x, i) && ! copied)
            {
-             rtx new_x = rtx_alloc (code);
-             memcpy (new_x, x, RTX_SIZE (code));
-             x = new_x;
+             x = shallow_copy_rtx (x);
              copied = 1;
            }
          XEXP (x, i) = new;
@@ -2626,9 +2624,7 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
                                             XVEC (x, i)->elem);
                  if (! copied)
                    {
-                     rtx new_x = rtx_alloc (code);
-                     memcpy (new_x, x, RTX_SIZE (code));
-                     x = new_x;
+                     x = shallow_copy_rtx (x);
                      copied = 1;
                    }
                  XVEC (x, i) = new_v;
@@ -5508,10 +5504,7 @@ choose_reload_regs (struct insn_chain *chain)
                  mode = GET_MODE (rld[r].in_reg);
                }
 #ifdef AUTO_INC_DEC
-             else if ((GET_CODE (rld[r].in_reg) == PRE_INC
-                       || GET_CODE (rld[r].in_reg) == PRE_DEC
-                       || GET_CODE (rld[r].in_reg) == POST_INC
-                       || GET_CODE (rld[r].in_reg) == POST_DEC)
+             else if (GET_RTX_CLASS (GET_CODE (rld[r].in_reg)) == RTX_AUTOINC
                       && REG_P (XEXP (rld[r].in_reg, 0)))
                {
                  regno = REGNO (XEXP (rld[r].in_reg, 0));
@@ -5780,7 +5773,7 @@ choose_reload_regs (struct insn_chain *chain)
 
              if (equiv != 0)
                {
-                 if (regno_clobbered_p (regno, insn, rld[r].mode, 0))
+                 if (regno_clobbered_p (regno, insn, rld[r].mode, 2))
                    switch (rld[r].when_needed)
                      {
                      case RELOAD_FOR_OTHER_ADDRESS:
@@ -7419,13 +7412,18 @@ emit_reload_insns (struct insn_chain *chain)
       /* If a register gets output-reloaded from a non-spill register,
         that invalidates any previous reloaded copy of it.
         But forget_old_reloads_1 won't get to see it, because
-        it thinks only about the original insn.  So invalidate it here.  */
-      if (i < 0 && rld[r].out != 0
-         && (REG_P (rld[r].out)
-             || (MEM_P (rld[r].out)
+        it thinks only about the original insn.  So invalidate it here.
+        Also do the same thing for RELOAD_OTHER constraints where the
+        output is discarded.  */
+      if (i < 0 
+         && ((rld[r].out != 0
+              && (REG_P (rld[r].out)
+                  || (MEM_P (rld[r].out)
+                      && REG_P (rld[r].out_reg))))
+             || (rld[r].out == 0 && rld[r].out_reg
                  && REG_P (rld[r].out_reg))))
        {
-         rtx out = (REG_P (rld[r].out)
+         rtx out = ((rld[r].out && REG_P (rld[r].out))
                     ? rld[r].out : rld[r].out_reg);
          int nregno = REGNO (out);
          if (nregno >= FIRST_PSEUDO_REGISTER)
@@ -7501,7 +7499,7 @@ emit_reload_insns (struct insn_chain *chain)
            }
          else
            {
-             int num_regs = hard_regno_nregs[nregno][GET_MODE (rld[r].out)];
+             int num_regs = hard_regno_nregs[nregno][GET_MODE (out)];
 
              while (num_regs-- > 0)
                reg_last_reload_reg[nregno + num_regs] = 0;
@@ -7721,6 +7719,10 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
       rtx out_moded;
       rtx set;
 
+      op1 = find_replacement (&XEXP (in, 0));
+      if (op1 != XEXP (in, 0))
+       in = gen_rtx_fmt_e (GET_CODE (in), GET_MODE (in), op1);
+
       /* First, try a plain SET.  */
       set = emit_insn_if_valid_for_reload (gen_rtx_SET (VOIDmode, out, in));
       if (set)
@@ -7729,7 +7731,6 @@ gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
       /* If that failed, move the inner operand to the reload
         register, and try the same unop with the inner expression
         replaced with the reload register.  */
-      op1 = XEXP (in, 0);
 
       if (GET_MODE (op1) != GET_MODE (out))
        out_moded = gen_rtx_REG (GET_MODE (op1), REGNO (out));
@@ -8110,7 +8111,8 @@ inc_for_reload (rtx reloadreg, rtx in, rtx value, int inc_amount)
   /* REG or MEM to be copied and incremented.  */
   rtx incloc = XEXP (value, 0);
   /* Nonzero if increment after copying.  */
-  int post = (GET_CODE (value) == POST_DEC || GET_CODE (value) == POST_INC);
+  int post = (GET_CODE (value) == POST_DEC || GET_CODE (value) == POST_INC
+             || GET_CODE (value) == POST_MODIFY);
   rtx last;
   rtx inc;
   rtx add_insn;
@@ -8125,10 +8127,18 @@ inc_for_reload (rtx reloadreg, rtx in, rtx value, int inc_amount)
   if (REG_P (incloc))
     reg_last_reload_reg[REGNO (incloc)] = 0;
 
-  if (GET_CODE (value) == PRE_DEC || GET_CODE (value) == POST_DEC)
-    inc_amount = -inc_amount;
+  if (GET_CODE (value) == PRE_MODIFY || GET_CODE (value) == POST_MODIFY)
+    {
+      gcc_assert (GET_CODE (XEXP (value, 1)) == PLUS);
+      inc = XEXP (XEXP (value, 1), 1);
+    }
+  else
+    {
+      if (GET_CODE (value) == PRE_DEC || GET_CODE (value) == POST_DEC)
+       inc_amount = -inc_amount;
 
-  inc = GEN_INT (inc_amount);
+      inc = GEN_INT (inc_amount);
+    }
 
   /* If this is post-increment, first copy the location to the reload reg.  */
   if (post && real_in != reloadreg)
@@ -8188,7 +8198,10 @@ inc_for_reload (rtx reloadreg, rtx in, rtx value, int inc_amount)
 
       emit_insn (gen_add2_insn (reloadreg, inc));
       store = emit_insn (gen_move_insn (incloc, reloadreg));
-      emit_insn (gen_add2_insn (reloadreg, GEN_INT (-inc_amount)));
+      if (GET_CODE (inc) == CONST_INT)
+       emit_insn (gen_add2_insn (reloadreg, GEN_INT (-INTVAL(inc))));
+      else
+       emit_insn (gen_sub2_insn (reloadreg, inc));
     }
 
   return store;