On Sat, Apr 28, 2012 at 4:55 PM, Eric Botcazou <ebotca...@adacore.com> wrote: >> I noticed that global passes before combine, like loop-invariant/cprop/cse2 >> some time have conflicts with combine. >> The combine pass can only operates with basic block, while these global >> passes move insns across basic block and left no description info. >> >> For example, a case I encountered. >> >> (insn 77 75 78 8 (set (reg:SI 171) >> (const_int 9999 [0x270f])) diffmeasure/verify.c:157 176 >> {*thumb1_movsi_insn} >> (nil)) >> >> (insn 78 77 79 8 (set (reg:SI 172) >> (const_int 0 [0])) diffmeasure/verify.c:157 176 >> {*thumb1_movsi_insn} (nil)) >> >> (insn 79 78 80 8 (set (reg:SI 170) >> (plus:SI (plus:SI (reg:SI 172) >> (reg:SI 172)) >> (geu:SI (reg:SI 171) >> (reg/v:SI 138 [ num ])))) diffmeasure/verify.c:157 226 >> {thumb1_addsi3_addgeu} >> (expr_list:REG_DEAD (reg:SI 172) >> (expr_list:REG_DEAD (reg:SI 171) >> (expr_list:REG_EQUAL (geu:SI (const_int 9999 [0x270f]) >> (reg/v:SI 138 [ num ])) >> (nil))))) >> >> (insn 80 79 81 8 (set (reg:QI 169) >> (subreg:QI (reg:SI 170) 0)) diffmeasure/verify.c:157 187 >> {*thumb1_movqi_insn} >> (expr_list:REG_DEAD (reg:SI 170) >> (nil))) >> >> (insn 81 80 82 8 (set (reg:SI 173) >> (zero_extend:SI (reg:QI 169))) diffmeasure/verify.c:157 158 >> {*thumb1_zero_extendqisi2_v6} >> (expr_list:REG_DEAD (reg:QI 169) >> (nil))) >> >> (jump_insn 82 81 124 8 (set (pc) >> (if_then_else (eq (reg:SI 173) >> (const_int 0 [0])) >> (label_ref:SI 129) >> (pc))) diffmeasure/verify.c:157 196 {cbranchsi4_insn} >> (expr_list:REG_DEAD (reg:SI 173) >> (expr_list:REG_BR_PROB (const_int 900 [0x384]) >> (nil))) >> -> 129) >> >> can be combined into : >> (insn 77 75 78 8 (set (reg:SI 171) >> (const_int 9999 [0x270f])) diffmeasure/verify.c:157 176 >> {*thumb1_movsi_insn} >> (nil)) >> >> (note 78 77 79 8 NOTE_INSN_DELETED) >> >> (note 79 78 80 8 NOTE_INSN_DELETED) >> >> (note 80 79 81 8 NOTE_INSN_DELETED) >> >> (note 81 80 82 8 NOTE_INSN_DELETED) >> >> (jump_insn 82 81 124 8 (set (pc) >> (if_then_else (ltu (reg:SI 171) >> (reg/v:SI 138 [ num ])) >> (label_ref:SI 129) >> (pc))) diffmeasure/verify.c:157 196 {cbranchsi4_insn} >> (expr_list:REG_DEAD (reg:SI 171) >> (expr_list:REG_BR_PROB (const_int 900 [0x384]) >> (nil))) >> -> 129) >> >> BUT, if pre-combine passes propagate register 172 in insn79 and delete >> insn78, the resulting instructions will not be combined. > > The example doesn't seem to illustrate to the problem though, since > propagating > reg 172 into insn 179 is a purely local change. In any case, you first need > to > understand why combine fails, then find out whether this is generic problem or > a problem more specific to the port, in which case you can try to add patterns > and/or splitters to help combine. >
Thanks for explaining. I am sorry for misleading description. By "propagate register 172 in insn79 and delete insn78" I was meaning that gcc replaces reg 172 in insn79 with another register contains ZERO and that register(saying reg X) is defined in other basic blocks. And you are right, the pattern generated here is awful. :) Thanks -- Best Regards.