考虑这段代码:
// foo.cxx
int last;
int next() {
return ++last;
}
int index(int scale) {
return next() << scale;
}
使用 gcc 7.2 编译时:
$ g++ -std=c++11 -O3 -fPIC
这发出:
next():
movq last@GOTPCREL(%rip), %rdx
movl (%rdx), %eax
addl $1, %eax
movl %eax, (%rdx)
ret
index(int):
pushq %rbx
movl %edi, %ebx
call next()@PLT ## next() not inlined, call through PLT
movl %ebx, %ecx
sall %cl, %eax
popq %rbx
ret
但是,当使用 clang 3.9 编译具有相同标志的相同代码时:
next(): # @next()
movq last@GOTPCREL(%rip), %rcx
movl (%rcx), %eax
incl %eax
movl %eax, (%rcx)
retq
index(int): # @index(int)
movq last@GOTPCREL(%rip), %rcx
movl (%rcx), %eax
incl %eax ## next() was inlined!
movl %eax, (%rcx)
movl %edi, %ecx
shll %cl, %eax
retq
gccnext()
通过 PLT 调用,clang 内联它。last
两者仍然从 GOT 中查找。对于在 linux 上编译,clang 进行优化是否正确,而 gcc 错过了简单的内联,或者 clang 进行优化是错误的,或者这纯粹是 QoI 问题?