]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Backport a bunch of reload fixes
authorBernd Schmidt <bernds@redhat.co.uk>
Mon, 18 Dec 2000 14:29:56 +0000 (14:29 +0000)
committerBernd Schmidt <bernds@gcc.gnu.org>
Mon, 18 Dec 2000 14:29:56 +0000 (14:29 +0000)
From-SVN: r38348

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

index 53de662c547b246eba505e52a4c9b31a5a1efa4a..8bc4f9f9c90fa355d4e5b71db4c5784302a80e65 100644 (file)
@@ -1,3 +1,25 @@
+2000-12-18  Bernd Schmidt  <bernds@redhat.co.uk>
+
+       2000-12-02  Bernd Schmidt  <bernds@redhat.co.uk>
+       * reload1.c (free_for_value_p): New function, frontend to
+       reload_reg_free_for_value_p.  All callers of the latter now call
+       this function with an additional mode argument.
+
+       2000-11-10  Bernd Schmidt  <bernds@redhat.co.uk>
+       (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-10-28  Bernd Schmidt  <bernds@redhat.co.uk>
+       * reload1.c (choose_reload_regs): Never set reload_override_in for an
+       optional reload.
+
+       2000-09-07  Bernd Schmidt  <bernds@redhat.co.uk>
+       * reload.c (regno_clobbered_p): Accept new arg, MODE, and use it
+       to handle multiword modes correctly.  All callers and the declaration
+       changed.
+
 2000-12-18  David Edelsohn  <edelsohn@gnu.org>
 
        * rs6000.c (and64_operand): Use logical_u_operand.
index 72b38f3251659ee4363143cd20cb89b53460d28d..7aa297150e80039bde1009b011a7bcf15a0510ce 100644 (file)
@@ -4682,7 +4682,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))
+              && ! regno_clobbered_p (regno, this_insn, GET_MODE (ad), 0))
        return 0;
 
       /* If we do not have one of the cases above, we must do the reload.  */
@@ -5514,7 +5514,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))
+       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),
@@ -6627,13 +6627,23 @@ find_inc_amount (x, inced)
 /* Return 1 if register REGNO is the subject of a clobber in insn INSN.  */
 
 int
-regno_clobbered_p (regno, insn)
+regno_clobbered_p (regno, insn, mode, sets)
      int regno;
      rtx insn;
