Andrej Mitrovic:

> Oh, I thought the compiler could optimize calls to popFront if I'm not
> assigning its value.
> 
> Doesn't a technique exist where if a function is called and I'm not
> assigning its result anywhere it should simply exit the function
> without returning anything? It seems like a valuable compiler
> optimization, if that is even possible.

The function may have different calling points, including having its pointer 
taken and passed around. So you generally need the full compiled function, that 
generates the output too.

If the compiler is able to perform some kind of "whole program optimization" 
(today both GCC and LLVM are able to do some of it), and the compiler is able 
to infer that the result of popFront is never used in the whole program, then 
it might be able to remove the dead code that generates the output.

If the compiler inlines popFront at a call point, and in this call point the 
result is not used, all compilers are usually able to remove the useless 
computations of the result.

Some time ago I have proposed a __used_result boolean flag, usable inside 
functions. If inside a function you use this value (inside a "static if"), the 
function becomes a template, and it generally gets compiled two times in the 
final binary. If at a calling point the result of the function doesn't get 
used, the compiler calls the template instantiation where __used_result is 
false, so with the static if you are able to avoid computing the result.

So this program:

int count = 0;

int foo(int x) {
    count++;
    static if (__used_result) {
        int result = x * x;
        return result;
    }
}

void main() {
        foo(10);
        int y = foo(20);
}


Gets rewritten by the compiler to something like:

int count = 0;

auto foo(bool use_return)(int x) {
    count++;
    static if (use_return) {
        int result = x * x;
        return result;
    }
}

void main() {
    foo!false(10);
    int y = foo!true(20);
}


That produces:

_D4test11__T3fooVb0Z3fooFiZv    comdat
                push    EAX
                mov     ECX,FS:__tls_array
                mov     EDX,[ECX]
                inc     dword ptr _D4test5counti[EDX]
                pop     EAX
                ret

_D4test11__T3fooVb1Z3fooFiZi    comdat
                push    EAX
                mov     ECX,FS:__tls_array
                mov     EDX,[ECX]
                inc     dword ptr _D4test5counti[EDX]
                imul    EAX,EAX
                pop     ECX
                ret

Bye,
bearophile

Reply via email to