]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Several fixes to make reload handle POST_MODIFY correctly.
authorbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 10 Nov 2000 17:10:29 +0000 (17:10 +0000)
committerbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 10 Nov 2000 17:10:29 +0000 (17:10 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@37370 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 5cc14f3d28b5229a3437c88c7afe05f520c75f50..532a9c6bfd5e12355a30fba87eddca981f7bf14a 100644 (file)
@@ -1,3 +1,12 @@
+2000-11-10  Bernd Schmidt  <bernds@redhat.co.uk>
+
+       * reload.c (find_reloads_address_1, case POST_MODIFY): Use RELOAD_OTHER
+       for address reloads.  Push replacements for REG_INC notes.
+       (regno_clobbered_p): New arg SETS.  Examine SETs if it's nonzero.  All
+       callers changed.
+       * reload1.c (choose_reload_regs): Registers set in the insn can't be
+       used for RELOAD_OTHER reloads.
+
 2000-11-10  Mark Mitchell  <mark@codesourcery.com>
 
        * c-dump.h: New file.
index 65a5e731b4156801c2dcccd37ab7e5c6b14448a4..86d80c1af23bd670f753bd0231058e9539ba2e7d 100644 (file)
@@ -4536,7 +4536,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
 
       else if (regno < FIRST_PSEUDO_REGISTER
               && REGNO_MODE_OK_FOR_BASE_P (regno, mode)
-              && ! regno_clobbered_p (regno, this_insn, mode))
+              && ! regno_clobbered_p (regno, this_insn, mode, 0))
        return 0;
 
       /* If we do not have one of the cases above, we must do the reload.  */
@@ -5155,7 +5155,9 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
 
        if (REG_P (XEXP (op1, 0)))
          {
-           register int regno = REGNO (XEXP (op1, 0));
+           rtx link;
+           int regno = REGNO (XEXP (op1, 0));
+           int reloadnum;
 
            /* A register that is incremented cannot be constant!  */
            if (regno >= FIRST_PSEUDO_REGISTER
@@ -5178,15 +5180,17 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
                       write back the value after reading it, hence we actually
                       need two registers.  */
                    find_reloads_address (GET_MODE (tem), 0, XEXP (tem, 0),
-                                         &XEXP (tem, 0), opnum, type,
+                                         &XEXP (tem, 0), opnum,
+                                         RELOAD_OTHER,
                                          ind_levels, insn);
 
                    /* Then reload the memory location into a base
                       register.  */
-                   push_reload (tem, tem, &XEXP (x, 0), &XEXP (op1, 0),
-                                BASE_REG_CLASS, GET_MODE (x), GET_MODE (x),
-                                0, 0, opnum, RELOAD_OTHER);
-                   break;
+                   reloadnum = push_reload (tem, tem, &XEXP (x, 0),
+                                            &XEXP (op1, 0), BASE_REG_CLASS,
+                                            GET_MODE (x), GET_MODE (x), 0,
+                                            0, opnum, RELOAD_OTHER);
+                   goto reg_inc;
                  }
              }
 
@@ -5196,12 +5200,19 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
            /* We require a base register here...  */
            if (!REGNO_MODE_OK_FOR_BASE_P (regno, GET_MODE (x)))
              {
-               push_reload (XEXP (op1, 0), XEXP (x, 0),
-                            &XEXP (op1, 0), &XEXP (x, 0),
-                            BASE_REG_CLASS,
-                            GET_MODE (x), GET_MODE (x), 0, 0,
-                            opnum, RELOAD_OTHER);
+               reloadnum = push_reload (XEXP (op1, 0), XEXP (x, 0),
+                                        &XEXP (op1, 0), &XEXP (x, 0),
+                                        BASE_REG_CLASS,
+                                        GET_MODE (x), GET_MODE (x), 0, 0,
+                                        opnum, RELOAD_OTHER);
              }
+
+           /* Update the REG_INC notes.  */
+         reg_inc:
+           for (link = REG_NOTES (this_insn); link; link = XEXP (link, 1))
+             if (REG_NOTE_KIND (link) == REG_INC
+                 && REGNO (XEXP (link, 0)) == regno)
+               push_replacement (&XEXP (link, 0), reloadnum, VOIDmode);
          }
        else
          abort ();
@@ -5441,7 +5452,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
           in this insn, reload it into some other register to be safe.
           The CLOBBER is supposed to make the register unavailable
           from before this insn to after it.  */
