clang -O1和opt -O1有什么区别?

Jee*_*ang 4 optimization llvm clang

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
Run Code Online (Sandbox Code Playgroud)

经过大量尝试,我发现:

clang -o a.bc -emit-llvm -c a.c
opt -O1 a.bc >a.opt.bc
clang -o a a.opt.bc
Run Code Online (Sandbox Code Playgroud)

和clang -O1 -oa ac

发出明显不同的二进制文件。后者要高效得多,例如,对于一个示例程序,前者需要49秒才能运行,而后者则需要29秒。

尝试的方法

  • 我搜索了它的含义clang -O1,并找到了一些参考(例如Clang优化级别),但是这篇文章的确是关于opt,而不是clang

  • 我试图找到的正式文档clang,但没有成果。

  • 我试图了解clang源代码,但我无法...

发现的事实

  • 我尝试过

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

因为参考(Clang优化级别)表示opt -O1不包含mem2regpass。它帮助弥合了一些差距,但并没有完全消除。(49秒-> 40秒),我想这意味着先clang -O1进行一些初步优化,例如mem2reg,然后再进行-O1其他操作。

  • 我尝试过

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

因为我希望在LLVM IR通过之后进行一些与目标相关的优化。确实有效。(40秒-> 26秒,甚至比clang -O129秒还要快)

结论

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

shr*_*hrm 5

您可以打印使用clang以下代码时要经过的所有过程(以及这些过程完成的转换的信息):

clang -O1 -Rpass=.* code.c

要对进行相同操作opt,您可以使用:

opt -O1 -debug-pass=Arguments code.c

这也可能会有所帮助:LLVM执行哪种优化?