This is the mail archive of the gcc@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]
Other format: [Raw text]

Reload using a live register to reload into


Hi,
Working on a private port I am seeing a problem with reload clobbering
a live register and thus causing havoc.

Consider the following snippet of the code dump.
(note:HI 85 84 86 5 [bb 5] NOTE_INSN_BASIC_BLOCK)

(note:HI 86 85 89 5 NOTE_INSN_DELETED)

(insn:HI 89 86 87 5 cor_h.c:129 (set (reg:SI 3 $c3 [ ivtmp.103 ])
        (sign_extend:SI (subreg:HI (reg:SI 206 [ ivtmp.103 ]) 0))) 86
{extendhisi2} (nil))

(insn:HI 87 89 88 5 cor_h.c:129 (set (reg:SI 1 $c1 [ ivtmp.101 ])
        (reg:SI 208 [ ivtmp.101 ])) 45 {*movsi} (nil))

(insn:HI 88 87 270 5 cor_h.c:129 (set (reg:SI 2 $c2 [ h ])
        (reg/v/f:SI 236 [ h ])) 45 {*movsi} (nil))

(insn:HI 270 88 91 5 cor_h.c:129 (set (reg:SI 4 $c4)
        (const_int 0 [0x0])) 45 {*movsi} (nil))

(call_insn:HI 91 270 92 5 cor_h.c:129 (parallel [
            (set (reg:SI 1 $c1)
                (call (mem:SI (symbol_ref:SI
("DotProductWithoutShift") [flags 0x41] <function_decl 0x401f7d00
DotProductWithoutShift>) [0 S4 A32])
                    (const_int 0 [0x0])))
            (use (const_int 0 [0x0]))
            (clobber (reg:SI 31 $link))
        ]) 42 {*call_value_direct} (expr_list:REG_DEAD (reg:SI 4 $c4)
        (expr_list:REG_DEAD (reg:SI 3 $c3 [ ivtmp.103 ])
            (expr_list:REG_DEAD (reg:SI 2 $c2 [ h ])
                (nil))))
    (expr_list:REG_DEP_TRUE (use (reg:SI 4 $c4))
        (expr_list:REG_DEP_TRUE (use (reg:SI 3 $c3 [ ivtmp.103 ]))
            (expr_list:REG_DEP_TRUE (use (reg:SI 2 $c2 [ h ]))
                (expr_list:REG_DEP_TRUE (use (reg:SI 1 $c1 [ ivtmp.101 ]))
                    (nil))))))

(insn:HI 92 91 285 5 cor_h.c:129 (set (reg/v:SI 230 [ s ])
        (reg:SI 1 $c1)) 45 {*movsi} (expr_list:REG_DEAD (reg:SI 1 $c1)
        (nil)))

(jump_insn:HI 285 92 286 5 (set (pc)
        (label_ref 118)) 8 {jump} (nil))
;; End of basic block 5 -> ( 10)

The register $c1 is used to pass the first argument to the function
DotProductWithoutShift
On encountering the call_insn ( insn no 91) global.c inserts a store
to save the register $c16 (which contains a variable 'tot'  and $c16
is a caller save register ).
Hence the following insn is inserted just before the call to
DotProductWithoutShift.

(insn 309 270 91 5 cor_h.c:129 (set (mem/c:SI (plus:SI (reg/f:SI 29 $sp)
    (const_int 176 [0xb0])) [11 S4 A32])
        (reg:SI 16 $c16)) 45 {*movsi} (nil))

However the index 176 is too large and
 (plus:SI (reg/f:SI 29 $sp)
    (const_int 176 [0xb0])) needs to be reloaded.

$c1 gets chosen for this reload and now the dump snippet looks like

(note:HI 85 84 86 5 [bb 5] NOTE_INSN_BASIC_BLOCK)

(note:HI 86 85 89 5 NOTE_INSN_DELETED)

(insn:HI 89 86 87 5 cor_h.c:129 (set (reg:SI 3 $c3 [ ivtmp.103 ])
        (sign_extend:SI (reg:HI 14 $c14 [orig:206 ivtmp.103 ] [206])))
86 {extendhisi2} (nil))