+     enum machine_mode mode;
+     int sets;
 {
-  if (GET_CODE (PATTERN (insn)) == CLOBBER
+  int nregs = HARD_REGNO_NREGS (regno, mode);
+  int endregno = regno + nregs;
+
+  if ((GET_CODE (PATTERN (insn)) == CLOBBER
+       || (sets && GET_CODE (PATTERN (insn)) == SET))
       && GET_CODE (XEXP (PATTERN (insn), 0)) == REG)
-    return REGNO (XEXP (PATTERN (insn), 0)) == regno;
+    {
+      int test = REGNO (XEXP (PATTERN (insn), 0));
+
+      return test >= regno && test < endregno;
+    }
 
   if (GET_CODE (PATTERN (insn)) == PARALLEL)
     {
@@ -6642,9 +6652,15 @@ regno_clobbered_p (regno, insn)
       for (; i >= 0; i--)
        {
          rtx elt = XVECEXP (PATTERN (insn), 0, i);
-         if (GET_CODE (elt) == CLOBBER && GET_CODE (XEXP (elt, 0)) == REG
-             && REGNO (XEXP (elt, 0)) == regno)
-           return 1;
+         if ((GET_CODE (elt) == CLOBBER
+              || (sets && GET_CODE (PATTERN (insn)) == SET))
+             && GET_CODE (XEXP (elt, 0)) == REG)
+           {
+             int test = REGNO (XEXP (elt, 0));
+             
+             if (test >= regno && test < endregno)
+               return 1;
+           }
        }
     }
 
index 50526db8566fc58efca62a2eb58960d397ecd127..7bc6ccab89aef6c5b53bc34d3fc2402982765841 100644 (file)
@@ -296,7 +296,7 @@ extern rtx find_equiv_reg PROTO((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 PROTO((int, rtx));
+extern int regno_clobbered_p PROTO((int, rtx, enum machine_mode, int));
 
 /* Functions in reload1.c:  */
 
index 4011236f47b228e61426413b0cafc898f648303b..13e24ee67cfed2b5dd782882fcb1ad68eb0ba8b0 100644 (file)
@@ -420,6 +420,9 @@ static void clear_reload_reg_in_use PROTO((int, int, enum reload_type,
                                               enum machine_mode));
 static int reload_reg_free_p           PROTO((int, int, enum reload_type));
 static int reload_reg_free_for_value_p PROTO((int, int, enum reload_type, rtx, rtx, int, int));
+static int free_for_value_p            PROTO((int, enum machine_mode, int,
+                                              enum reload_type, rtx, rtx,
+                                              int, int));
 static int reload_reg_reaches_end_p    PROTO((int, int, enum reload_type));
 static int allocate_reload_reg         PROTO((struct insn_chain *, int, int,
                                               int));
@@ -5177,25 +5180,8 @@ rtx reload_override_in[MAX_RELOADS];
    or -1 if we did not need a register for this reload.  */
 int reload_spill_index[MAX_RELOADS];
 
-/* Return 1 if the value in reload reg REGNO, as used by a reload
-   needed for the part of the insn specified by OPNUM and TYPE,
-   may be used to load VALUE into it.
-
-   Other read-only reloads with the same value do not conflict
-   unless OUT is non-zero and these other reloads have to live while
-   output reloads live.
-   If OUT is CONST0_RTX, this is a special case: it means that the
-   test should not be for using register REGNO as reload register, but
-   for copying from register REGNO into the reload register.
+/* Subroutine of free_for_value_p, used to check a single register.  */
 
-   RELOADNUM is the number of the reload we want to load this value for;
-   a reload does not conflict with itself.
-
-   When IGNORE_ADDRESS_RELOADS is set, we can not have conflicts with
-   reloads that load an address for the very reload we are considering.
-
-   The caller has to make sure that there is no conflict with the return
-   register.  */
 static int
 reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
                              ignore_address_reloads)
@@ -5413,6 +5399,48 @@ reload_reg_free_for_value_p (regno, opnum, type, value, out, reloadnum,
   return 1;
 }
 
+/* Return 1 if the value in reload reg REGNO, as used by a reload
+   needed for the part of the insn specified by OPNUM and TYPE,
+   may be used to load VALUE into it.
+
+   MODE is the mode in which the register is used, this is needed to
+   determine how many hard regs to test.
+
+   Other read-only reloads with the same value do not conflict
+   unless OUT is non-zero and these other reloads have to live while
+   output reloads live.
+   If OUT is CONST0_RTX, this is a special case: it means that the
+   test should not be for using register REGNO as reload register, but
+   for copying from register REGNO into the reload register.
+
+   RELOADNUM is the number of the reload we want to load this value for;
+   a reload does not conflict with itself.
+
+   When IGNORE_ADDRESS_RELOADS is set, we can not have conflicts with
+   reloads that load an address for the very reload we are considering.
+
+   The caller has to make sure that there is no conflict with the return
+   register.  */
+
+static int
+free_for_value_p (regno, mode, opnum, type, value, out, reloadnum,
+                 ignore_address_reloads)
+     int regno;
+     enum machine_mode mode;
+     int opnum;
+     enum reload_type type;
+     rtx value, out;
+     int reloadnum;
+     int ignore_address_reloads;
+{
+  int nregs = HARD_REGNO_NREGS (regno, mode);
+  while (nregs-- > 0)
+    if (! reload_reg_free_for_value_p (regno, opnum, type, value, out,
+                                      reloadnum, ignore_address_reloads))
+      return 0;
+  return 1;
+}
+
 /* Determine whether the reload reg X overlaps any rtx'es used for
    overriding inheritance.  Return nonzero if so.  */
 
@@ -5508,11 +5536,10 @@ allocate_reload_reg (chain, r, last_reload, noerror)
                      /* We check reload_reg_used to make sure we
                         don't clobber the return register.  */
                   && ! TEST_HARD_REG_BIT (reload_reg_used, regnum)
-                  && reload_reg_free_for_value_p (regnum,
-                                                 reload_opnum[r],
-                                                 reload_when_needed[r],
-                                                 reload_in[r],
-                                                 reload_out[r], r, 1)))
+                  && free_for_value_p (regnum, reload_mode[r],
+                                       reload_opnum[r],
+                                       reload_when_needed[r],
+                                       reload_in[r], reload_out[r], r, 1)))
              && TEST_HARD_REG_BIT (reg_class_contents[class], regnum)
              && HARD_REGNO_MODE_OK (regnum, reload_mode[r])
              /* Look first for regs to share, then for unshared.  But
@@ -5967,10 +5994,9 @@ choose_reload_regs (chain)
                      && (reload_nregs[r] == max_group_size
                          || ! TEST_HARD_REG_BIT (reg_class_contents[(int) group_class],
                                                  i))
-                     && reload_reg_free_for_value_p (i, reload_opnum[r],
-                                                     reload_when_needed[r],
-                                                     reload_in[r],
-                                                     const0_rtx, r, 1))
+                     && free_for_value_p (i, reload_mode[r], reload_opnum[r],
+                                          reload_when_needed[r], reload_in[r],
+                                          const0_rtx, r, 1))
                    {
                      /* If a group is needed, verify that all the subsequent
                         registers still have their values intact.  */
