GCC 4.7 has "the inter-procedural constant propagation pass" rewritten, which
brought generic function specialization to C world.
Suppose, we have the following example:
void foo(bool f)
{
char *p;
if (f) {
p = (char *) malloc(256);
if (!p) {
printf("Mem alloc error\n");
return;
}
/* something extremly valuable */
free(p);
} else {
p = (char *) malloc(256);
if (!p) {
printf("Mem alloc error\n");
return;
}
/* something very important */
free(p);
}
}
int main()
{
foo(TRUE);
foo(FALSE);
return 0;
}
GCC now able to produce the following main():
(gdb) disassemble main
<+0>: push %rax
<+1>: callq 0x4005cc <foo.part.0>
<+6>: xor %edi,%edi
<+8>: callq 0x400649 <foo>
<+13>: xor %eax,%eax
<+15>: pop %rdx
<+16>: retq
Note, that GCC has actually generated two functions:
-- foo.part.0 at 0x4005cc
-- foo at 0x400649
for each possible arg values: TRUE and FALSE.
Since compiler now changes function call code it has to protect himself from "incorrect"
outside calls, e.g. foo(TRUE) instead of foo.part.0(TRUE)
That's the reason "master" copy of foo() has switch() at the beginning:
(gdb) disassemble foo
<+0>: test %dil,%dil
<+3>: je 0x400653 <foo+10>
<+10>: push %rbx
<+11>: mov $0x40079e,%edi
[...]