(insn:HI 87 89 88 5 cor_h.c:129 (set (reg:SI 1 $c1 [ ivtmp.101 ])
        (reg:SI 8 $c8 [orig:208 ivtmp.101 ] [208])) 45 {*movsi} (nil))

(insn:HI 88 87 270 5 cor_h.c:129 (set (reg:SI 2 $c2 [ h ])
        (reg/v/f:SI 22 $c22 [orig:236 h ] [236])) 45 {*movsi} (nil))

(insn:HI 270 88 329 5 cor_h.c:129 (set (reg:SI 4 $c4)
        (const_int 0 [0x0])) 45 {*movsi} (nil))

(insn 329 270 330 5 cor_h.c:129 (set (reg:SI 1 $c1)
        (const_int 176 [0xb0])) 45 {*movsi} (nil))

(insn 330 329 309 5 cor_h.c:129 (set (reg:SI 1 $c1)
        (plus:SI (reg:SI 1 $c1)
            (reg/f:SI 29 $sp))) 65 {*addsi3} (expr_list:REG_EQUIV
(plus:SI (reg/f:SI 29 $sp)
            (const_int 176 [0xb0]))
        (nil)))

(insn 309 330 91 5 cor_h.c:129 (set (mem/c:SI (reg:SI 1 $c1) [11 S4 A32])
        (reg:SI 16 $c16)) 45 {*movsi} (nil))

(call_insn:HI 91 309 332 5 cor_h.c:129 (parallel [
            (set (reg:SI 1 $c1)
                (call (mem:SI (symbol_ref:SI
("DotProductWithoutShift") [flags 0x41] <function_decl 0x401f7d00
DotProductWithoutShift>) [0 S4 A32])
                    (const_int 0 [0x0])))
            (use (const_int 0 [0x0]))
            (clobber (reg:SI 31 $link))
        ]) 42 {*call_value_direct} (nil)
    (expr_list:REG_DEP_TRUE (use (reg:SI 4 $c4))
        (expr_list:REG_DEP_TRUE (use (reg:SI 3 $c3 [ ivtmp.103 ]))
            (expr_list:REG_DEP_TRUE (use (reg:SI 2 $c2 [ h ]))
                (expr_list:REG_DEP_TRUE (use (reg:SI 1 $c1 [ ivtmp.101 ]))
                    (nil))))))

(insn 332 91 333 5 (set (reg:SI 4 $c4)
        (const_int 176 [0xb0])) 45 {*movsi} (nil))

(insn 333 332 310 5 (set (reg:SI 4 $c4)
        (plus:SI (reg:SI 4 $c4)
            (reg/f:SI 29 $sp))) 65 {*addsi3} (expr_list:REG_EQUIV
(plus:SI (reg/f:SI 29 $sp)
            (const_int 176 [0xb0]))
        (nil)))

(insn 310 333 285 5 (set (reg:SI 16 $c16)
        (mem/c:SI (reg:SI 4 $c4) [11 S4 A32])) 45 {*movsi} (nil))

(jump_insn:HI 285 310 286 5 (set (pc)
        (label_ref 118)) 8 {jump} (nil))
;; End of basic block 5 -> ( 10)

clearly the register $c1 which after insn 87 has the first argument of
the function DotProductWithoutShift is overwritten.

The file.c.176r.greg for insn 309 says

"Spilling for insn 309.
Using reg 6 for reload 0"

and indeed rld[0].regno is 6 and rld[0].in is

(plus:SI (reg/f:SI 29 $sp)
    (const_int 176 [0xb0]))

However the function choose_reload_regs chooses $c1 for this reload
and sets rld[0].reg_rtx to the rtl expression for $c1.

Looking at struct reload in reload.h I am a little confused about the
use of regno and reg_rtx. While the comment for reg_rtx is quite
clear, for
regno it reads,
 /* Used in find_reload_regs to record the allocated register.  */
and for reg_rtx it reads,
 /* This is the register to reload into.  If it is zero when `find_reloads'
     returns, you must find a suitable register in the class specified by
     reload_reg_class, and store here an rtx for that register with mode from
     reload_inmode or reload_outmode.  */

I am confused whether reg_rtx should always be the rtl expression for
regno ?  or am I missing something here.
Anyways shouldnt reload be checking for live registers before
reloading into them ?

TIA,
Pranav


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