clang -O1
和 opt -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 -O1
和 opt -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/