clang -O1opt -O1 有什么区别?
我观察到这两个命令的行为方式截然不同。

语境

我想测试 LLVM 优化通过。更具体地说,我想选择 -O1 传递的一个子集,以便 1) 该子集的性能与整个 -O1 一样好,并且 2) 选择的传递很容易推断其正确性。

为了测试子集的性能,我写了一个shell脚本,如:

clang -o a.bc -emit-llvm -c a.c
opt (..., optmizations like -adce, ...) a.bc >a.opt.bc
clang -o a a.opt.bc

经过多次尝试,我发现:
clang -o a.bc -emit-llvm -c a.c
opt -O1 a.bc >a.opt.bc
clang -o a a.opt.bc


clang -O1 -o a a.c

发出明显不同的二进制文件。后者效率更高,例如,对于示例程序,前者运行需要 49 秒,而后者需要 29 秒。

尝试过的方法
  • 我搜索了 clang -O1 的含义,并找到了一些引用资料,如 Clang optimization levels ,但这篇文章实际上是关于 opt 的,而不是 clang
  • 我试图找到 clang 的官方文档,但没有结果。
  • 我试图理解 clang 源代码,但我无法...

  • 发现的事实
  • 我试过

    clang -o a.bc -emit-llvm -c a.c
    opt -mem2reg -O1 a.bc >a.opt.bc
    clang -o a a.opt.bc

  • 因为引用( Clang optimization levels )说 opt -O1 不包含 mem2reg pass。它有助于缩小一些差距,但并不完全。 (49 秒 -> 40 秒)我猜这意味着 clang -O1 会在 mem2reg 执行其他操作之前执行一些初步优化,例如 -O1
  • 我试过

    clang -o a.bc -emit-llvm -c a.c
    opt -mem2reg -O1 a.bc >a.opt.bc
    clang -O1 -o a a.opt.bc

  • 因为我希望在 LLVM IR 通过后进行一些与目标相关的优化。实际上它起作用了。 (40 秒 -> 26 秒,甚至比 clang -O1 的 29 秒还要快)

    结论

    总之,我猜在 clang -O1 中有一个前和后 LLVM IR 传递,而 opt -O1 中不存在。那么有没有人知道 clang -O1opt -O1 之间的区别?任何对官方文档或源代码的引用,或解决我最初问题的方法都将不胜感激。

    最佳答案

    您可以打印代码在使用 clang 时经历的所有传递(以及这些传递完成的转换的信息),如下所示:
    clang -O1 -Rpass=.* code.c
    要对 opt 执行相同操作,您可以使用:
    opt -O1 -debug-pass=Arguments code.c
    这也可能有帮助:Which optimization does LLVM perform?

    关于optimization - clang -O1 和 opt -O1 有什么区别?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24861842/

    10-12 23:25