Clang 优化级别

139

对于gcc,官方手册解释了-O3-Os等参数在具体优化参数(如-funswitch-loops-fcompare-elim等)方面的意义。

我正在寻找同样有关clang的信息。

我已经在在线手册man clang中查找,但只得到一般信息(-O2-O1更激进地进行优化,-Os针对尺寸进行优化...),并在Stack Overflow上查找到这篇文章,但在所引用的源文件中没有找到任何相关信息。

编辑:我已经找到一个答案,但仍然希望能获得有关所有优化参数及-Ox选择的相关文件链接。目前我只找到这个优化参数列表,但没有关于优化级别的相关信息。


gcc-12 -c -Q -O2 --help=optimizers - Eljay
4个回答

214

我发现这个相关问题。

总结一下,了解编译器优化过程的方法:

llvm-as < /dev/null | opt -O3 -disable-output -debug-pass=Arguments

正如Geoff Nixon(+1)所指出的那样,clang还运行一些更高级别的优化,我们可以通过以下方式检索:

echo 'int;' | clang -xc -O3 - -o /dev/null -\#\#\#

单独的 passes 文档可以在这里找到。

您可以像这样比较更改高级标志(例如 -O)的效果:

diff -wy --suppress-common-lines  \
  <(echo 'int;' | clang -xc     - -o /dev/null -\#\#\# 2>&1 | tr " " "\n" | grep -v /tmp) \
  <(echo 'int;' | clang -xc -O0 - -o /dev/null -\#\#\# 2>&1 | tr " " "\n" | grep -v /tmp)
# will tell you that -O0 is indeed the default.
使用版本6.0,各优化级别如下:
  • 基线(-O0):

    • opt设置: -tti -verify -ee-instrument -targetlibinfo -assumption-cache-tracker -profile-summary-info -forceattrs -basiccg -always-inline -barrier
    • clang添加 : -mdisable-fp-elim -mrelax-all
  • -O1 基于 -O0

    • opt添加: -targetlibinfo -tti -tbaa -scoped-noalias -assumption-cache-tracker -profile-summary-info -forceattrs -inferattrs -ipsccp -called-value-propagation -globalopt -domtree -mem2reg -deadargelim -basicaa -aa -loops -lazy-branch-prob -lazy-block-freq -opt-remark-emitter -instcombine -simplifycfg -basiccg -globals-aa -prune-eh -always-inline -functionattrs -sroa -memoryssa -early-cse-memssa -speculative-execution -lazy-value-info -jump-threading -correlated-propagation -libcalls-shrinkwrap -branch-prob -block-freq -pgo-memop-opt -tailcallelim -reassociate -loop-simplify -lcssa-verification -lcssa -scalar-evolution -loop-rotate -licm -loop-unswitch -indvars -loop-idiom -loop-deletion -loop-unroll -memdep -memcpyopt -sccp -demanded-bits -bdce -dse -postdomtree -adce -barrier -rpo-functionattrs -globaldce -float2int -loop-accesses -loop-distribute -loop-vectorize -loop-load-elim -alignment-from-assumptions -strip-dead-prototypes -loop-sink -instsimplify -div-rem-pairs -verify -ee-instrument -early-cse -lower-expect
    • clang添加: -momit-leaf-frame-pointer
    • clang删除: -mdisable-fp-elim -mrelax-all
  • -O2 基于 -O1

    • opt添加: -inline -mldst-motion -gvn -elim-avail-extern -slp-vectorizer -constmerge
    • opt删除: -always-inline
    • clang添加: -vectorize-loops -vectorize-slp

-O3是基于-O2的。

  • opt添加了::-callsite-splitting -argpromotion
  • -Ofast基于-O3,可以在clang中使用但不能在opt中使用:

    • clang添加了:: -fno-signed-zeros -freciprocal-math -ffp-contract=fast -menable-unsafe-fp-math -menable-no-nans -menable-no-infs -mreassociate -fno-trapping-math -ffast-math -ffinite-math-only
  • -Os-O2类似。

    • opt删除了:: -libcalls-shrinkwrap和-pgo-memopt-opt
  • -Oz基于-Os

    • opt删除了:: -slp-vectorizer

  • 版本3.8开始,传递如下:

    • 基线(-O0):

      • opt设置:: -targetlibinfo -tti -verify
      • clang添加了:: -mdisable-fp-elim -mrelax-all
    • -O1是基于-O0的。

      • opt adds: -globalopt -demanded-bits -branch-prob -inferattrs -ipsccp -dse -loop-simplify -scoped-noalias -barrier -adce -deadargelim -memdep -licm -globals-aa -rpo-functionattrs -basiccg -loop-idiom -forceattrs -mem2reg -simplifycfg -early-cse -instcombine -sccp -loop-unswitch -loop-vectorize -tailcallelim -functionattrs -loop-accesses -memcpyopt -loop-deletion -reassociate -strip-dead-prototypes -loops -basicaa -correlated-propagation -lcssa -domtree -always-inline -aa -block-freq -float2int -lower-expect -sroa -loop-unroll -alignment-from-assumptions -lazy-value-info -prune-eh -jump-threading -loop-rotate -indvars -bdce -scalar-evolution -tbaa -assumption-cache-tracker
      • clang adds: -momit-leaf-frame-pointer
      • clang drops: -mdisable-fp-elim -mrelax-all
      • opt adds: -elim-avail-extern -mldst-motion -slp-vectorizer -gvn -inline -globaldce -constmerge
      • opt drops: -always-inline
      • clang adds: -vectorize-loops -vectorize-slp
      • opt adds: -argpromotion
      • clang adds: -fno-signed-zeros -freciprocal-math -ffp-contract=fast -menable-unsafe-fp-math -menable-no-nans -menable-no-infs

      Note: -O2, -Os, and -Oz are optimization levels in C/C++ compilers, while -O3 is an additional optimization level based on -O2. opt refers to the LLVM optimizer. clang is a C/C++ compiler that uses LLVM as its backend.

      • opt drops: -slp-vectorizer
      • clang drops: -vectorize-loops
      • default (-O0): -targetlibinfo -verify -tti

      • -O1 is based on -O0

        • adds: -sccp -loop-simplify -float2int -lazy-value-info -correlated-propagation -bdce -lcssa -deadargelim -loop-unroll -loop-vectorize -barrier -memcpyopt -loop-accesses -assumption-cache-tracker -reassociate -loop-deletion -branch-prob -jump-threading -domtree -dse -loop-rotate -ipsccp -instcombine -scoped-noalias -licm -prune-eh -loop-unswitch -alignment-from-assumptions -early-cse -inline-cost -simplifycfg -strip-dead-prototypes -tbaa -sroa -no-aa -adce -functionattrs -lower-expect -basiccg -loops -loop-idiom -tailcallelim -basicaa -indvars -globalopt -block-freq -scalar-evolution -memdep -always-inline
      • -O2 is based on -O1

        • adds: -elim-avail-extern -globaldce -inline -constmerge -mldst-motion -gvn -slp-vectorizer
        • removes: -always-inline
      • -O3 is based on -O2

        • adds: -argpromotion -verif
      • -Os is identical to -O2

      • -Oz is based on -Os

        • removes: -slp-vectorizer
      • 添加: -argpromotion(仅限-O3)
      • 删除: -always-inline (仅限-O2和-Oz)
      • -O0: -targetlibinfo -preverify -domtree -verify
      • -O1基于-O0, 添加: -adce -always-inline -basicaa -basiccg -correlated-propagation -deadargelim -dse -early-cse -functionattrs -globalopt -indvars -inline-cost -instcombine -ipsccp -jump-threading -lazy-value-info -lcssa -licm -loop-deletion -loop-idiom -loop-rotate -loop-simplify -loop-unroll -loop-unswitch -loops -lower-expect -memcpyopt -memdep -no-aa -notti -prune-eh -reassociate -scalar-evolution -sccp -simplifycfg -sroa -strip-dead-prototypes -tailcallelim -tbaa
      • -O2 基于-O1,添加: -barrier -constmerge -domtree -globaldce -gvn -inline -loop-vectorize -preverify -slp-vectorizer -targetlibinfo -verify,删除: -always-inline
      • -O3 基于-O2, 添加: -argpromotion
      • -Os 等同于 -O2
      • -Oz基于-Os,删除: -slp-vectorizer
      • adds: -argpromotion
    • -Os等同于-O2

      • -Oz基于-O2

        • removes: -barrier -loop-vectorize -slp-vectorizer

      使用3.2版本的优化选项如下(以上述命令的解析输出为准):

      • -O0: -targetlibinfo -preverify -domtree -verify

      • -O1基于-O0

        • adds: -sroa -early-cse -lower-expect -no-aa -tbaa -basicaa -globalopt -ipsccp -deadargelim -instcombine -simplifycfg -basiccg -prune-eh -always-inline -functionattrs -simplify-libcalls -lazy-value-info -jump-threading -correlated-propagation -tailcallelim -reassociate -loops -loop-simplify -lcssa -loop-rotate -licm -loop-unswitch -scalar-evolution -indvars -loop-idiom -loop-deletion -loop-unroll -memdep -memcpyopt -sccp -dse -adce -strip-dead-prototypes
      • -O2基于-O1

        • adds: -inline -globaldce -constmerge
        • removes: -always-inline
      • -O3基于-O2

        • adds: -argpromotion
      • -Os等同于-O2

      • -Oz等同于-Os


      编辑 [2014年3月] 从列表中删除了重复项。

      编辑 [2014年4月] 添加文档链接+3.4的选项

      编辑 [2014年9月] 添加3.5的选项

      编辑 [2015年12月] 添加3.7的选项并提到现有的3.6答案

      编辑 [2016年5月] 添加了3.8的选项,适用于opt和clang,并提到了与opt相比的clang(已存在的答案)

      编辑 [2018年11月] 添加6.0的选项


    2
    有没有办法使用XCode5附带的clang版本来完成这个操作?我已经试图寻找llvm-as命令,但是在我的机器上似乎不存在。 - Teknogrebo
    2
    @Paschalis:我不确定,但由于某些优化通道只有在运行了其他通道后才能起作用,例如simplifycfg被多个通道所需。而且debug-pass=Arguments可能会在去重之前发生。我已经在我的答案中删除了重复项,感谢您的反馈。 - Antoine
    7
    有些优化会产生可以进一步优化的内容(如死代码等),因此重新运行某些优化处理可能是有意义的。 - cyco130
    3
    为什么不考虑使用LLVM 7(或者这就是你的意思吗?)此外:
    1. 我不确定它已经存在多长时间了,但现在也有类似GCC的-Og
    2. 还需要列出旧版本的所有具体信息吗?
    3. 我认为鉴于多年来所做的良好改变和社区状况,我将简化我的答案,只提及像 clang -cc1 -mllvm -help-list-hidden 这样的东西(除非你希望将其整合)。
    - Geoff Nixon
    1
    @Antoine 感谢您的回答!更新一下回答并告知“默认值仍为 -O0”将会很有用。人们可能会搜索这些信息。 - pmor
    显示剩余6条评论

    24

    @Antoine的回答(以及链接的其他问题)准确描述了启用的LLVM优化,但还有一些Clang特定的选项(即影响到AST降低的选项)受到-O[0|1|2|3|fast]标志的影响。

    你可以使用以下代码查看:

    echo 'int;' | clang -xc -O0 - -o /dev/null -\#\#\#

    echo 'int;' | clang -xc -O1 - -o /dev/null -\#\#\#

    echo 'int;' | clang -xc -O2 - -o /dev/null -\#\#\#

    echo 'int;' | clang -xc -O3 - -o /dev/null -\#\#\#

    echo 'int;' | clang -xc -Ofast - -o /dev/null -\#\#\#

    例如,-O0 启用 -mrelax-all-O1 启用 -vectorize-loops-vectorize-slp,而 -Ofast 启用 -menable-no-infs-menable-no-nans-menable-unsafe-fp-math-ffp-contract=fast-ffast-math


    @Techogrebo:

    是的,你不需要其他LLVM工具。试试这个:

    echo 'int;' | clang -xc - -o /dev/null -mllvm -print-all-options

    此外,还有很多Clang独有的详细选项可以检查/修改...你只需要知道如何访问它们!

    尝试一些:

    clang -help

    clang -cc1 -help

    clang -cc1 -mllvm -help

    clang -cc1 -mllvm -help-list-hidden

    clang -cc1as -help

    以上命令为使用clang编译器时的帮助命令。其中,clang -cc1 -help 用来查看clang编译器的基本选项和参数;clang -cc1 -mllvm -help 用来查看LLVM工具链的基本选项和参数;clang -cc1 -mllvm -help-list-hidden 用来查看LLVM工具链所有选项和参数,包括被隐藏的选项;clang -cc1as -help 用来查看clang汇编器的选项和参数。

    7
    从clang / LLVM 13.0.0开始,传统的pass manager已被弃用,默认使用新的pass manager。这意味着如果没有显式启用旧的pass manager(使用-enable-new-pm=0),则以前在opt中为不同优化级别打印优化passes的先前解决方案将无效。因此,只要传统pass manager还存在(预计到LLVM 14),就可以使用以下命令。
    llvm-as < /dev/null | opt -O3 -disable-output -debug-pass=Arguments -enable-new-pm=0
    

    另外,可以使用--debug-pass-manager(而不是-debug-pass=Arguments)提取新Pass Manager的优化Pass执行顺序。 不幸的是,输出非常冗长,需要进行一些处理才能使用-passes=手动重构行为。 如果只对转换Pass感兴趣,可以使用选项-debug-pass-manager=quiet跳过有关分析的信息。

    有一个用户指南介绍如何在LLVM网站上使用新Pass Manager。


    2

    LLVM 3.6 -O1

    传递参数:-targetlibinfo -no-aa -tbaa -scoped-noalias -assumption-cache-tracker -basicaa -notti -verify-di -ipsccp -globalopt -deadargelim -domtree -instcombine -simplifycfg -basiccg -prune-eh -inline-cost -always-inline -functionattrs -sroa -domtree -early-cse -lazy-value-info -jump-threading -correlated-propagation -simplifycfg -domtree -instcombine -tailcallelim -simplifycfg -reassociate -domtree -loops -loop-simplify -lcssa -loop-rotate -licm -loop-unswitch -instcombine -scalar-evolution -loop-simplify -lcssa -indvars -loop-idiom -loop-deletion -function_tti -loop-unroll -memdep -memcpyopt -sccp -domtree -instcombine -lazy-value-info -jump-threading -correlated-propagation -domtree -memdep -dse -adce -simplifycfg -domtree -instcombine -barrier -domtree -loops -loop-simplify -lcssa -branch-prob -block-freq -scalar-evolution -loop-vectorize -instcombine -simplifycfg -domtree -instcombine -loops -loop-simplify -lcssa -scalar-evolution -function_tti -loop-unroll -alignment-from-assumptions -strip-dead-prototypes -verify -verify-di

    -O2 基于 -O1

    添加:-inline -mldst-motion -domtree -memdep -gvn -memdep -scalar-evolution -slp-vectorizer -globaldce -constmerge

    移除:-always-inline

    -O3 基于 -O2

    添加:-argpromotion


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接