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
。< / p>
我试图找到clang
的官方文档,但它没有用。
我尝试了解clang
源代码,但我无法理解......
我尝试了
clang -o a.bc -emit-llvm -c a.c opt -mem2reg -O1 a.bc&gt; a.opt.bc clang -o a.opt.bc
因为引用(Clang optimization levels)表示opt -O1
不包含mem2reg
次传递。它有助于缩小差距,但并非完全。 (49秒 - > 40秒)这意味着,我想clang -O1
在mem2reg
执行其他操作之前执行了一些初步优化,例如-O1
。
我尝试了
clang -o a.bc -emit-llvm -c a.c opt -mem2reg -O1 a.bc&gt; a.opt.bc clang -O1 -o a.opt.bc
因为我希望在LLVM IR传递之后进行一些依赖于目标的优化。实际上它奏效了。 (40秒 - > 26秒,甚至比clang -O1
的29秒更快)
总之,我猜在clang -O1
中存在LLVM IR之前和之后的传递,opt -O1
中没有。那么是否有人知道clang -O1
和opt -O1
之间的区别?任何对官方文档或源代码的引用,或解决我的初始问题的方法都将非常感激。
答案 0 :(得分:4)
您可以打印代码在使用clang
时经历的所有传递(以及有关这些传递完成的转换的信息),如下所示:
clang -O1 -Rpass=.* code.c
要对opt
执行相同操作,您可以使用:
opt -O1 -debug-pass=Arguments code.c
这也可能会有所帮助:Which optimization does LLVM perform?