Re: Preventing scheduling of normal operations across calls to built-ins

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


On 21 February 2012 22:02, Ian Lance Taylor <iant@xxxxxxxxxx> wrote:
> Ayonam Ray <ayonam@xxxxxxxxx> writes:
>
>> Here's the RTL:
>>
>> (define_insn "mvc_from_ccr"
>>   [(set (match_operand:SI 0 "register_operand" "=r")
>>         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "Y")]
>>                             UNSPEC_MVC_FROM_CCR))
>>    (set (reg:SI 0) (const_int 0))]
>>   ""
>>   "s2.mvc\t%1, %0"
>>   [(set_attr "length" "4")])
>>
>>
>> (define_insn "mvc_to_ccr"
>>   [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "=Y")
>>                         (match_operand:SI 1 "register_operand" "r")]
>>                        UNSPEC_MVC_TO_CCR)
>>    (set (reg:SI 0) (const_int 0))]
>>   ""
>>   "s2.mvc\t%1, %0\;s1.nop"
>>   [(set_attr "length" "4")])
>>
>> (define_expand "addsi3"
>>  [(parallel [(set (match_operand:SI 0 "register_operand" "")
>>                   (plus:SI (match_operand:SI 1 "nonmemory_operand" "")
>>                            (match_operand:SI 2 "nonmemory_operand" "")))
>>              (use (reg:SI 0))])]
>>   ""
>>   {
>>     if (GET_CODE(operands[1]) != REG  &&
>>         (   GET_CODE(operands[1]) != CONST_INT
>>          || ! satisfies_constraint_J(operands[1])))
>>       operands[1] = force_reg(SImode, operands[1]);
>>
>>     if (GET_CODE(operands[2]) != REG  &&
>>         (   GET_CODE(operands[2]) != CONST_INT
>>          || ! satisfies_constraint_J(operands[2])))
>>       operands[2] = force_reg(SImode, operands[2]);
>>   })
>>
>> (define_insn "*addsi3"
>>  [(set (match_operand:SI 0 "register_operand" "=r,r")
>>        (plus:SI (match_operand:SI 1 "register_or_const_int_operand" "%r,r")
>>                 (match_operand:SI 2 "register_or_const_int_operand"  "r,J")))
>>   (use (reg:SI 0))]
>>   ""
>>   "@
>>    add\t%1, %2, %0
>>    addi\t%1, %2, %0"
>>   [(set_attr "length" "4")])
>>
>>
>> (define_insn "subsi3"
>>   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
>>         (minus:SI (match_operand:SI 1 "nonmemory_operand" "r,r,J")
>>                   (match_operand:SI 2 "nonmemory_operand" "r,J,r")))
>>    (use (reg:SI 0))]
>>   ""
>>   "@
>>     sub\t%1, %2, %0
>>     subi\t%1, %2, %0
>>     sub\tr0, %2, %0\;addi\t%0, %1, %0"
>>   [(set_attr "length" "4,8,8")
>> ] )
>
> Don't (set (reg:SI 0) (const_int 0)).  The compiler is smart enough to
> know that as long as the register is set to 0, it doesn't matter which
> actual insn sets it.  Instead, do something like
>    (set (reg:SI 0) (unspec_volatile UNSPEC_CCR))
>
> If that doesn't help, show us the actual RTL from a dump file generated
> by -da.  Ideally the one before the scheduling pass which is messing
> things up.
>
> By the way, it's unusual to make register 0 a fixed register, although I
> don't know of anything wrong with it.  More typically you would use a
> pseudo-reg number past all the normal registers.
>
> Ian

Ian,

Register r0 is set to zero as per software conventions.  Hence, it is
made a fixed register.

I tried setting the register r0 to an unspec_volatile of r0 like below:

(define_insn "mvc_to_ccr"
  [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "=Y")
                        (match_operand:SI 1 "register_operand" "r")]
                       UNSPEC_MVC_TO_CCR)
   (set (reg:SI 0) (unspec_volatile [(reg:SI 0)]UNSPEC_CCR))]
  ""

This does not help.  Actually the RTL that is getting generated in the
expand stage itself has the calls to the built-ins moved around.  For
the C code below with all SImode variables:

<quote>
  __builtin_mvc_to_ccr(0x0, CCR8);      // Configuration for
wrap_aroung logic...
  val = (intVal - oneVal);
  val += oneVal1;

  __builtin_mvc_to_ccr(0xffffffff, CCR8);   // Configuration for
