Optimization clang-O1和opt-O1之间有什么区别?

Optimization clang-O1和opt-O1之间有什么区别?,optimization,clang,llvm,Optimization,Clang,Llvm,clang-O1和opt-O1之间有什么区别? 我观察到这两个命令的行为方式明显不同 上下文 我想测试LLVM优化过程。更具体地说,我想选择-O1过程的子集,以便1)子集的性能与整个-O1一样好,2)所选过程很容易推断其正确性 为了测试subset的性能,我编写了一个shell脚本,如: clang -o a.bc -emit-llvm -c a.c opt (..., optmizations like -adce, ...) a.bc >a.opt.bc clang -o a a.op

clang-O1
opt-O1
之间有什么区别? 我观察到这两个命令的行为方式明显不同

上下文 我想测试LLVM优化过程。更具体地说,我想选择
-O1
过程的子集,以便1)子集的性能与整个
-O1
一样好,2)所选过程很容易推断其正确性

为了测试subset的性能,我编写了一个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
及 叮当声-O1-o a.c

发射明显不同的二进制信号。后者的效率更高,例如,对于一个示例程序,前者需要49秒才能运行,而后者需要29秒

尝试过的方法
  • 我搜索了
    clang-O1
    的含义,并找到了一些类似的参考文献,但这篇文章实际上是关于
    opt
    ,而不是
    clang

  • 我试图为
    clang
    查找官方文档,但没有结果

  • 我试图理解源代码,但我不能

发现事实
  • 我试过了

    叮当声-o a.bc-发射llvm-c a.c opt-mem2reg-O1 a.bc>a.opt.bc 叮当声-o a.opt.bc

因为引用()说,
opt-O1
不包含
mem2reg
pass。这有助于缩小一些差距,但并非完全如此。(49秒->40秒)我想这意味着,
clang-O1
-O1
做其他事情之前执行一些初步优化,例如
mem2reg

  • 我试过了

    叮当声-o a.bc-发射llvm-c a.c opt-mem2reg-O1 a.bc>a.opt.bc 叮当声-O1-Oa 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


这也可能有帮助:

-Rpass=.*
在叮当声中对我不起作用
-mllvm-debug pass=Arguments
可以工作。