1

我有一个简单的 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 能够消除帧指针)

4

1 回答 1

3

感谢@fuz

似乎clang在位码中添加了禁用/启用帧指针消除的属性

当使用 -O0 编译时,这些是位码中的属性:

attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }

使用 -O3 编译时,这些是属性:

attributes #0 = { norecurse nounwind readnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }

看到no-frame-pointer-elim两者的值不同。

于 2020-12-23T18:35:32.513 回答