While working on some Linux kernel code, I've found that functions that are declared as 'static inline' are having their arguments evaluated well before they are used. For example I have a function:
static inline void trace(arg1, arg2) { if (unlikely(enabled)) { <use the arguments> } } To make this more concrete here is a simple .c program: #include <stdio.h> # define unlikely(x) __builtin_expect(!!(x), 0) int enabled = 0; struct foo { int value; }; struct foo a = { .value = 10 }; static inline evaluate(int value) { if (unlikely(enabled)) { printf("value is: %d\n", value); } } /* #define evaluate(val) \ do { \ if (unlikely(enabled)) { \ printf("value is: %d\n", val); \ } \ } while (0) */ int main() { evaluate((&a)->value); } With the macro commented out I get: 00000000004004cc <main>: 4004cc: 55 push %rbp 4004cd: 48 89 e5 mov %rsp,%rbp 4004d0: 48 83 ec 10 sub $0x10,%rsp 4004d4: 8b 3d 22 04 20 00 mov 0x200422(%rip),%edi # 6008fc <a> 4004da: e8 02 00 00 00 callq 4004e1 <evaluate> Thus, a is loaded before the call to 'evaluate' However, if i compile the macro version of 'evaluate' i get: 00000000004004cc <main>: 4004cc: 55 push %rbp 4004cd: 48 89 e5 mov %rsp,%rbp 4004d0: 48 83 ec 10 sub $0x10,%rsp 4004d4: 8b 05 ee 03 20 00 mov 0x2003ee(%rip),%eax # 6008c8 <enabled> 4004da: 85 c0 test %eax,%eax 4004dc: 0f 95 c0 setne %al 4004df: 0f b6 c0 movzbl %al,%eax 4004e2: 48 85 c0 test %rax,%rax 4004e5: 74 15 je 4004fc <main+0x30> 4004e7: 8b 35 c7 03 20 00 mov 0x2003c7(%rip),%esi # 6008b4 <a> 4004ed: bf f8 05 40 00 mov $0x4005f8,%edi 4004f2: b8 00 00 00 00 mov $0x0,%eax 4004f7: e8 bc fe ff ff callq 4003b8 <pri...@plt> Thus, the load of 'a' happens after the 'unlikely' test as I would like it. It would be nice if gcc could optimize the 'unlikely' case in the 'static inline' function case. thanks. -- Summary: request for enhancement: delay argument loading until needed Product: gcc Version: 4.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: jbaron at redhat dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40207