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]

Reload inheritance and auto inc/dec


I've been investigating a reload problem that showed up while
compiling some code for SH.  Basically, the problem is that reload
didn't take advantage of inheritance for a pseudo used in an post_inc
memory reference, and, in a subsequence insn, ended up inheriting the
value of an out-dated register.

A longer description of the problem follows.  After lreg, we had:

(insn 939 197 199 (set (reg:SI 130)
        (reg:SI 14 r14)) 85 {movsi_i} (nil)
    (nil))

(insn 199 939 200 (set (reg:QI 120)
        (mem/s:QI (post_inc:SI (reg:SI 130)) 0)) 89 {movqi_i} (insn_list 939 (nil))
    (expr_list:REG_INC (reg:SI 130)
        (nil)))

[snip]

(insn 220 218 221 (set (reg:QI 131)
        (mem/s:QI (reg:SI 130) 0)) 89 {movqi_i} (insn_list 218 (nil))
    (expr_list:REG_EQUIV (mem/s:QI (reg:SI 130) 0)
        (nil)))

The relevant reloads are:

Reloads for insn # 941
Reload 0: reload_out (SI) = (mem:SI (plus:SI (reg:SI 15 r15)
                                                        (const_int 32 [0x20])) 0)
	NO_REGS, RELOAD_FOR_OUTPUT (opnum = 0), optional
	reload_out_reg: (reg:SI 130)
Reload 1: reload_in (SI) = (plus:SI (reg:SI 15 r15)
                                                    (const_int 4 [0x4]))
	GENERAL_REGS, RELOAD_FOR_INPUT (opnum = 1)
	reload_in_reg: (plus:SI (reg:SI 15 r15)
                                                    (const_int 4 [0x4]))
	reload_reg_rtx: (reg:SI 2 r2)

Reloads for insn # 199
Reload 0: reload_in (SI) = (mem:SI (plus:SI (reg:SI 15 r15)
                                                        (const_int 32 [0x20])) 0)
	reload_out (SI) = (mem:SI (plus:SI (reg:SI 15 r15)
                                                        (const_int 32 [0x20])) 0)
	GENERAL_REGS, RELOAD_OTHER (opnum = 1)
	reload_in_reg: (mem:SI (plus:SI (reg:SI 15 r15)
                                                        (const_int 32 [0x20])) 0)
	reload_out_reg: (mem:SI (plus:SI (reg:SI 15 r15)
                                                        (const_int 32 [0x20])) 0)
	reload_reg_rtx: (reg:SI 0 r0)

Reloads for insn # 220
Reload 0: reload_in (SI) = (mem:SI (plus:SI (reg:SI 15 r15)
                                                        (const_int 32 [0x20])) 0)
	GENERAL_REGS, RELOAD_FOR_OPERAND_ADDRESS (opnum = 1), can't combine
	reload_in_reg: (reg:SI 130)
	reload_reg_rtx: (reg:SI 2 r2)

You see, it used register r0 for the post-increment and, even though
it ends up copying r0 from r2, it doesn't copy it back, and insn 220
ends up using r2, because the scan for an equivalent register ignores
reload-generated insns, but insn 941 is considered, since it's
modified by reload.  The end result is:

(insn 1127 197 1128 (set (reg:SI 2 r2)
        (const_int 4 [0x4])) 85 {movsi_i} (nil)
    (nil))

(insn 1128 1127 941 (set (reg:SI 2 r2)
        (plus:SI (reg:SI 2 r2)
            (reg:SI 15 r15))) 18 {addsi3} (nil)
    (expr_list:REG_EQUIV (plus:SI (reg:SI 15 r15)
            (const_int 4 [0x4]))
        (nil)))

(insn 941 1128 1131 (set (mem:SI (plus:SI (reg:SI 15 r15)
                (const_int 32 [0x20])) 0)
        (reg:SI 2 r2)) 85 {movsi_i} (nil)
    (nil))

(insn 1131 941 199 (set (reg:SI 0 r0)
        (reg:SI 2 r2)) 85 {movsi_i} (nil)
    (nil))

(insn 199 1131 1134 (set (reg:QI 7 r7)
        (mem/s:QI (post_inc:SI (reg:SI 0 r0)) 0)) 89 {movqi_i} (insn_list 941 (nil))
    (expr_list:REG_INC (reg:SI 0 r0)
        (nil)))

(insn 1134 199 200 (set (mem:SI (plus:SI (reg:SI 15 r15)
                (const_int 32 [0x20])) 0)
        (reg:SI 0 r0)) 85 {movsi_i} (nil)
    (nil))

[snip]

(insn 220 218 221 (set (reg:QI 1 r1)
        (mem/s:QI (reg:SI 2 r2) 0)) 89 {movqi_i} (insn_list 218 (nil))
    (expr_list:REG_EQUIV (mem/s:QI (reg:SI 2 r2) 0)
        (nil)))

The problem seemed to be that choose_reload_regs would never set
search_equiv in case both rld.in and .out were set, which is the case
for an auto-inc memory reference.  The following patch fixes the
problem, arranging for the register to be inherited for the reload for
insn 199.  Is it ok to install?

I'm wondering whether there is some way to eliminate insn 941, since
the same memory address is being overwritten in insn 1134, and it
doesn't seem to me that the value read in insn 199 might be reading
from it.

Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* reload1.c (choose_reload_regs): Search for equivalences if `in'
	and `out' are the same rtx.

Index: gcc/reload1.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/reload1.c,v
retrieving revision 1.227
diff -u -p -r1.227 reload1.c
--- gcc/reload1.c 2000/09/08 09:41:07 1.227
+++ gcc/reload1.c 2000/09/12 11:33:13
@@ -5439,7 +5439,9 @@ choose_reload_regs (chain)
 	  if (inheritance
 	      && rld[r].in != 0
 	      && ! reload_inherited[r]
-	      && rld[r].out == 0
+	      && (rld[r].out == 0
+		  /* This is used for auto inc/dec.  */
+		  || rld[r].out == rld[r].in)
 	      && (CONSTANT_P (rld[r].in)
 		  || GET_CODE (rld[r].in) == PLUS
 		  || GET_CODE (rld[r].in) == REG

-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                  aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist    *Please* write to mailing lists, not to me

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