This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[RFA]: Fix pb in merge_assigned_reloads
- To: gcc-patches at gcc dot gnu dot org
- Subject: [RFA]: Fix pb in merge_assigned_reloads
- From: Stephane Carrez <Stephane dot Carrez at worldnet dot fr>
- Date: Tue, 12 Jun 2001 22:19:35 +0200
Hi!
I found a problem in merge_assigned_reloads() where it changes the type
of a reload from RELOAD_FOR_OTHER_ADDRESS to RELOAD_OTHER which is not correct.
I have this insn (HC11 port):
(insn 242 241 243 (parallel[
(set (reg:SI 0 x [90])
(minus:SI (mem/s:SI (plus:HI (reg/v/f:HI 53)
(const_int 8 [0x8])) 4)
(mem/s:SI (plus:HI (reg/v/f:HI 54)
(const_int 8 [0x8])) 4)))
(clobber (scratch:HI))
] ) 43 {*subsi3} (nil)
(expr_list:REG_EQUIV (mem/s:SI (plus:HI (reg/v/f:HI 53)
(const_int 8 [0x8])) 4)
(expr_list:REG_UNUSED (scratch:HI)
(nil))))
And for it, the following reloads are generated:
Reload 0: reload_in (HI) = (reg/f:HI 9 *_.frame)
A_REGS, RELOAD_FOR_OTHER_ADDRESS (opnum = 0)
reload_in_reg: (reg/f:HI 9 *_.frame)
Reload 1: reload_in (HI) = (mem:HI (plus:HI (reg/f:HI 9 *_.frame)
(const_int 9 [0x9])) 37)
A_REGS, RELOAD_FOR_OTHER_ADDRESS (opnum = 0), can't combine
reload_in_reg: (reg/v/f:HI 53)
Reload 2: reload_in (HI) = (reg/f:HI 9 *_.frame)
A_REGS, RELOAD_FOR_OPADDR_ADDR (opnum = 2)
reload_in_reg: (reg/f:HI 9 *_.frame)
Reload 3: reload_in (HI) = (mem/f:HI (plus:HI (reg/f:HI 9 *_.frame)
(const_int 39 [0x27])) 24)
A_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 2), can't combine
reload_in_reg: (reg/v/f:HI 54)
Reload 4: reload_in (SI) = (mem/s:SI (plus:HI (reg/v/f:HI 53)
(const_int 8 [0x8])) 4)
reload_out (SI) = (reg:SI 0 x [90])
D_OR_X_REGS, RELOAD_OTHER (opnum = 0)
reload_in_reg: (mem/s:SI (plus:HI (reg/v/f:HI 53)
(const_int 8 [0x8])) 4)
reload_out_reg: (reg:SI 0 x [90])
reload_reg_rtx: (reg:SI 0 x [90])
Reload 5: reload_in (SI) = (mem/s:SI (plus:HI (reg/v/f:HI 54)
(const_int 8 [0x8])) 4)
A_OR_D_REGS, RELOAD_FOR_INPUT (opnum = 2), optional
reload_in_reg: (mem/s:SI (plus:HI (reg/v/f:HI 54)
(const_int 8 [0x8])) 4)
The reload 2 is merged with reload 0 and during the merge
the type for reload 0 is changed from RELOAD_FOR_OTHER_ADDRESS to RELOAD_OTHER.
At the end, the reload 0 is emitted after reload 1 because the
RELOAD_FOR_OTHER_ADDRESS reloads are emitted before RELOAD_OTHER reloads
(see emit_reload_insns). But the reload 1 needs reload 0.
When we merge two reloads, we must set the type to:
- RELOAD_FOR_OTHER_ADDRESS if one of the two reloads is a RELOAD_FOR_OTHER_ADDRESS
- RELOAD_OTHER otherwise.
Can you approve this patch?
Stephane
2001-06-12 Stephane Carrez <Stephane.Carrez@worldnet.fr>
* reload1.c (merge_assigned_reloads): Set the type of the merging
reload to RELOAD_FOR_OTHER_ADDRESS if one of the two reloads is a
RELOAD_FOR_OTHER_ADDRESS, otherwise set it to RELOAD_OTHER.
Index: reload1.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/reload1.c,v
retrieving revision 1.255.4.11
diff -u -p -r1.255.4.11 reload1.c
--- reload1.c 2001/06/06 03:31:21 1.255.4.11
+++ reload1.c 2001/06/12 20:11:40
@@ -6058,7 +6058,13 @@ merge_assigned_reloads (insn)
|| rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS
|| rld[j].when_needed == RELOAD_FOR_OTHER_ADDRESS))
{
- rld[i].when_needed = RELOAD_OTHER;
+ /* Change the type of the reload to emit it at the
+ good place after the merge. */
+ if (rld[j].when_needed != RELOAD_FOR_OTHER_ADDRESS
+ && rld[i].when_needed != RELOAD_FOR_OTHER_ADDRESS)
+ rld[i].when_needed = RELOAD_OTHER;
+ else
+ rld[i].when_needed = RELOAD_FOR_OTHER_ADDRESS;
rld[j].in = 0;
reload_spill_index[j] = -1;
transfer_replacements (i, j);