Originally Posted by
Dino
Or, with the above scenario, is the compiler smart enough to see the multiple compares and generate the code that does a single assembler compare and then branch accordingly?
Yes. This sort of optimization is typically done midway through code optimization. The condition flags can be represented as boolean temporaries, and the compiler is aware that more than one temporary can be set by a single comparison. The redundant comparisons can then be eliminated during data flow analysis.
It's actually a fairly easy optimization to make.
And of course, the proof:
Code:
void a();
void b();
void c();
void foo( int x )
{
if( x < 0 ) a();
else if( x == 0 ) b();
else c();
}
Compiled with gcc -O3 -S:
Code:
.file "foo.c"
.text
.p2align 4,,15
.globl foo
.type foo, @function
foo:
pushl %ebp
movl %esp, %ebp
cmpl $0, 8(%ebp)
jl .L9
je .L10
popl %ebp
jmp c
.p2align 4,,7
.L10:
popl %ebp
.p2align 4,,6
jmp b
.p2align 4,,7
.L9:
popl %ebp
jmp a
.size foo, .-foo
.ident "GCC: (GNU) 4.1.2 (Ubuntu 4.1.2-0ubuntu4)"
.section .note.GNU-stack,"",@progbits
(The code is somewhat odd-looking because of the compiler's tail-call elimination, but you can see that the comparison only happens once)