>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

Reply via email to