This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH: reload register collision
- To: Bernd Schmidt <bernds at redhat dot com>
- Subject: Re: PATCH: reload register collision
- From: Dale Johannesen <dalej at apple dot com>
- Date: Wed, 3 Oct 2001 14:00:49 -0700
- Cc: Dale Johannesen <dalej at apple dot com>, gcc-patches at gcc dot gnu dot org
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