On Monday 26 October 2009 07:20:23 Mike Frysinger wrote:
> On Sunday 25 October 2009 15:19:49 Rob Landley wrote:
> > -   int readlinks = 0;
> > +   int readlinks = 0, allocated = 0;
> > ...
> > +   if (!got_path) {
> > +           got_path = alloca(PATH_MAX);
> > +           allocated++;
> > +   }
> > ...
> > +   if (allocated) got_path = strdup(got_path);
>
> it doesnt make any sense to treat "allocated" as an integer that gets
> incremented.  you're pointlessly forcing gcc to generate load/update/store
> instructions when it only needs a store instruction.  i.e. use stdbool like
> evolution intended.

I did that because instruction sets that have an increment instruction can 
produce smaller code by avoiding the 32 bit constant, and on something like 
arm using a variable smaller than integer size can produce significantly 
_larger_ code due to the masking and shifting the compiler generates to fake 
the smaller sizes it hasn't got instructions for.  Also, in my experience 
_Bool is about as real-world useful as the bit field notation with the colons, 
and is really there to keep the language pedants and the c++ guys happy 
without actually accomplishing much.  I've never seen it actually produce 
better code.

But by all means let's test it:

gcc -v 2>&1 | tail -n 1
gcc version 4.3.3 (Ubuntu 4.3.3-5ubuntu4)

cat > hello.c << EOF
#include <stdio.h>

int main(int argc, char *argv[])
{
  int allocated=0;

  if (argc==2) allocated++;

  printf("allocated=%d\n", allocated);
}
EOF

gcc -Os -s hello.c
objdump -d a.out

000000000040052c <main>:
  40052c:       31 d2                   xor    %edx,%edx
  40052e:       83 ff 02                cmp    $0x2,%edi
  400531:       be 3c 06 40 00          mov    $0x40063c,%esi
  400536:       0f 94 c2                sete   %dl
  400539:       bf 01 00 00 00          mov    $0x1,%edi
  40053e:       31 c0                   xor    %eax,%eax
  400540:       e9 db fe ff ff          jmpq   400420 <__printf_...@plt>

And the optimizer's constant propogation expanded it to use the constant 
assignment anyway.  But just to be sure let's switch to allocated=1 and...

000000000040052c <main>:
  40052c:       31 d2                   xor    %edx,%edx
  40052e:       83 ff 02                cmp    $0x2,%edi
  400531:       be 3c 06 40 00          mov    $0x40063c,%esi
  400536:       0f 94 c2                sete   %dl
  400539:       bf 01 00 00 00          mov    $0x1,%edi
  40053e:       31 c0                   xor    %eax,%eax
  400540:       e9 db fe ff ff          jmpq   400420 <__printf_...@plt>

Yup, the optimizer is actually coercing the two into producing identical code 
on x86-64, which isn't particularly surprising. 

Let's change the variable type to _Bool and...

000000000040052c <main>:
  40052c:       31 d2                   xor    %edx,%edx
  40052e:       83 ff 02                cmp    $0x2,%edi
  400531:       be 3c 06 40 00          mov    $0x40063c,%esi
  400536:       0f 94 c2                sete   %dl
  400539:       bf 01 00 00 00          mov    $0x1,%edi
  40053e:       31 c0                   xor    %eax,%eax
  400540:       e9 db fe ff ff          jmpq   400420 <__printf_...@plt>

Again, exactly the same code.

Now let's try arm, I've got a gcc 4.2.1 for armv5l lying around:

With the increment:
000083f8 <main>:
    83f8:       e3500002        cmp     r0, #2  ; 0x2
    83fc:       13a01000        movne   r1, #0  ; 0x0
    8400:       03a01001        moveq   r1, #1  ; 0x1
    8404:       e59f0000        ldr     r0, [pc, #0]    ; 840c <.text+0xe0>
    8408:       eaffffbe        b       8308 <.text-0x24>
    840c:       00008420        andeq   r8, r0, r0, lsr #8

With the integer assignment=1:

000083f8 <main>:
    83f8:       e3500002        cmp     r0, #2  ; 0x2
    83fc:       13a01000        movne   r1, #0  ; 0x0
    8400:       03a01001        moveq   r1, #1  ; 0x1
    8404:       e59f0000        ldr     r0, [pc, #0]    ; 840c <.text+0xe0>
    8408:       eaffffbe        b       8308 <.text-0x24>
    840c:       00008420        andeq   r8, r0, r0, lsr #8

And with the use of _Bool:

000083f8 <main>:
    83f8:       e3500002        cmp     r0, #2  ; 0x2
    83fc:       13a01000        movne   r1, #0  ; 0x0
    8400:       03a01001        moveq   r1, #1  ; 0x1
    8404:       e59f0000        ldr     r0, [pc, #0]    ; 840c <.text+0xe0>
    8408:       eaffffbe        b       8308 <.text-0x24>
    840c:       00008420        andeq   r8, r0, r0, lsr #8

It's really looking like gcc's optimizer is doing a whole lot of "not caring" 
about the difference in this instance.  The constant propogation is dropping 
the distinction so it's actually _less_ optimized than using the INC 
instruction (on x86, anyway), but oh well.

But I can change it if it makes you happy.

Rob
-- 
Latency is more important than throughput. It's that simple. - Linus Torvalds

_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc

Reply via email to