reload.c (find_reloads): Do not use the mode specified in the insn pattern as reload...
authorUlrich Weigand <uweigand@de.ibm.com>
Sat, 1 Feb 2003 01:01:38 +0000 (01:01 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Sat, 1 Feb 2003 01:01:38 +0000 (01:01 +0000)
gcc/
* reload.c (find_reloads): Do not use the mode specified in the insn
pattern as reload mode for address operands.  Do not generate optional
reloads for operands where a mandatory reload was already pushed.
Generate optional reloads only in the final pass though find_reloads.
(have_replacement_p): New function.

gcc/testsuite/
* gcc.dg/20030129-1.c: New test.

From-SVN: r62225

gcc/ChangeLog
gcc/reload.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/20030129-1.c [new file with mode: 0644]

index dedd614f5a80cc301776c8539e9faa36c02c42af..bd9a73d7eaa142205f28e903513b6ad0fba7447e 100644 (file)
@@ -1,3 +1,11 @@
+2003-01-31  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * reload.c (find_reloads): Do not use the mode specified in the insn
+       pattern as reload mode for address operands.  Do not generate optional
+       reloads for operands where a mandatory reload was already pushed.
+       Generate optional reloads only in the final pass though find_reloads.
+       (have_replacement_p): New function.
+
 2003-01-31  Gerald Pfeifer  <pfeifer@dbai.tuwien.ac.at>
 
        * doc/install.texi (Testing): Remove a reference to our obsolete
index 46d0d6417df02b41b73bb22c36dbaa8c3ac30b96..1a7434f643c64e286cd68b41d14ce556dcf4383a 100644 (file)
@@ -274,6 +274,7 @@ static void find_reloads_address_part PARAMS ((rtx, rtx *, enum reg_class,
 static rtx find_reloads_subreg_address PARAMS ((rtx, int, int,
                                                enum reload_type, int, rtx));
 static void copy_replacements_1 PARAMS ((rtx *, rtx *, int));
+static bool have_replacement_p PARAMS ((rtx *));
 static int find_inc_amount     PARAMS ((rtx, rtx));
 \f
 #ifdef HAVE_SECONDARY_RELOADS
@@ -2689,6 +2690,10 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
 
          recog_data.operand[i] = *recog_data.operand_loc[i];
          substed_operand[i] = recog_data.operand[i];
+
+         /* Address operands are reloaded in their existing mode,
+            no matter what is specified in the machine description.  */
+         operand_mode[i] = GET_MODE (recog_data.operand[i]);
        }
       else if (code == MEM)
        {
@@ -3302,10 +3307,6 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
                           the address into a base register.  */
                        this_alternative[i] = (int) MODE_BASE_REG_CLASS (VOIDmode);
                        badop = 0;
-
-                       /* Address constraints are reloaded in Pmode, no matter
-                          what mode is given in the machine description.  */
-                       operand_mode[i] = Pmode;
                        break;
                      }
 
@@ -3876,9 +3877,20 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
            return 0;
          }
       }
+
+    /* Generate optional reloads only when optimizing, and only
+       on the last pass through reload.  Also, make sure we do not
+       make an optional reload where we already have a mandatory
+       one; this can happen in the case of address operands.
+
+       To check for mandatory reloads, we use have_replacement_p.
+       Note that this works only on the last pass through reload.  */
+    else if (!optimize || !replace 
+            || have_replacement_p (recog_data.operand_loc[i]))
+      ; /* Do nothing.  */
+
     else if (goal_alternative_matched[i] < 0
-            && goal_alternative_matches[i] < 0
-            && optimize)
+            && goal_alternative_matches[i] < 0)
       {
        /* For each non-matching operand that's a MEM or a pseudo-register
           that didn't get a hard register, make an optional reload.
@@ -3928,11 +3940,10 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
           reload, check if this is actually a pseudo register reference;
           we then need to emit a USE and/or a CLOBBER so that reload
           inheritance will do the right thing.  */
-       else if (replace
-                && (GET_CODE (operand) == MEM
-                    || (GET_CODE (operand) == REG
-                        && REGNO (operand) >= FIRST_PSEUDO_REGISTER
-                        && reg_renumber [REGNO (operand)] < 0)))
+       else if (GET_CODE (operand) == MEM
+                || (GET_CODE (operand) == REG
+                    && REGNO (operand) >= FIRST_PSEUDO_REGISTER
+                    && reg_renumber [REGNO (operand)] < 0))
          {
            operand = *recog_data.operand_loc[i];
 
@@ -3955,8 +3966,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
             && goal_alternative_win[goal_alternative_matches[i]]
             && modified[i] == RELOAD_READ
             && modified[goal_alternative_matches[i]] == RELOAD_WRITE
-            && ! no_input_reloads && ! no_output_reloads
-            && optimize)
+            && ! no_input_reloads && ! no_output_reloads)
       {
        /* Similarly, make an optional reload for a pair of matching
           objects that are in MEM or a pseudo that didn't get a hard reg.  */
@@ -6130,6 +6140,21 @@ find_replacement (loc)
 
   return *loc;
 }
+
+/* Return true if some replacement was scheduled at LOC.  */
+
+static bool
+have_replacement_p (loc)
+     rtx *loc;
+{
+  struct replacement *r;
+
+  for (r = &replacements[0]; r < &replacements[n_replacements]; r++)
+    if (r->where == loc)
+      return true;
+
+  return false;
+}
 \f
 /* Return nonzero if register in range [REGNO, ENDREGNO)
    appears either explicitly or implicitly in X
index 87a814f50fc394bd84e90beea3a83d6e9203d87a..acf883d108d1f028af6949b9f0830b42d18f5310 100644 (file)
@@ -1,3 +1,7 @@
+2003-01-31  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * gcc.dg/20030129-1.c: New test.
+
 2003-01-31  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
 
        PR c++/8849
diff --git a/gcc/testsuite/gcc.dg/20030129-1.c b/gcc/testsuite/gcc.dg/20030129-1.c
new file mode 100644 (file)
index 0000000..0b745a9
--- /dev/null
@@ -0,0 +1,37 @@
+/* This used to ICE due to a reload bug on s390*.  */
+
+/* { dg-do compile { target s390*-*-* } } */
+/* { dg-options "-O2" } */
+
+int f (unsigned int);
+void g (void *);
+
+void test (void *p, void *dummy)
+{
+  unsigned int flags = 0;
+
+  if (dummy)
+    g (dummy);
+
+  if (p)
+    flags |= 0x80000000;
+
+  asm volatile ("" : : : "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12");
+
+  if (dummy)
+    g (dummy);
+
+  if (p) 
+    {
+      flags |= 0x20000000|0x80000000;
+
+      if (!f (0))
+        flags &= ~0x80000000;
+    }
+
+  f (flags);
+
+  if (dummy)
+    g (dummy);
+}
+