>> 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