参考资料:《Using the GNU Compiler Collection》
打开优化标志会使编译器尝试以牺牲编译时间和调试程序的能力为代价来提高性能和/或代码大小。
根据目标和 GCC 的配置方式,在每个“-O”级别启用的优化设置可能与此处列出的设置略有不同。 您可以使用“-Q --help=optimizers”调用 GCC,以找出在每个级别启用的确切优化集。
如果您使用多个“-O”选项,无论有无级别编号,最后一个这样的选项是有效的那个。
-O1 优化。 优化编译需要更多时间,大型函数需要更多内存。使用“-O1”,编译器会尝试减少代码大小和执行时间,而不执行任何需要大量编译时间的优化。‘-O1’ 打开以下优化标志:
-fauto-inc-dec #将地址的递增或递减与内存访问相结合。
-fbranch-count-reg #
-fcombine-stack-adjustments #跟踪堆栈调整(推送和弹出)和堆栈内存引用,然后尝试找到组合它们的方法。
-fcompare-elim #在寄存器分配和post-register分配指令拆分之后,识别计算处理器标志的算术指令,类似于基于该算术的比较操作。
-fcprop-registers #在寄存器分配和post-register分配指令拆分之后,执行复制传播pass以尝试减少调度依赖并偶尔消除复制。
-fdce #在 RTL 上执行dead code消除 (DCE)。
-fdefer-pop #允许编译器让参数在堆栈上为多个函数调用累积并一次全部弹出。
-fdelayed-branch #如果目标机器支持,尝试重新排序指令以利用延迟分支指令后可用的指令槽。
-fdse #在 RTL 上执行dead store消除 (DSE)。
-fforward-propagate #在 RTL 上执行前向传播pass。 pass 尝试结合两个指令并检查结果是否可以简化。 如果循环展开处于活动状态,则执行两次pass,并在循环展开之后安排第二次pass。
-fguess-branch-probability #使用启发式猜测分支概率。
-fif-conversion #尝试将条件跳转转换为无分支的等效项。
-fif-conversion2 #使用条件执行(如果可用)将条件跳转转换为无分支的等效项。
-finline-functions-called-once #考虑所有调用一次的静态函数以内联到它们的调用者,即使它们没有标记为内联。
-fipa-modref #执行过程间 mod/ref 分析。
-fipa-profile #执行过程间配置文件传播。
-fipa-pure-const #发现哪些函数是纯函数或常数。
-fipa-reference #发现哪些静态变量不会逃逸编译单元。
-fipa-reference-addressable #发现只读、只写和不可寻址的静态变量。
-fmerge-constants #尝试跨编译单元合并相同的常量(字符串常量和浮点常量)。
-fmove-loop-invariants #在 RTL 循环优化器中启用loop invariant motion pass。
-fmove-loop-stores #在 GIMPLE 循环优化器中启用loop store motion pass。
-fomit-frame-pointer #在不需要的函数中省略帧指针。
-freorder-blocks #重新排序编译函数中的基本块,以减少采用的分支数量并提高代码局部性。
-fshrink-wrap #仅在需要它的函数部分之前发出函数序言,而不是在函数的顶部。
-fshrink-wrap-separate #分别收缩包装序言和尾声的单独部分,以便仅在需要时执行这些部分。
-fsplit-wide-types #当使用占用多个寄存器的类型时,例如 32 位系统上的 long long ,将寄存器分开并独立分配。
-fssa-backprop #在定义链上传播有关值使用的信息,以简化定义。
-fssa-phiopt #在 SSA PHI 节点上执行模式匹配以优化条件代码。
-ftree-bit-ccp #在树上执行稀疏的条件位常数传播并传播指针对齐信息。
-ftree-ccp #在树上执行稀疏条件常数传播 (CCP)。
-ftree-ch #在树上执行循环头复制。
-ftree-coalesce-vars #在将程序转换为 SSA 表示形式时,尝试通过合并不同用户定义变量的版本来减少复制,而不仅仅是编译器临时变量。
-ftree-copy-prop #在树上执行复制传播。 此遍消除了不必要的复制操作。
-ftree-dce #对树执行dead code消除 (DCE)。
-ftree-dominator-opts #基于支配树遍历执行各种简单的标量清理(常量/复制传播、冗余消除、范围传播和表达式简化)。
-ftree-dse #对树执行dead store消除 (DSE)。
-ftree-forwprop #在树上执行前向传播。
-ftree-fre #对树执行完全冗余消除 (FRE)。
-ftree-phiprop #从树上的条件指针执行负载提升。
-ftree-pta #对树执行函数局部点分析。
-ftree-scev-cprop #执行循环最终值替换。
-ftree-sink #在树上执行前向存储运动。
-ftree-slsr #对树进行直线强度降低。 这可以识别涉及乘法的相关表达式,并在可能的情况下用成本较低的计算替换它们。
-ftree-sra #执行聚合的标量替换。 此过程将结构引用替换为标量,以防止过早将结构提交到内存。
-ftree-ter #在 SSA->normal 阶段执行临时表达式替换。
-funit-at-a-time #出于兼容性原因,保留此选项。 '-funit-at-a-time' 没有效果,而“-fno-unit-at-a-time”意味着 “-fno-toplevel-reorder” 和 '-fno-section-anchors'。
-O2优化。进一步优化。 GCC 执行几乎所有支持的优化,不涉及空间速度折衷。 与“-O1”相比,此选项增加了编译时间和生成代码的性能。‘-O2’ 打开所有由 ‘-O1’ 指定的优化标志。 它还打开以下优化标志:
-falign-functions -falign-jumps
-falign-labels -falign-loops
-fcaller-saves
-fcode-hoisting
-fcrossjumping
-fcse-follow-jumps -fcse-skip-blocks
-fdelete-null-pointer-checks
-fdevirtualize -fdevirtualize-speculatively
-fexpensive-optimizations
-ffinite-loops
-fgcse -fgcse-lm
-fhoist-adjacent-loads
-finline-functions
-finline-small-functions
-findirect-inlining
-fipa-bit-cp -fipa-cp -fipa-icf
-fipa-ra -fipa-sra -fipa-vrp
-fisolate-erroneous-paths-dereference
-flra-remat
-foptimize-sibling-calls
-foptimize-strlen
-fpartial-inlining
-fpeephole2
-freorder-blocks-algorithm=stc
-freorder-blocks-and-partition -freorder-functions
-frerun-cse-after-loop
-fschedule-insns -fschedule-insns2
-fsched-interblock -fsched-spec
-fstore-merging
-fstrict-aliasing
-fthread-jumps
-ftree-builtin-call-dce
-ftree-loop-vectorize
-ftree-pre
-ftree-slp-vectorize
-ftree-switch-conversion -ftree-tail-merge
-ftree-vrp
-fvect-cost-model=very-cheap
-O3优化。 ‘-O3’ 开启所有由 ‘-O2’ 指定的优化,同时开启以下优化标志:
-fgcse-after-reload
-fipa-cp-clone -floop-interchange
-floop-unroll-and-jam
-fpeel-loops
-fpredictive-commoning
-fsplit-loops
-fsplit-paths
-ftree-loop-distribution
-ftree-partial-pre
-funswitch-loops
-fvect-cost-model=dynamic
-fversion-loops-for-stride
-O0 减少编译时间并使调试产生预期的结果。这是默认值。
-Os 优化大小。 “-Os”启用所有“-O2”优化,除了那些经常增加代码大小的优化:
-falign-functions
-falign-jumps
-falign-labels
-falign-loops
-fprefetch-loop-arrays
-freorder-blocks-algorithm=stc
它还启用“-finline-functions”,使编译器调整代码大小而不是执行速度,并执行旨在减少代码大小的进一步优化。
-Ofast 无视严格的标准合规性。 “-Ofast”启用所有“-O3”优化。 它还支持并非对所有符合标准的程序都有效的优化。 它打开“-ffast-math”、“-fallow-store-data-races”和特定于 Fortran 的“-fstack-arrays”,除非指定了“-fmax-stack-var-size”和“-fno-protect-parens’。 它关闭“-fsemantic-interposition”。
-Og 优化调试体验。 “-Og”应该是标准编辑-编译-调试周期的优化级别选择,提供合理的优化级别,同时保持快速编译和良好的调试体验。对于生成可调试代码来说,它是比‘-O0’更好的选择,因为一些收集调试信息的编译器通道在‘-O0’处被禁用。与“-O0”一样,“-Og”完全禁用了许多优化通道。 “-Og”会启用所有“-O1”优化标志,除了下面这些可能会干扰调试的优化标志:
-fbranch-count-reg
-fdelayed-branch
-fdse
-fif-conversion
-fif-conversion2
-finline-functions-called-once
-fmove-loop-invariants
-fmove-loop-stores
-fssa-phiopt
-ftree-bit-ccp
-ftree-dse
-ftree-pta
-ftree-sra
-Oz 积极优化尺寸而不是速度。这可能会增加执行的指令的数量, 如果这些指令可以用更少的字节来编码。 “-Oz”的行为类似于“-Os”,包括启用大多数“-O2”优化。