This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: PATCH: reload register collision



On Tuesday, October 2, 2001, at 04:41 PM, Bernd Schmidt wrote:

> On Tue, 2 Oct 2001, Dale Johannesen wrote:
>>
>> Tue Oct  2 16:11:07 PDT 2001  Dale Johannesen <dalej@apple.com>
>>
>>          * reload1.c (emit_reload_insns): Put out reloads for multiple
>>            outputs in the order of the reload indices.
>>
>
> Not ok.  There's other code in reload that assumes reverse order, e.g.
> in push_reload.

OK, the following fixes the problem by making the register
interference checking understand that multiple output reloads are
emitted in reverse order.  Bootstrapped on Darwin.

Wed Oct  3 12:12:06 PDT 2001  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.

Index: reload1.c
===================================================================
RCS file: /cvs/Darwin/Commands/GNU/gcc/gcc/reload1.c,v
retrieving revision 1.4
diff -u -d -b -w -r1.4 reload1.c
--- reload1.c   2001/09/26 06:50:52     1.4
+++ reload1.c   2001/10/03 19:04:30
@@ -4415,11 +4415,13 @@

      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;

@@ -4428,11 +4430,13 @@
      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;

@@ -4455,7 +4459,9 @@

      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;

@@ -4463,7 +4469,7 @@
         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;
@@ -4599,7 +4605,7 @@
        /* These conflict with other outputs with RELOAD_OTHER.  So
          we need only check for output addresses.  */

-      opnum = -1;
+      opnum = reload_n_operands;

        /* ... fall through ...  */

@@ -4607,8 +4613,10 @@
      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;
@@ -4660,11 +4668,11 @@

      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
@@ -4678,7 +4686,7 @@
        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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]