@@ -6004,9 +6030,11 @@ choose_reload_regs (chain)
                              break;
 
                          if (i1 != n_earlyclobbers
-                             || ! (reload_reg_free_for_value_p
-                                   (i, reload_opnum[r], reload_when_needed[r],
-                                    reload_in[r], reload_out[r], r, 1))
+                             || ! (free_for_value_p (i, reload_mode[r],
+                                                     reload_opnum[r],
+                                                     reload_when_needed[r],
+                                                     reload_in[r],
+                                                     reload_out[r], r, 1))
                              /* Don't use it if we'd clobber a pseudo reg.  */
                              || (TEST_HARD_REG_BIT (reg_used_in_insn, i)
                                  && reload_out[r]
@@ -6028,9 +6056,12 @@ choose_reload_regs (chain)
                                  && rtx_equal_p (reload_out[r],
                                                  reload_reg_rtx[r])))
                            {
-                             reload_override_in[r] = last_reg;
-                             reload_inheritance_insn[r]
-                               = reg_reloaded_insn[i];
+                             if (! reload_optional[r])
+                               {
+                                 reload_override_in[r] = last_reg;
+                                 reload_inheritance_insn[r]
+                                   = reg_reloaded_insn[i];
+                               }
                            }
                          else
                            {
@@ -6108,10 +6139,11 @@ choose_reload_regs (chain)
                 and of the desired class.  */
              if (equiv != 0
                  && ((TEST_HARD_REG_BIT (reload_reg_used_at_all, regno)
-                      && ! reload_reg_free_for_value_p (regno, reload_opnum[r],
-                                                        reload_when_needed[r],
-                                                        reload_in[r],
-                                                        reload_out[r], r, 1))
+                      && ! free_for_value_p (regno, reload_mode[r],
+                                             reload_opnum[r],
+                                             reload_when_needed[r],
+                                             reload_in[r], reload_out[r], r,
+                                             1))
                      || ! TEST_HARD_REG_BIT (reg_class_contents[(int) reload_reg_class[r]],
                                              regno)))
                equiv = 0;
@@ -6129,7 +6161,8 @@ choose_reload_regs (chain)
                  if (reg_overlap_mentioned_for_reload_p (equiv,
                                                          reload_earlyclobbers[i]))
                    {
-                     reload_override_in[r] = equiv;
+                     if (! reload_optional[r])
+                       reload_override_in[r] = equiv;
                      equiv = 0;
                      break;
                    }
