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]

[RFA]: Fix pb in merge_assigned_reloads


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);

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