OSDN Git Service

* reload.c (find_reloads): Add code to convert RELOAD_FOR_OPADDR_ADDR
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 19 Aug 1997 16:04:22 +0000 (16:04 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 19 Aug 1997 16:04:22 +0000 (16:04 +0000)
        reloads to RELOAD_FOR_OPERAND_ADDRESS reloads.
        * reload1.c: Undo bugfix from Aug 11.
Back out "simple" patch for PA reload bug and install the one accepted
by the FSF.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@14847 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 1b1beac..aef412e 100644 (file)
@@ -1,3 +1,9 @@
+Mon Aug 18 21:49:02 1997  Jim Wilson  <wilson@cygnus.com>
+
+       * reload.c (find_reloads): Add code to convert RELOAD_FOR_OPADDR_ADDR
+       reloads to RELOAD_FOR_OPERAND_ADDRESS reloads.
+       * reload1.c: Undo bugfix from Aug 11.
+
 Tue Aug 19 09:34:57 1997  Jeffrey A Law  (law@cygnus.com)
 
        * Makefile.in (EXPECT, RUNTEST, RUNTESTFLAGS): Define.
index a8bd5de..efd4aca 100644 (file)
@@ -3871,6 +3871,35 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
        reload_opnum[i] = goal_alternative_matches[reload_opnum[i]];
     }
 
+  /* Scan all the reloads, and check for RELOAD_FOR_OPERAND_ADDRESS reloads.
+     If we have more than one, then convert all RELOAD_FOR_OPADDR_ADDR
+     reloads to RELOAD_FOR_OPERAND_ADDRESS reloads.
+
+     choose_reload_regs assumes that RELOAD_FOR_OPADDR_ADDR reloads never
+     conflict with RELOAD_FOR_OPERAND_ADDRESS reloads.  This is true for a
+     single pair of RELOAD_FOR_OPADDR_ADDR/RELOAD_FOR_OPERAND_ADDRESS reloads.
+     However, if there is more than one RELOAD_FOR_OPERAND_ADDRESS reload,
+     then a RELOAD_FOR_OPADDR_ADDR reload conflicts with all
+     RELOAD_FOR_OPERAND_ADDRESS reloads other than the one that uses it.
+     This is complicated by the fact that a single operand can have more
+     than one RELOAD_FOR_OPERAND_ADDRESS reload.  It is very difficult to fix
+     choose_reload_regs without affecting code quality, and cases that
+     actually fail are extremely rare, so it turns out to be better to fix
+     the problem here by not generating cases that choose_reload_regs will
+     fail for.  */
+   
+  {
+    int op_addr_reloads = 0;
+    for (i = 0; i < n_reloads; i++)
+      if (reload_when_needed[i] == RELOAD_FOR_OPERAND_ADDRESS)
+       op_addr_reloads++;
+
+    if (op_addr_reloads > 1)
+      for (i = 0; i < n_reloads; i++)
+       if (reload_when_needed[i] == RELOAD_FOR_OPADDR_ADDR)
+         reload_when_needed[i] = RELOAD_FOR_OPERAND_ADDRESS;
+  }
+
   /* See if we have any reloads that are now allowed to be merged
      because we've changed when the reload is needed to
      RELOAD_FOR_OPERAND_ADDRESS or RELOAD_FOR_OTHER_ADDRESS.  Only
index 8067787..a3361ab 100644 (file)
@@ -1341,8 +1341,8 @@ reload (first, global, dumpfile)
                         don't conflict with things needed to reload inputs or
                         outputs.  */
 
-                     in_max = MAX ((insn_needs.op_addr.regs[j][i]
-                                    + insn_needs.op_addr_reload.regs[j][i]),
+                     in_max = MAX (MAX (insn_needs.op_addr.regs[j][i],
+                                        insn_needs.op_addr_reload.regs[j][i]),
                                    in_max);
 
                      out_max = MAX (out_max, insn_needs.insn.regs[j][i]);
@@ -1374,8 +1374,8 @@ reload (first, global, dumpfile)
                        = MAX (out_max, insn_needs.out_addr_addr[j].groups[i]);
                    }
 
-                 in_max = MAX ((insn_needs.op_addr.groups[i]
-                                + insn_needs.op_addr_reload.groups[i]),
+                 in_max = MAX (MAX (insn_needs.op_addr.groups[i],
+                                    insn_needs.op_addr_reload.groups[i]),
                                in_max);
                  out_max = MAX (out_max, insn_needs.insn.groups[i]);
 
@@ -4605,13 +4605,7 @@ reload_reg_free_p (regno, opnum, type)
        if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
          return 0;
 
-      /* ??? A OPADDR_ADDR reload does not conflict with the OPERAND_ADDRESS
-        reload that uses it.  However, the same operand can have multiple
-        OPERAND_ADDRESS reloads, and a OPADDR_ADDR reload does conflict with
-        other OPERAND_ADDRESS reloads for the same operand, hence we must
-        say that OPADDR_ADDR and OPERAND_ADDRESS reloads always conflict.  */
       return (! TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)
-             && ! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno)
              && ! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno));
 
     case RELOAD_FOR_OPADDR_ADDR:
@@ -4619,8 +4613,7 @@ reload_reg_free_p (regno, opnum, type)
         if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
           return 0;
 
-      return (! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno)
-             && ! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno));
+      return (!TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno));
 
     case RELOAD_FOR_OUTPUT:
       /* This cannot share a register with RELOAD_FOR_INSN reloads, other
@@ -4737,6 +4730,12 @@ reload_reg_free_before_p (regno, opnum, type)
       return ! TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno);
 
     case RELOAD_FOR_OPERAND_ADDRESS:
+      /* Earlier reloads include RELOAD_FOR_OPADDR_ADDR reloads.  */
+      if (TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno))
+       return 0;
+
+      /* ... fall through ...  */
+
     case RELOAD_FOR_OPADDR_ADDR:
     case RELOAD_FOR_INSN:
       /* These can't conflict with inputs, or each other, so all we have to
@@ -4880,7 +4879,8 @@ reload_reg_reaches_end_p (regno, opnum, type)
            || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
          return 0;
 
-      return (! TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno));
+      return (! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)
+             && !TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno));
 
     case RELOAD_FOR_INSN:
       /* These conflict with other outputs with RELOAD_OTHER.  So
@@ -4955,13 +4955,11 @@ reloads_conflict (r1, r2)
 
     case RELOAD_FOR_OPERAND_ADDRESS:
       return (r2_type == RELOAD_FOR_INPUT || r2_type == RELOAD_FOR_INSN
-             || r2_type == RELOAD_FOR_OPERAND_ADDRESS
-             || r2_type == RELOAD_FOR_OPADDR_ADDR);
+             || r2_type == RELOAD_FOR_OPERAND_ADDRESS);
 
     case RELOAD_FOR_OPADDR_ADDR:
       return (r2_type == RELOAD_FOR_INPUT 
-             || r2_type == RELOAD_FOR_OPADDR_ADDR
-             || r2_type == RELOAD_FOR_OPERAND_ADDRESS);
+             || r2_type == RELOAD_FOR_OPADDR_ADDR);
 
     case RELOAD_FOR_OUTPUT:
       return (r2_type == RELOAD_FOR_INSN || r2_type == RELOAD_FOR_OUTPUT