Walter Bright:
> I didn't know gcc had pure functions. It doesn't have immutable data. If 
> it does optimize with it, you can try it and see!

It seems to work:

// test1
int bar(int);
int foo(int i) {
    return bar(i) + bar(i);
}

Asm with no optimization and default CPU, GCC 4.2.1:

        .file   "test1.c"
        .text
.globl _foo
        .def    _foo;   .scl    2;      .type   32;     .endef
_foo:
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ebx
        subl    $4, %esp
        movl    8(%ebp), %eax
        movl    %eax, (%esp)
        call    _bar
        movl    %eax, %ebx
        movl    8(%ebp), %eax
        movl    %eax, (%esp)
        call    _bar
        leal    (%ebx,%eax), %eax
        addl    $4, %esp
        popl    %ebx
        popl    %ebp
        ret
        .def    _bar;   .scl    2;      .type   32;     .endef


With -O2:

        .file   "test1.c"
        .text
        .p2align 4,,15
.globl _foo
        .def    _foo;   .scl    2;      .type   32;     .endef
_foo:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $24, %esp
        movl    %ebx, -8(%ebp)
        movl    8(%ebp), %ebx
        movl    %esi, -4(%ebp)
        movl    %ebx, (%esp)
        call    _bar
        movl    %ebx, (%esp)
        movl    %eax, %esi
        call    _bar
        movl    -8(%ebp), %ebx
        addl    %esi, %eax
        movl    -4(%ebp), %esi
        movl    %ebp, %esp
        popl    %ebp
        ret
        .def    _bar;   .scl    2;      .type   32;     .endef


// test2
int bar(int) __attribute__ ((pure));
int foo(int i) {
    return bar(i) + bar(i);
}


Asm with no optimization:

        .file   "test2.c"
        .text
.globl _foo
        .def    _foo;   .scl    2;      .type   32;     .endef
_foo:
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ebx
        subl    $4, %esp
        movl    8(%ebp), %eax
        movl    %eax, (%esp)
        call    _bar
        movl    %eax, %ebx
        movl    8(%ebp), %eax
        movl    %eax, (%esp)
        call    _bar
        leal    (%ebx,%eax), %eax
        addl    $4, %esp
        popl    %ebx
        popl    %ebp
        ret
        .def    _bar;   .scl    2;      .type   32;     .endef


With -O2:

        .file   "test2.c"
        .text
        .p2align 4,,15
.globl _foo
        .def    _foo;   .scl    2;      .type   32;     .endef
_foo:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        movl    8(%ebp), %eax
        movl    %eax, (%esp)
        call    _bar
        leave
        addl    %eax, %eax
        ret
        .def    _bar;   .scl    2;      .type   32;     .endef

As you can see now there's just one call to bar.

Bye,
bearophile

Reply via email to