@@ -6140,7 +6173,8 @@ 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))
+             if (equiv != 0 && regno_clobbered_p (regno, insn,
+                                                  reload_mode[r], 0))
                {
                  switch (reload_when_needed[r])
                    {
@@ -6152,13 +6186,32 @@ choose_reload_regs (chain)
                    case RELOAD_OTHER:
                    case RELOAD_FOR_INPUT:
                    case RELOAD_FOR_OPERAND_ADDRESS:
-                     reload_override_in[r] = equiv;
+                     if (! reload_optional[r])
+                       reload_override_in[r] = equiv;
                      /* Fall through. */
                    default:
                      equiv = 0;
                      break;
                    }
                }
+             else if (regno_clobbered_p (regno, insn, reload_mode[r], 1))
+               switch (reload_when_needed[r])
+                 {
+                 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 (! reload_optional[r])
+                     reload_override_in[r] = equiv;
+                   /* Fall through.  */
+                 default:
+                   equiv = 0;
+                   break;
+                 }
 
              /* If we found an equivalent reg, say no code need be generated
                 to load it, and use it as our reload reg.  */
@@ -6319,13 +6372,12 @@ choose_reload_regs (chain)
            check_reg = reload_override_in[r];
          else
            continue;
-         if (! reload_reg_free_for_value_p (true_regnum (check_reg),
-                                            reload_opnum[r],
-                                            reload_when_needed[r],
-                                            reload_in[r],
-                                            (reload_inherited[r]
-                                             ? reload_out[r] : const0_rtx),
-                                            r, 1))
+         if (! free_for_value_p (true_regnum (check_reg), reload_mode[r],
+                                 reload_opnum[r], reload_when_needed[r],
+                                 reload_in[r],
+                                 (reload_inherited[r]
+                                  ? reload_out[r] : const0_rtx),
+                                 r, 1))
            {
              if (pass)
                continue;
@@ -6682,10 +6734,10 @@ emit_reload_insns (chain)
 
              /* Don't use OLDEQUIV if any other reload changes it at an
                 earlier stage of this insn or at this stage.  */
-             if (! reload_reg_free_for_value_p (regno, reload_opnum[j],
-                                                reload_when_needed[j],
-                                                reload_in[j], const0_rtx, j,
-                                                0))
+             if (! free_for_value_p (regno, reload_mode[j],
+                                     reload_opnum[j],
+                                     reload_when_needed[j],
+                                     reload_in[j], const0_rtx, j, 0))
                oldequiv = 0;
 
              /* If it is no cheaper to copy from OLDEQUIV into the
@@ -6836,11 +6888,9 @@ emit_reload_insns (chain)
                   /* This is unsafe if some other reload
                      uses the same reg first.  */
                   && ! conflicts_with_override (reloadreg)
-                  && reload_reg_free_for_value_p (REGNO (reloadreg),
-                                                  reload_opnum[j],
-                                                  reload_when_needed[j], 
-                                                  old, reload_out[j],
-                                                  j, 0))
+                  && free_for_value_p (REGNO (reloadreg), reload_mode[j],
+                                       reload_opnum[j], reload_when_needed[j],
+                                       old, reload_out[j], j, 0))
            {
              rtx temp = PREV_INSN (insn);
              while (temp && GET_CODE (temp) == NOTE)
@@ -7326,7 +7376,7 @@ emit_reload_insns (chain)
                  || !(set = single_set (insn))
                  || rtx_equal_p (old, SET_DEST (set))
                  || !reg_mentioned_p (old, SET_SRC (set))
-                 || !regno_clobbered_p (REGNO (old), insn))
+                 || !regno_clobbered_p (REGNO (old), insn, reload_mode[j], 0))
                gen_reload (old, reloadreg, reload_opnum[j],
                            reload_when_needed[j]);
            }