"Rohit Arul Raj" <[EMAIL PROTECTED]> writes:

> The relevant part of RTL dump of fgcse pass  is given below:
> 
> (insn 13 12 50 0 (set (reg:CC 21 cc)
>         (compare:CC (reg:SI 29 [ n ])
>             (const_int 30 [0x1e]))) 68 {*cmpsi_internal} (nil)
>     (nil))
> 
> (insn 50 13 53 0 (parallel [
>             (set (reg/f:SI 38)
>                 (symbol_ref:SI ("p") <var_decl 0x402270b0 p>))
>             (clobber (reg:CC 21 cc))
>         ]) 22 {movsi_long_const} (nil)
>     (nil))
> 
> (insn 53 50 14 0 (parallel [
>             (set (reg/f:SI 39)
>                 (symbol_ref:SI ("k") <var_decl 0x40227108 k>))
>             (clobber (reg:CC 21 cc))
>         ]) 22 {movsi_long_const} (nil)
>     (nil))
> 
> (jump_insn 14 53 16 0 (set (pc)
>         (if_then_else (gtu:CC (reg:CC 21 cc)
>                 (const_int 0 [0x0]))
>             (label_ref 27)
>             (pc))) 41 {*branch_true} (nil)
>     (expr_list:REG_BR_PROB (const_int 5000 [0x1388])
>         (nil)))
> 
> 1. In Insn 13, the compiler uses the CC Reg instead of "h".  Then the
> compiler inserted to movsi_long_const inbetween the compare and the
> if_then_else.  BUT the movsi_long_const destroys the condition code
> register CC .As the optimizer considers CC dead  due to the
> clobber(reg:CC 21 cc)) it removes the first pattern actually setting
> CC. It gets deleted later.

Thanks for finally giving the complete program and the RTL.

I think you said earlier that this is a private target, not a standard
gcc target.  On that basis, I would say that the problem appears to be
that you have a cc0 machine of a type which gcc does not handle
naturally.

If your comparison instructions set a fixed hard register, and simple
register to register moves clobber that hard register, then you must
handle comparison instructions specially before reload.  You must emit
a combined compare_and_branch instruction, which does the comparison
and the branch in a single insn.  Then you may write a define_split
which runs after reload and splits the instruction back into its
components for the second scheduling pass.

You've encountered a somewhat subtle way in which gcc fails if you
don't do this.  There a much more obvious it will fail: reload will
wind up clobbering the condition register every time it has to load or
store a register.

Writing the patterns to avoid using the fixed condition register
before reload is tedious but typically not difficult.  Writing the
define_splits which run after reload is typically more complicated.
Note that in general the define_splits are only useful if scheduling
helps your processor.

The C4X is an example of a standard target which has some of these
issues.

(In fairness I should say that there is an alternative, which is to
use (cc0) for the condition register.  But I do not recommend this, as
support for (cc0) may be removed from the compiler at some point in
the future.)

Ian

Reply via email to