[Numpy-discussion] Changeset 6557

David Cournapeau cournape at gmail.com
Sun Mar 8 01:10:53 EST 2009


On Sun, Mar 8, 2009 at 4:34 AM, Charles R Harris
<charlesr.harris at gmail.com> wrote:
>
>
> On Sat, Mar 7, 2009 at 11:57 AM, David Cournapeau <cournape at gmail.com>
> wrote:
>>
>> On Sun, Mar 8, 2009 at 3:20 AM, Charles R Harris
>> <charlesr.harris at gmail.com> wrote:
>>
>> >
>> > The macro is ugly, unneeded, and obfuscating. Why construct a number
>> > from
>> > characters and shifts when you can just *write it down*?
>>
>> The idea was to replace the 'ABCD' multi-byte constant. If you think
>> that writing down the corresponding integer is cleaner, so be it - I
>> don't care either way. I am not sure I see a difference between 'A' <<
>> 24 .... and 103...., though.
>>
>>
>> > True, it is initialized here:
>> >
>> >         movl    $16909060, -8(%ebp)
>> >
>>
>> The generated assembly is exactly the same wether the constant is
>> initialized through the macro or the integer (the actual integer is in
>> the assembly). But in the following case:
>>
>> const union {
>> npy_uint32 i;
>>    char c[4];
>> } bint = {some constant};
>>
>> switch (bint.c[0]) {
>>   case 'A':
>>  etc....
>> }
>>
>> The compiler did not remove the conditionals corresponding to the
>> switch - const or not.
>
> I got curious to see just how it would all go together. Here is the C:
>
> #include <stdio.h>
>
> enum {little_endian, big_endian, unknown};
>
> static int order(void)
> {
>     const union {
>         int i;
>         char c[sizeof(int)];
>     } test = {0x01020304};
>
>     if (test.c[0] == 1) {
>         return big_endian;
>     }
>     else if (test.c[0] == 4) {
>         return little_endian;
>     }
>     else {
>         return unknown;
>     }
> }
>
> int main(int argc, char **argv)
> {
>     printf("%d\n", order());
>     return 0;
> }
>
>
> And here is the gcc -S -O2 compiled assembly:
>
>     .file    "order.c"
>     .section    .rodata.str1.1,"aMS", at progbits,1
> .LC0:
>     .string    "%d\n"
>     .text
>     .p2align 4,,15
> .globl main
>     .type    main, @function
> main:
>     leal    4(%esp), %ecx
>     andl    $-16, %esp
>     pushl    -4(%ecx)
>     pushl    %ebp
>     movl    %esp, %ebp
>     pushl    %ecx
>     subl    $20, %esp
>     movl    $0, 4(%esp)  <<<<<<<<<
>     movl    $.LC0, (%esp)
>     call    printf
>     addl    $20, %esp
>     xorl    %eax, %eax
>     popl    %ecx
>     popl    %ebp
>     leal    -4(%ecx), %esp
>     ret
>     .size    main, .-main
>     .ident    "GCC: (GNU) 4.3.0 20080428 (Red Hat 4.3.0-8)"
>     .section    .note.GNU-stack,"", at progbits
>
>
> The order function has been inlined and the return value, 0, is loaded for
> printing at the marked line.

That's strange - I redid the compilation this morning, and I now get
the same results as you (modulo the function call - I forced the
function call because that's how it would work in numpy), that is the
return value is builtin at compile time:

        .text
        .align 4,0x90
.globl _order
_order:
        pushl   %ebp
        movl    $1, %eax
        movl    %esp, %ebp
        leave
        ret
        .subsections_via_symbols

And even simpler on ppc:

        .section __TEXT,__text,regular,pure_instructions
        .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
        .machine ppc7400
        .text
        .align 2
        .p2align 4,,15
        .globl _order
_order:
        li r3,0
        blr
        .subsections_via_symbols

I don't know what I did wrong yesterday. It almost look like I did not
set the optimization flag, but I can't have been that stupid, can I :)

cheers,

David



More information about the NumPy-Discussion mailing list