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.