saturation_logic..
  val1 = __builtin_mvc_from_ccr(CCR8);
  val += val1;

  __builtin_mvc_to_ccr(0x0, CCR8);      // Configuration for
wrap_aroung logic...
  val1 = intVal;
  val += val1;
<unquote>


The RTL generated in expand at -O2 is as follows:

<quote>
;; __builtin_mvc_to_ccr (0, 8);

(insn 13 12 14 g.c:980 (asm_input/v ("") (null):0) -1 (nil))

(insn 14 13 15 g.c:980 (set (reg:SI 124)
        (const_int 0 [0x0])) -1 (nil))

(insn 15 14 16 g.c:980 (parallel [
            (unspec_volatile:SI [
                    (reg:SI 98 ccr8)
                    (reg:SI 124)
                ] 28)
            (set (reg:SI 1 r1)
                (const_int 0 [0x0]))
        ]) -1 (nil))

(insn 16 15 0 g.c:980 (asm_input/v ("") (null):0) -1 (nil))

;; __builtin_mvc_to_ccr (-1, 8);

(insn 17 16 18 g.c:986 (asm_input/v ("") (null):0) -1 (nil))

(insn 18 17 19 g.c:986 (set (reg:SI 125)
        (const_int -1 [0xffffffff])) -1 (nil))

(insn 19 18 20 g.c:986 (parallel [
            (unspec_volatile:SI [
                    (reg:SI 98 ccr8)
                    (reg:SI 125)
                ] 28)
            (set (reg:SI 1 r1)
                (const_int 0 [0x0]))
        ]) -1 (nil))

(insn 20 19 0 g.c:986 (asm_input/v ("") (null):0) -1 (nil))

;; val1_7 = __builtin_mvc_from_ccr (8);

(insn 21 20 22 g.c:987 (asm_input/v ("") (null):0) -1 (nil))

(insn 22 21 23 g.c:987 (parallel [
            (set (reg/v:SI 114 [ val1 ])
                (unspec_volatile:SI [
                        (reg:SI 98 ccr8)
                    ] 29))
            (set (reg:SI 1 r1)
                (const_int 0 [0x0]))
        ]) -1 (nil))

(insn 23 22 0 g.c:987 (asm_input/v ("") (null):0) -1 (nil))

;; __builtin_mvc_to_ccr (0, 8);

(insn 24 23 25 g.c:991 (asm_input/v ("") (null):0) -1 (nil))

(insn 25 24 26 g.c:991 (set (reg:SI 126)
        (const_int 0 [0x0])) -1 (nil))

(insn 26 25 27 g.c:991 (parallel [
            (unspec_volatile:SI [
                    (reg:SI 98 ccr8)
                    (reg:SI 126)
                ] 28)
            (set (reg:SI 1 r1)
                (const_int 0 [0x0]))
        ]) -1 (nil))

(insn 27 26 0 g.c:991 (asm_input/v ("") (null):0) -1 (nil))

;; val_4 = intVal_2(D) + intVal_2(D);

(insn 28 27 0 g.c:982 (parallel [
            (set (reg/v:SI 112 [ val ])
                (plus:SI (reg/v:SI 120 [ intVal ])
                    (reg/v:SI 120 [ intVal ])))
            (use (reg:SI 1 r1))
        ]) -1 (nil))

;; val_6 = val_4 + oneVal1_5(D);

(insn 29 28 0 g.c:983 (parallel [
            (set (reg/v:SI 113 [ val ])
                (plus:SI (reg/v:SI 112 [ val ])
                    (reg/v:SI 122 [ oneVal1 ])))
            (use (reg:SI 1 r1))
        ]) -1 (nil))

;; val_8 = val_6 - oneVal_3(D);

(insn 30 29 0 g.c:988 (set (reg/v:SI 115 [ val ])
        (minus:SI (reg/v:SI 113 [ val ])
            (reg/v:SI 121 [ oneVal ]))) -1 (nil))

;; if (val_10 != -1)

(insn 31 30 32 g.c:994 (parallel [
            (set (reg:SI 127)
                (plus:SI (reg/v:SI 115 [ val ])
                    (reg/v:SI 114 [ val1 ])))
            (use (reg:SI 1 r1))
        ]) -1 (nil))
<unquote>

Thanks and regards
Ayonam

P.S.:  Are attachments allowed on the GCC mailing lists?



[Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

Add to Google