-       if (regno_clobbered_p (regno, this_insn, GET_MODE (x)))
+       if (regno_clobbered_p (regno, this_insn, GET_MODE (x), 0))
          {
            push_reload (x, NULL_RTX, loc, NULL_PTR,
                         (context ? INDEX_REG_CLASS : BASE_REG_CLASS),
@@ -6552,18 +6563,21 @@ find_inc_amount (x, inced)
   return 0;
 }
 \f
-/* Return 1 if register REGNO is the subject of a clobber in insn INSN.  */
+/* Return 1 if register REGNO is the subject of a clobber in insn INSN.
+   If SETS is nonzero, also consider SETs.  */
 
 int
-regno_clobbered_p (regno, insn, mode)
+regno_clobbered_p (regno, insn, mode, sets)
      unsigned int regno;
      rtx insn;
      enum machine_mode mode;
+     int sets;
 {
   int nregs = HARD_REGNO_NREGS (regno, mode);
   int endregno = regno + nregs;
 
-  if (GET_CODE (PATTERN (insn)) == CLOBBER
+  if ((GET_CODE (PATTERN (insn)) == CLOBBER
+       || (sets && GET_CODE (PATTERN (insn)) == SET))
       && GET_CODE (XEXP (PATTERN (insn), 0)) == REG)
     {
       int test = REGNO (XEXP (PATTERN (insn), 0));
@@ -6578,7 +6592,9 @@ regno_clobbered_p (regno, insn, mode)
       for (; i >= 0; i--)
        {
          rtx elt = XVECEXP (PATTERN (insn), 0, i);
-         if (GET_CODE (elt) == CLOBBER && GET_CODE (XEXP (elt, 0)) == REG)
+         if ((GET_CODE (elt) == CLOBBER
+              || (sets && GET_CODE (PATTERN (insn)) == SET))
+             && GET_CODE (XEXP (elt, 0)) == REG)
            {
              int test = REGNO (XEXP (elt, 0));
              
index a2df3b1caa5d02d9f26a2a75c40d169fd0e7e1c9..7841c7ad7d1383ee201ece4351d3e3a64a06973e 100644 (file)
@@ -335,7 +335,8 @@ extern rtx find_equiv_reg PARAMS ((rtx, rtx, enum reg_class, int, short *,
                                 int, enum machine_mode));
 
 /* Return 1 if register REGNO is the subject of a clobber in insn INSN.  */
-extern int regno_clobbered_p PARAMS ((unsigned int, rtx, enum machine_mode));
+extern int regno_clobbered_p PARAMS ((unsigned int, rtx, enum machine_mode,
+                                     int));
 
 /* Return 1 if X is an operand of an insn that is being earlyclobbered.  */
 int earlyclobber_operand_p PARAMS ((rtx));
index dbe13fa6f51e05d1242d0639bd1c54ffc3161f75..fe749293dbfa1586b3a2c2ea1c1ce18a4cb67b4d 100644 (file)
@@ -5544,25 +5544,44 @@ choose_reload_regs (chain)
                 In particular, we then can't use EQUIV for a
                 RELOAD_FOR_OUTPUT_ADDRESS reload.  */
 
-             if (equiv != 0 && regno_clobbered_p (regno, insn, rld[r].mode))
-               {
-                 switch (rld[r].when_needed)
-                   {
-                   case RELOAD_FOR_OTHER_ADDRESS:
-                   case RELOAD_FOR_INPADDR_ADDRESS:
-                   case RELOAD_FOR_INPUT_ADDRESS:
-                   case RELOAD_FOR_OPADDR_ADDR:
-                     break;
-                   case RELOAD_OTHER:
-                   case RELOAD_FOR_INPUT:
-                   case RELOAD_FOR_OPERAND_ADDRESS:
-                     if (! rld[r].optional)
-                       reload_override_in[r] = equiv;
-                     /* Fall through.  */
-                   default:
-                     equiv = 0;
-                     break;
-                   }
+             if (equiv != 0)
+               {
+                 if (regno_clobbered_p (regno, insn, rld[r].mode, 0))
+                   switch (rld[r].when_needed)
+                     {
+                     case RELOAD_FOR_OTHER_ADDRESS:
+                     case RELOAD_FOR_INPADDR_ADDRESS:
+                     case RELOAD_FOR_INPUT_ADDRESS:
+                     case RELOAD_FOR_OPADDR_ADDR:
+                       break;
+                     case RELOAD_OTHER:
+                     case RELOAD_FOR_INPUT:
+                     case RELOAD_FOR_OPERAND_ADDRESS:
+                       if (! rld[r].optional)
+                         reload_override_in[r] = equiv;
+                       /* Fall through.  */
+                     default:
+                       equiv = 0;
+                       break;
+                     }
+                 else if (regno_clobbered_p (regno, insn, rld[r].mode, 1))
+                   switch (rld[r].when_needed)
+                     {
+                     case RELOAD_FOR_OTHER_ADDRESS:
+                     case RELOAD_FOR_INPADDR_ADDRESS:
+                     case RELOAD_FOR_INPUT_ADDRESS:
+                     case RELOAD_FOR_OPADDR_ADDR:
+                     case RELOAD_FOR_OPERAND_ADDRESS:
+                     case RELOAD_FOR_INPUT:
+                       break;
+                     case RELOAD_OTHER:
+                       if (! rld[r].optional)
+                         reload_override_in[r] = equiv;
+                       /* Fall through.  */
+                     default:
+                       equiv = 0;
+                       break;
+                     }
                }
 
              /* If we found an equivalent reg, say no code need be generated
@@ -6567,7 +6586,7 @@ emit_output_reload_insns (chain, rl, j)
          || !(set = single_set (insn))
          || rtx_equal_p (old, SET_DEST (set))
          || !reg_mentioned_p (old, SET_SRC (set))
-         || !regno_clobbered_p (REGNO (old), insn, rl->mode))
+         || !regno_clobbered_p (REGNO (old), insn, rl->mode, 0))
        gen_reload (old, reloadreg, rl->opnum,
                    rl->when_needed);
     }