I have this foo.cpp:
int add(int a, int b) {
return a + b;
}
int add_wrapper(int a, int b) {
return add(a,b);
}
Compiling like so
g++ -c -S -fPIC -O4 -finline-functions foo.cpp -o foo.s
Gives the (demangled) assembly:
.globl add(int, int)
.type add(int, int), @function
add(int, int):
.LFB0:
.cfi_startproc
endbr64
leal (%rdi,%rsi), %eax
ret
.cfi_endproc
.LFE0:
.size add(int, int), .-add(int, int)
.p2align 4
.globl add_wrapper(int, int)
.type add_wrapper(int, int), @function
add_wrapper(int, int):
.LFB1:
.cfi_startproc
endbr64
jmp add(int, int)@PLT
.cfi_endproc
.LFE1:
.size add_wrapper(int, int), .-add_wrapper(int, int)
.ident "GCC: (Ubuntu 11.2.0-19ubuntu1) 11.2.0"
Note that add() is not inlined.
However, without -fPIC, I get
.globl add(int, int)
.type add(int, int), @function
add(int, int):
.LFB0:
.cfi_startproc
endbr64
leal (%rdi,%rsi), %eax
ret
.cfi_endproc
.LFE0:
.size add(int, int), .-add(int, int)
.p2align 4
.globl add_wrapper(int, int)
.type add_wrapper(int, int), @function
add_wrapper(int, int):
.LFB3:
.cfi_startproc
endbr64
leal (%rdi,%rsi), %eax
ret
.cfi_endproc
.LFE3:
.size add_wrapper(int, int), .-add_wrapper(int, int)
With add() inlined.
If I add inline to the declaration of add() and compile with -fPIC, I get
.globl add_wrapper(int, int)
.type add_wrapper(int, int), @function
add_wrapper(int, int):
.LFB1:
.cfi_startproc
endbr64
leal (%rdi,%rsi), %eax
ret
.cfi_endproc
.LFE1:
.size add_wrapper(int, int), .-add_wrapper(int, int)
.ident "GCC: (Ubuntu 11.2.0-19ubuntu1) 11.2.0"
With add() omitted entirely.
So it seems that inlining is not disallowed by -fPIC because the compiler will inline if I label the function inline, but I don't understand why the compiler is unwilling to inline automatically with '-fPIC'.
Does anyone know why this is?
Is there a flag that will convince g++ to inline with -fPIC but without labeling functions as inline?
I'm using g++ 11.2, but Compiler Explorer shows that the behavior is consistent across versions: https://godbolt.org/z/Y14edz968.