OSDN Git Service

Fix reload conflict testing to take correct order of output reloads into account.
authorbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 7 Oct 2001 15:05:20 +0000 (15:05 +0000)
committerbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 7 Oct 2001 15:05:20 +0000 (15:05 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@46061 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/reload1.c

index fc92184..8ad7b71 100644 (file)
@@ -1,3 +1,11 @@
+2001-10-07  Dale Johannesen  <dalej@apple.com>
+
+       * reload1.c (reload_reg_free_p): Teach register interference
+       checking that multiple output reloads are emitted in
+       reverse order.
+       reload1.c (reload_reg_reaches_end_p):  Ditto.
+       reload1.c (reloads_conflict):  Ditto.
+
 2001-10-07  Joseph S. Myers  <jsm28@cam.ac.uk>
 
        * doc/c-tree.texi, doc/tm.texi: Consistently put NULL and
index 7828bf5..de868e6 100644 (file)
@@ -4417,11 +4417,13 @@ reload_reg_free_p (regno, opnum, type)
 
     case RELOAD_FOR_OUTPUT_ADDRESS:
       /* Can't use a register if it is used for an output address for this
-        operand or used as an output in this or a later operand.  */
+        operand or used as an output in this or a later operand.  Note
+        that multiple output operands are emitted in reverse order, so
+        the conflicting ones are those with lower indices.  */
       if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[opnum], regno))
        return 0;
 
-      for (i = opnum; i < reload_n_operands; i++)
+      for (i = 0; i <= opnum; i++)
        if (TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
          return 0;
 
@@ -4430,11 +4432,13 @@ reload_reg_free_p (regno, opnum, type)
     case RELOAD_FOR_OUTADDR_ADDRESS:
       /* Can't use a register if it is used for an output address
         for this operand or used as an output in this or a
-        later operand.  */
+        later operand.  Note that multiple output operands are
+        emitted in reverse order, so the conflicting ones are
+        those with lower indices.  */
       if (TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[opnum], regno))
        return 0;
 
-      for (i = opnum; i < reload_n_operands; i++)
+      for (i = 0; i <= opnum; i++)
        if (TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
          return 0;
 
@@ -4457,7 +4461,9 @@ reload_reg_free_p (regno, opnum, type)
 
     case RELOAD_FOR_OUTPUT:
       /* This cannot share a register with RELOAD_FOR_INSN reloads, other
-        outputs, or an operand address for this or an earlier output.  */
+        outputs, or an operand address for this or an earlier output.
+        Note that multiple output operands are emitted in reverse order,
+        so the conflicting ones are those with higher indices.  */
       if (TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno))
        return 0;
 
@@ -4465,7 +4471,7 @@ reload_reg_free_p (regno, opnum, type)
        if (TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
          return 0;
 
-      for (i = 0; i <= opnum; i++)
+      for (i = opnum; i < reload_n_operands; i++)
        if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
            || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno))
          return 0;
@@ -4601,7 +4607,7 @@ reload_reg_reaches_end_p (regno, opnum, type)
       /* These conflict with other outputs with RELOAD_OTHER.  So
         we need only check for output addresses.  */
 
-      opnum = -1;
+      opnum = reload_n_operands;
 
       /* ... fall through ...  */
 
@@ -4609,8 +4615,10 @@ reload_reg_reaches_end_p (regno, opnum, type)
     case RELOAD_FOR_OUTPUT_ADDRESS:
     case RELOAD_FOR_OUTADDR_ADDRESS:
       /* We already know these can't conflict with a later output.  So the
-        only thing to check are later output addresses.  */
-      for (i = opnum + 1; i < reload_n_operands; i++)
+        only thing to check are later output addresses.
+        Note that multiple output operands are emitted in reverse order,
+        so the conflicting ones are those with lower indices.  */
+      for (i = 0; i < opnum; i++)
        if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
            || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno))
          return 0;
@@ -4662,11 +4670,11 @@ reloads_conflict (r1, r2)
 
     case RELOAD_FOR_OUTPUT_ADDRESS:
       return ((r2_type == RELOAD_FOR_OUTPUT_ADDRESS && r2_opnum == r1_opnum)
-             || (r2_type == RELOAD_FOR_OUTPUT && r2_opnum >= r1_opnum));
+             || (r2_type == RELOAD_FOR_OUTPUT && r2_opnum <= r1_opnum));
 
     case RELOAD_FOR_OUTADDR_ADDRESS:
       return ((r2_type == RELOAD_FOR_OUTADDR_ADDRESS && r2_opnum == r1_opnum)
-             || (r2_type == RELOAD_FOR_OUTPUT && r2_opnum >= r1_opnum));
+             || (r2_type == RELOAD_FOR_OUTPUT && r2_opnum <= r1_opnum));
 
     case RELOAD_FOR_OPERAND_ADDRESS:
       return (r2_type == RELOAD_FOR_INPUT || r2_type == RELOAD_FOR_INSN
@@ -4680,7 +4688,7 @@ reloads_conflict (r1, r2)
       return (r2_type == RELOAD_FOR_INSN || r2_type == RELOAD_FOR_OUTPUT
              || ((r2_type == RELOAD_FOR_OUTPUT_ADDRESS
                   || r2_type == RELOAD_FOR_OUTADDR_ADDRESS)
-                 && r2_opnum <= r1_opnum));
+                 && r2_opnum >= r1_opnum));
 
     case RELOAD_FOR_INSN:
       return (r2_type == RELOAD_FOR_INPUT || r2_type == RELOAD_FOR_OUTPUT