我有一个简单的 c 代码:
// main.c
#include <stdio.h>
void foo()
{
}
int main()
{
return 0;
}
以下命令的输出
clang -O3 -emit-llvm -c main.c -o main.bc; llc main.bc -o main.S; cat main.S;
我得到:
...
foo: # @foo
.cfi_startproc
# %bb.0:
retq
...
这是预期的。该foo()
功能已转换为retq
指令。
但是如果我运行以下命令:
clang -emit-llvm -c main.c -o main.bc; llc -O=3 main.bc -o main.S; cat main.S;
我得到:
...
foo: # @foo
.cfi_startproc
# %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
popq %rbp
.cfi_def_cfa %rsp, 8
retq
...
从功能上讲,这是可以的,但foo()
在这种情况下,没有必要为空函数处理帧指针。第一种情况和第二种情况的区别在于,在第一种情况下,我们使用 -O3 表示 clang,而在第二种情况下,我们使用 -O3 表示 llc。我认为这两个是等价的。
我还尝试了以下方法:
clang -emit-llvm -fomit-frame-pointer -c main.c -o main.bc ; llc -O=3 main.bc -o main.S; cat main.S;
我得到:
...
foo: # @foo
.cfi_startproc
# %bb.0:
retq
...
那么,这是否意味着如果clang
决定将帧指针发送到 LLVM 字节码中,llc
是否不够聪明,无法删除它们?(llc
似乎没有-fomit-frame-pointer
选项,尽管它确实有-disable-fp-elim
选项,Disable frame pointer elimination optimization
所以我认为 llc 能够消除帧指针)