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

-- 
Eric Botcazou

Reply via email to