avr-gcc-list
[Top][All Lists]
Advanced

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

Re: [avr-gcc-list] Re: Why is gcc promoting on an unsigned char?


From: J.C. Wren
Subject: Re: [avr-gcc-list] Re: Why is gcc promoting on an unsigned char?
Date: Tue, 23 Dec 2003 10:15:55 -0500
User-agent: KMail/1.5.4

        In the original code, there was some additional action that replaced 
the : 0 
portion of the ternary operator.  I had eliminated that in an effort to track 
down why it was getting promoted.

        I rewrote the ?: slightly differently, so it's treated more like 
if/else.  It 
produces the same code as the if() version.  The second version (or more 
correctly, original version) of ?: is not optimizing correctly, based on my 
interpetation of the grammar.  Considering that every thing is cast, I am 
unclear as to why it thinks it needs to promote to ints for the intermediate 
results.

        What I can't determine is exactly what portion of the ?: clause is 
responsible for the promotion.  While I'm familiar with compiler design in 
general, and have written several small grammars, GCCs complexity is a little 
hard to follow on short notice.

        I know perfectly well some of the casts in the last example are not 
necessary, but I left them in for demonstation purposes.

        --jc

        
With if ()

   for (data = 0, i = 0; i <= 128; i <<= 1)
  78: 20 e0          ldi   r18, 0x00   ; 0
  7a: 82 2f          mov   r24, r18
   {
      loop_until_bit_is_clear (CLKPIN, CLK);     // Receive first databit
  7c: c8 99          sbic  0x19, 0  ; 25
  7e: fe cf          rjmp  .-4         ; 0x7c

      if (bit_is_set (DATAPIN, DATA))
  80: c9 99          sbic  0x19, 1  ; 25
         data |= i;
  82: 28 2b          or r18, r24
      else
         data |= 0;

      loop_until_bit_is_set (CLKPIN, CLK);
  84: c8 9b          sbis  0x19, 0  ; 25
  86: fe cf          rjmp  .-4         ; 0x84
  88: 88 0f          add   r24, r24
  8a: 81 38          cpi   r24, 0x81   ; 129
  8c: b8 f3          brcs  .-18        ; 0x7c
   }

While ?: operator, version 1

   for (data = 0, i = 0; i <= 128; i <<= 1)
  78: 20 e0          ldi   r18, 0x00   ; 0
  7a: 82 2f          mov   r24, r18
   {
      loop_until_bit_is_clear (CLKPIN, CLK);     // Receive first databit
  7c: c8 99          sbic  0x19, 0  ; 25
  7e: fe cf          rjmp  .-4         ; 0x7c

      bit_is_set (DATAPIN, DATA) ? (data |= i) : (data |= 0);
  80: c9 99          sbic  0x19, 1  ; 25
  82: 28 2b          or r18, r24

      loop_until_bit_is_set (CLKPIN, CLK);
  84: c8 9b          sbis  0x19, 0  ; 25
  86: fe cf          rjmp  .-4         ; 0x84
  88: 88 0f          add   r24, r24
  8a: 81 38          cpi   r24, 0x81   ; 129
  8c: b8 f3          brcs  .-18        ; 0x7c
   }

With ?: operator, version 2.

   for (data = 0, i = 0; i <= 128; i <<= 1)
  78: 20 e0          ldi   r18, 0x00   ; 0
  7a: 42 2f          mov   r20, r18
   {
      loop_until_bit_is_clear (CLKPIN, CLK);     // Receive first databit
  7c: c8 99          sbic  0x19, 0  ; 25
  7e: fe cf          rjmp  .-4         ; 0x7c
      data |= (unsigned char) ((unsigned char) bit_is_set (DATAPIN, DATA) ? 
(unsigned char) i : (unsigned char) 0);
  80: 33 27          eor   r19, r19
  82: c9 9b          sbis  0x19, 1  ; 25
  84: 05 c0          rjmp  .+10        ; 0x90
  86: 84 2f          mov   r24, r20
  88: 99 27          eor   r25, r25
  8a: 82 2b          or r24, r18
  8c: 93 2b          or r25, r19
  8e: 02 c0          rjmp  .+4         ; 0x94
  90: 93 2f          mov   r25, r19
  92: 82 2f          mov   r24, r18
  94: 28 2f          mov   r18, r24
      loop_until_bit_is_set (CLKPIN, CLK);
  96: c8 9b          sbis  0x19, 0  ; 25
  98: fe cf          rjmp  .-4         ; 0x96
  9a: 44 0f          add   r20, r20
  9c: 41 38          cpi   r20, 0x81   ; 129
  9e: 70 f3          brcs  .-36        ; 0x7c
   }



On Tuesday 23 December 2003 07:12 am, Neil Johnson wrote:
> Hi,
>
> I thnk Joerg has hit the nail on the head, but without explaining the
> "why".  Here's my (brief) attempt.
>
> Ok, here's your code:
> >       data |= (unsigned char) (bit_is_set (DATAPIN, DATA) ? i : 0);
>
> As far as the compiler is concerned what you have expressed in the
> language is something like:
>
>       Place in var "data" the bitwise OR of the current value of
>       var "data" and with the result of a conditional expression:
>               The conditional expression evaluates the predicate
>                       "bit_is_set (DATAPIN, DATA)"
>               If this evaluates to non-zero, the result of the
>               expression is the current value of var "i", otherwise
>               it is the value zero.
>
> This is one helluva thing to say, when in practice what you, perhaps,
>
> meant to say is what Joerg wrote:
> > if (DATAPIN & DATA)
> > {
> >   data |= i;
> > }
>
> Which means something like:
>
>       If the result of the expression "DATAPIN & DATA" is non-zero then
>               bitwise OR the var "data" with var "i".
>
> This is far more concise, and will allow the optimizer to do its work
> better.
>
> Unless, of course, you would like to pay for a more expensive optimizer
> which might have more smarts to try and unravel what you wrote :-)
>
> Cheers, and a Happy Christmas and Fun New Year to All!!
> Neil
>
> --
> Neil Johnson :: Computer Laboratory :: University of Cambridge ::
> http://www.njohnson.co.uk          http://www.cl.cam.ac.uk/~nej22
> ----  IEE Cambridge Branch: http://www.iee-cambridge.org.uk  ----



reply via email to

[Prev in Thread] Current Thread [Next in Thread]