This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: peephole2+dead reg info after reload?
>> Hi,
>>
>> I'm trying to make some peephole2 optimizations working (gcc 4.6.1), but
>> it seems the REG_DEAD information is lost during or after reload.
>>
>> In the following peephole2 definition, peep2_reg_dead_p returns false,
>> whereas REG_DEAD information is correctly set before reload for
>> operands[0] on the second insn:
>>
>> (define_peephole2
>> [(set (match_operand:SI 0 "nonimmediate_operand" "")
>> (sign_extend:SI (match_operand:HI 1 "general_operand" "")))
>> (set (match_operand:PSI 2 "nonimmediate_operand" "")
>> (truncate:PSI (match_dup 0)))]
>> "peep2_reg_dead_p(2, operands[0])"
>> [(set (match_dup 2) (sign_extend:PSI (match_dup 1)))]
>> "")
>
> This issue doesn't seem to be related to LOCAL_REGNO like this one:
> http://gcc.gnu.org/ml/gcc/2010-10/msg00305.html
> I have no register window.
>
> In the following example, after peepholoe2 pass, the operands[0] of
> above peephole is R0 (insns 17&19), a CALL_USED_REGISTERS, which is used
> as function arg and function value, and is in CLASS_LIKELY_SPILLED_P class.
>
> (insn 17 15 19 2 (set (reg:SI 0 r0)
> (sign_extend:SI (reg:HI 0 r0))) {*extendhisi2_call}
> (expr_list:REG_EQUAL (sign_extend:SI (reg:HI 0 r0 [orig:76
> MEM[(unsigned char[4] *)k_3(D) + 4B]+2 ] [76]))
> (nil)))
>
> (insn 19 17 21 2 (set (reg/f:PSI 8 a1 [81])
> (truncate:PSI (reg:SI 0 r0 [78]))) {truncsipsi2}
> (nil))
>
> (insn 21 19 111 2 (set (reg/f:PSI 8 a1 [81])
> (plus:PSI (reg/f:PSI 8 a1 [81])
> (symbol_ref:PSI ("S") [flags 0x2] <var_decl 0x2b6c588e10a0
> S>))) {*addpsi3_1}
> (expr_list:REG_EQUAL (plus:PSI (reg:PSI 79)
> (symbol_ref:PSI ("S") [flags 0x2] <var_decl 0x2b6c588e10a0
> S>))
> (nil)))
>
> (insn 111 21 22 2 (set (reg:QI 3 r3 [82])
> (mem/s/j:QI (reg/f:PSI 8 a1 [81]) [0 S S1 A8])) {movqi}
> (nil))
>
> (insn 22 111 23 2 (set (reg:QI 3 r3 [82])
> (xor:QI (reg:QI 3 r3 [82])
> (mem/s/j:QI (reg/v/f:PSI 10 a3 [orig:74 k ] [74]) [0
> *k_3(D)+0 S1 A8]))) {xorqi3}
> (nil))
>
> (insn 23 22 24 2 (set (reg:HI 0 r0)
> (reg/v:HI 2 r2 [orig:75 rd ] [75])) {movhi_1}
> (nil))
>
> (insn 24 23 26 2 (set (reg:SI 0 r0)
> (sign_extend:SI (reg:HI 0 r0))) {*extendhisi2_call}
> (expr_list:REG_EQUAL (sign_extend:SI (reg/v:HI 2 r2 [orig:75 rd ]
> [75]))
> (nil)))
>
> (insn 26 24 28 2 (set (reg/f:PSI 8 a1 [86])
> (truncate:PSI (reg:SI 0 r0 [83]))) {truncsipsi2}
> (nil))
>
>
> And before reload, insn 17&19 look like:
>
> (insn 17 16 18 2 (set (reg:SI 0 r0)
> (sign_extend:SI (reg:HI 0 r0))) {*extendhisi2_call}
> (expr_list:REG_EQUAL (sign_extend:SI (reg:HI 25 [ D.2124 ]))
> (nil)))
>
> (insn 18 17 19 2 (set (reg:SI 53)
> (reg:SI 0 r0)) {*movsi_split}
> (expr_list:REG_EQUAL (sign_extend:SI (reg:HI 25 [ D.2124 ]))
> (nil)))
>
> (insn 19 18 20 2 (set (reg:PSI 54)
> (truncate:PSI (reg:SI 53))) {truncsipsi2}
> (expr_list:REG_DEAD (reg:SI 53)
> (nil))
>
>>
>> What do I miss?
>>
>> Thanks,
>> Aurélien
>
Ping?
I noticed that mcore port implements mcore_is_dead which parses next
insns to try to figure out if a reg is actually dead.
Does it mean gcc is not always able to find dead regs? Is there a way to
make it work?
Aurélien