>From: Ulrich Weigand
>
>Erwin Unruh wrote:
>
>> I have a problem with delete_output_reload. It sometimes deletes
>> instructions which are needed. Here an analysis of a recent
>case (In a
>> private version of the S390 port). The original S390 shows
>almost the
>> same reloads, but chooses different registers.
>
>What GCC version your compiler based on?
GCC 4.1.0
>> Reloads for insn # 1598
>> Reload 0: reload_in (SI) =3D (const_int 4080 [0xff0])
>> ADDR_REGS, RELOAD_FOR_OUTPUT_ADDRESS (opnum =3D 0)
>> reload_in_reg: (const_int 4080 [0xff0])
>> reload_reg_rtx: (reg:SI 2 2)
>> Reload 1: reload_in (SI) =3D (const_int 4080 [0xff0])
>> ADDR_REGS, RELOAD_FOR_OTHER_ADDRESS (opnum =3D 0)
>> reload_in_reg: (const_int 4080 [0xff0])
>> reload_reg_rtx: (reg:SI 2 2)
>> Reload 2: reload_in (SI) =3D (const_int 4080 [0xff0])
>> ADDR_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum =3D 2)
>> reload_in_reg: (const_int 4080 [0xff0])
>> reload_reg_rtx: (reg:SI 2 2)
>> Reload 3: reload_in (DI) =3D (mem/c:DI (plus:SI (plus:SI
>(reg/f:SI 15 15)
>>
>(const_int
>> 4080 [0xff0]))
>> (const_int
>> 3144
>> [0xc48])) [0 S8 A8])
>> reload_out (DI) =3D (mem/c:DI (plus:SI (plus:SI (reg/f:SI 15 15)
>>
>(const_int
>> 4080 [0xff0]))
>> (const_int
>> 3136
>> [0xc40])) [0 S8 A8])
>> GENERAL_REGS, RELOAD_OTHER (opnum =3D 0), can't combine
>> reload_in_reg: (reg:DI 1391)
>> reload_out_reg: (reg:DI 1393)
>> reload_reg_rtx: (reg:DI 0 0)
>> Reload 4: ADDR_REGS, RELOAD_FOR_INPUT_ADDRESS (opnum =3D 2), can't
>> combine, secondary_reload_p
>> reload_reg_rtx: (reg:SI 3 3)
>> Reload 5: reload_in (SI) =3D (plus:SI (plus:SI (reg/f:SI 15 15)
>> (const_int
>> 4080
>> [0xff0]))
>> (const_int 3136
>> [0xc40]))
>> ADDR_REGS, RELOAD_FOR_INPUT (opnum =3D 2), inc by 8
>> reload_in_reg: (plus:SI (plus:SI (reg/f:SI 15 15)
>> (const_int
>> 4080
>> [0xff0]))
>> (const_int 3136
>> [0xc40]))
>> reload_reg_rtx: (reg:SI 2 2)
>> secondary_in_reload =3D 4
>> secondary_in_icode =3D reload_insi
>>
>> These reloads are ok. In do_output_reload it is noted that both
>> insn_1597.Reload_2 and insn_1598.Reload_3 write to the same
>stack slot.
>> So the compiler decides to remove the first reload and use register
>> (reg:DI 2) > directly. In this analysis it misses the fact that
>> (reg:SI 2) is used for input reloads of insn 1598.
>
>This should actually be caught by the free_for_value_p check
>in choose_reload_regs. You cannot inherit a value for a
>RELOAD_OTHER reload (3) in a register that is already in use
>for a RELOAD_FOR_INPUT_ ADDRESS reload (2).
>
>Could you try to find out why this doesn't work correctly?
Sorry, I mislead you. Somehow I did confuse (mem/c:DI (reg:SI 2 2) [0 S8
A8])
with (reg:DI 2). Register 2 is used correctly.
I do not think any reload is inherited in this case.
I did find something which might be the real problem. Within
delete_output_reload
there are two calls to count_occurrences. The second one will be called
with
parameters
(parallel [
(set (mem/c:DI (plus:SI (plus:SI (reg/f:SI 15 15)
(const_int 4080 [0xff0]))
(const_int 3136 [0xc40])) [0 S8 A8])
(plus:DI (mem/c:DI (plus:SI (plus:SI (reg/f:SI 15 15)
(const_int 4080 [0xff0]))
(const_int 3144 [0xc48])) [0 S8 A8])
(mem/c:DI (plus:SI (plus:SI (reg/f:SI 15 15)
(const_int 4080 [0xff0]))
(const_int 3136 [0xc40])) [0 S8 A8])))
(clobber (reg:CC 33 %cc))
])
(mem/c:DI (plus:SI (reg/f:SI 15 15)
(const_int 7216 [0x1c30])) [0 S8 A8])
The offset from register 15 is represented in two different ways. In the
first parameter it is split in two constants, in the second it is kept
as a single constant.
Due to this difference, no occurence is found. So the second operand
of the (plus:DI ...) is not counted.
So the output reload for insn 1597 is deleted, although the memory is
read
within insn 1598.
Erwin