gcc -O2优化

/*
 * O2 的描述如下:
 */
    优化更多。GCC执行几乎所有支持的优化,这些优化不涉及空间-速度折衷。与-O相比,此选项增加了编译时间和生成代码的性能。

    -O2 的优化就已经很多了。除了支持 -O1 的所有优化之外,还有额外的优化。

    -falign-functions  
        -falign-functions=n
        -falign-functions=n:m
        -falign-functions=n:m:n2
        -falign-functions=n:m:n2:m2
        将函数的开头与大于或等于n的二次方对齐,最多跳过m-1个字节。
        这确保了CPU可以在不跨越n字节对齐边界的情况下获取函数的至少前m个字节。
        如果未指定m,则默认为n。

        示例:-falign functions=32将函数与下一个32字节边界对齐,
        -falign functions=24仅当可以跳过23个字节或更少的字节来完成时才与下一32字节边界对准,
        -faliign functions=32:7仅当可以通过跳过6个字节或更小的字节来实现时才与上一个32个字节边界对准。

        第二对n2:m2值允许您指定二次对齐:
        -falign functions=64:7:32:3如果可以跳过6个字节或更少,则对齐到下一个64字节边界;
        否则,如果可以跳过2个字节或更小,则对齐下一个32字节边界。如果未指定m2,则默认为n2。

        一些汇编程序仅在n是二的幂时支持此标志;在这种情况下,它是四舍五入的。

        -fno-align函数和-falign函数=1是等价的,意味着函数不对齐。

        如果未指定n或n为零,请使用与机器相关的默认值。允许的最大n选项值为65536。
        在-O2、-O3水平下启用。

    -falign-jumps
        -falign-jumps=n
        -falign-jumps=n:m
        -falign-jumps=n:m:n2
        -falign-jumps=n:m:n2:m2

        将分支目标与二次方边界对齐,用于只能通过跳跃到达目标的分支目标。在这种情况下,不需要执行伪操作。
        如果-falign标签大于此值,则使用其值。

        此选项的参数类似于-falign functions选项-fno-align跳转和-falign跳转=1是等效的,意味着循环不对齐。
        如果未指定n或n为零,请使用与机器相关的默认值。允许的最大n选项值为65536。
        在-O2、-O3水平下启用。

    -falign-labels  
        -falign-labels=n
        -falign-labels=n:m
        -falign-labels=n:m:n2
        -falign-labels=n:m:n2:m2

        将所有分支目标与二次方边界对齐。
        此选项的参数类似于-falign functions选项-fno-align labels和-falign labels=1是等效的,表示标签未对齐。
        如果-falign循环或-falign跳跃适用并且大于此值,则使用它们的值。
        如果没有指定n或n为零,则使用机器相关的默认值,该默认值很可能为"1",表示没有对齐。允许的最大n选项值为65536。
        在-O2、-O3水平下启用。

    -falign-loops
        -falign-loops
        -falign-loops=n
        -falign-loops=n:m
        -falign-loops=n:m:n2
        -falign-loops=n:m:n2:m2
        将循环与二次方边界对齐。如果循环被执行多次,这就弥补了伪填充指令的任何执行。
        如果-falign标签大于此值,则使用其值。
        此选项的参数类似于-falign functions选项-fno-align循环和-falign循环=1是等价的,意味着循环不对齐。
        允许的最大n选项值为65536。
        如果未指定n或n为零,请使用与机器相关的默认值。
        在-O2、-O3水平下启用。

    -fcaller-saves
        通过发出额外的指令来保存和恢复函数调用周围的寄存器,可以将值分配给被函数调用破坏的寄存器。
        只有当这样的分配看起来会产生更好的代码时,才会进行这样的分配。
        默认情况下,在某些机器上始终启用此选项,通常是那些没有保留调用寄存器的机器。
        在水平-O2、-O3和-Os时启用。

    -fcode-hoisting
        执行代码提升。代码提升试图尽早将在所有路径上执行的表达式的求值移动到函数出口。
        这在优化代码大小时特别有用,但通常也有助于提高代码速度。
        默认情况下,此标志在-O2及更高的温度下启用。

    -fcrossjumping
        进行交叉跳跃变换。这种转换统一了等效代码并节省了代码大小。
        所得到的代码可能比没有交叉跳跃的情况下执行得更好,也可能不更好。
        在水平-O2、-O3和-Os时启用。

    -fcse-follow-jumps  -fcse-skip-blocks
        这类似于-fsse跟随跳跃,但会导致CSE跟随有条件跳过块的跳跃。
        当CSE遇到一个没有else子句的简单if语句时,-fcse跳过块会导致CSE跟随if正文的跳转。
        在水平-O2、-O3和-Os时启用。

    -fdelete-null-pointer-checks
        假设程序无法安全地取消引用空指针,并且没有代码或数据元素驻留在地址零处。
        此选项可在所有优化级别实现简单的恒定折叠优化。
        此外,GCC中的其他优化过程使用此标志来控制全局数据流分析,从而消除对空指针的无用检查;
        这些假设对地址0的内存访问总是会导致陷阱,因此,如果在指针被取消引用后对其进行检查,则指针不能为null。
        
        然而,请注意,在某些环境中,这种假设是不正确的。使用-fno delete null指针检查可以对依赖于该行为的程序禁用此优化。
        
        默认情况下,在大多数目标上都会启用此选项。在Nios II ELF上,它默认为关闭。在AVR和MSP430上,此选项完全禁用。
        使用数据流信息的过程在不同的优化级别上独立启用。

    -fdevirtualize  
        尝试将对虚拟函数的调用转换为直接调用。这既可以在过程中完成,也可以作为间接内联(-findirect内联)
        和过程间常量传播(-fipa-cp)的一部分在过程间完成。在水平-O2、-O3和-Os时启用。

    -fdevirtualize-speculatively
        尝试将对虚拟函数的调用转换为推测性直接调用。基于对类型继承图的分析,确定给定调用的可能目标集。
        如果集合很小,最好是大小为1,则将调用更改为直接调用和间接调用之间的条件决定。
        推测调用可以实现更多的优化,例如内联。当它们在进一步优化后看起来毫无用处时,它们会被转换回原始形式。

    -fexpensive-optimizations
        执行一些相对昂贵的小优化。
        在水平-O2、-O3和-Os时启用。

    -ffinite-loops
        假设一个带有出口的循环最终会占据出口,而不是无限循环。这允许编译器删除没有副作用的循环,而不考虑最终的无休止循环。
        对于-std=C++11或更高版本的C++,此选项默认在-O2时启用。

    -fgcse  
        执行全局公共子表达式消除过程。此过程还执行全局常量和复制传播。
        注意:当使用GCC扩展computed gotos编译程序时,
        如果通过在命令行中添加-fno gcse来禁用全局公共子表达式消除过程,则可能会获得更好的运行时性能。
        在水平-O2、-O3和-Os时启用。

    -fgcse-lm
        当启用-fgcse-lm时,全局公共子表达式消除会尝试将仅由存储终止的负载移动到其自身中。
        这允许将包含加载/存储序列的循环更改为循环外的加载和循环内的复制/存储。
        启用-fgcse时默认启用。

    -fhoist-adjacent-loads
        如果负载来自同一结构中的相邻位置,并且目标体系结构具有条件移动指令,则推测地从if的两个分支提升负载。
        默认情况下,此标志在-O2及更高的温度下启用。

    -finline-functions
    -findirect-inlining
        内联也是间接调用,由于以前的内联,这些调用在编译时被发现是已知的。
        只有当通过 -finline-functions 或 -finline-small-functions 选项启用内联本身时,此选项才有任何效果。
        在水平-O2、-O3和-Os时启用。

    -finline-small-functions    
        当函数的主体小于预期的函数调用代码时,将函数集成到调用程序中(因此程序的整体大小变小)。
        编译器启发式地决定哪些函数足够简单,值得以这种方式集成。这种内联适用于所有函数,即使是那些未声明为内联的函数。
        在水平-O2、-O3和-Os时启用。
    
    -fipa-bit-cp  
        启用时,执行过程间逐位恒定传播。
        默认情况下,此标志在-O2处启用,并通过-fprofile use和-futo profile启用。它要求启用-fipa cp。

    -fipa-cp  
        进行过程间恒定传播。这种优化分析程序以确定传递给函数的值何时为常数,然后进行相应的优化。
        如果应用程序具有传递给函数的常量,则这种优化可以显著提高性能。
        默认情况下,此标志在-O2、-Os和-O3处启用。fprofile use和-futo profile也启用了它。
    
    -fipa-icf
        对函数和只读变量执行相同的代码折叠。该优化减少了代码大小,并可能通过用具有不同名称的等效函数替换函数来干扰展开堆栈。
        启用链接时间优化后,优化工作更加有效。

        尽管行为类似于Gold Linker的ICF优化,但GCC ICF在不同级别上工作,因此优化并不相同——有只有GCC才能找到的等效项
        也有只有Gold才能找到的等价项。

        默认情况下,此标志在-O2和-Os处启用。

    -fipa-ra  
        如果调用方保存寄存器未被任何调用函数使用,请使用这些寄存器进行分配。在这种情况下,没有必要在呼叫时保存和恢复它们。
        只有当被调用的函数和当前函数是同一编译单元的一部分,并且它们在当前函数之前被编译时,这才有可能。
        
        在-O2、-O3、-Os级别启用,但是,如果生成的代码将被检测以进行分析(-p或-pg),
        或者如果被调用方的寄存器用法无法准确知道(这种情况发生在RTL中不公开序言和尾声的目标上),则该选项被禁用。

    -fipa-sra
        执行聚集体的过程间标量替换,删除未使用的参数,并用值传递的参数替换参考传递的参数。
        在-O2、-O3和-Os级别启用。

    -fipa-vrp
        启用时,执行值范围的过程间传播。默认情况下,此标志在-O2处启用。它要求启用-fipa cp。

    -fisolate-erroneous-paths-dereference
        检测由于取消引用空指针而触发错误或未定义行为的路径。将这些路径与主控制流隔离,并将具有错误或未定义行为的语句变成陷阱。
        默认情况下,此标志在-O2及更高级别启用,并取决于-fdelete空指针检查是否也已启用。

    -flra-remat
        在LRA中启用CFG敏感的重新材料化。LRA没有加载溢出假名的值,而是试图在有利可图的情况下重新物质化(重新计算)值。
        在水平-O2、-O3和-Os时启用。

    -foptimize-sibling-calls
        优化同级递归调用和尾部递归调用。
        在水平-O2、-O3和-Os时启用。

    -foptimize-strlen
        将各种标准C字符串函数(例如strlen、strchr或strcpy)及其_FORTIFY_SOURCE对应函数优化为更快的替代函数。
        在-O2、-O3水平下启用。

    -fpartial-inlining
        函数的内联部分。只有当通过-finline函数或-finline小函数选项启用内联本身时,此选项才有任何效果。
        在水平-O2、-O3和-Os时启用。

    -fpeephole2
    -freorder-blocks-algorithm=stc
    -freorder-blocks-and-partition  
    -freorder-functions

    -frerun-cse-after-loop
        在执行循环优化之后,重新运行公共子表达式消除。
        在水平-O2、-O3和-Os时启用。

    -fschedule-insns  
        如果目标计算机支持,请尝试重新排序指令,以消除由于所需数据不可用而导致的执行暂停。
        这有助于具有缓慢浮点或内存加载指令的机器,允许发出其他指令,直到需要加载或浮点指令的结果。
        在-O2、-O3水平下启用。

    -fschedule-insns2
        类似于-fschedule-insns,但在完成寄存器分配后请求额外的指令调度。
        这在寄存器数量相对较少且内存加载指令占用一个以上周期的机器上尤其有用。
        在水平-O2、-O3和-Os时启用。

    -fsched-interblock  
    -fsched-spec

    -fstore-merging
        将窄存储合并到连续的内存地址。此过程将比一个字窄的立即数的连续存储合并为较少的较宽存储,以减少指令的数量。
        默认情况下,这在-O2及更高以及-Os时启用。

    -fstrict-aliasing
        允许编译器采用适用于正在编译的语言的最严格的别名规则。对于C(和C++),这会激活基于表达式类型的优化。
        特别是,假设一种类型的对象永远不会与不同类型的对象位于同一地址,除非类型几乎相同。
        例如,无符号int可以别名为int,但不能别名为void*或double。字符类型可以别名为任何其他类型。

        请特别注意以下代码:

        union a_union {
          int i;
          double d;
        };

        int f() {
          union a_union t;
          t.d = 3.0;
          return t.i;
        }

        从与最近写给的union成员不同的工会成员那里阅读(称为"打字双关语")的做法很常见。
        即使使用-fstrict别名,只要通过并集类型访问内存,也允许进行类型punning。
        因此,上面的代码按预期工作。请参见结构、并集、枚举和位字段。但是,此代码可能不会:

        int f() {
          union a_union t;
          int* ip;
          t.d = 3.0;
          ip = &t.i;
          return *ip;
        }

        类似地,通过获取地址、强制转换结果指针和取消引用结果的访问具有未定义的行为,即使强制转换使用并集类型,例如:

        int f() {
          double d = 3.0;
          return ((union a_union *) &d)->i;
        }

        在-O2、-O3和-Os级别启用-fstrict别名选项。

    -fthread-jumps
        执行优化,检查跳转是否分支到找到第一个包含的另一个比较的位置。
        如果是,则第一个分支被重定向到第二个分支的目的地或紧接着它的点,这取决于条件是真还是假。
        在-O1、-O2、-O3和-Os级别启用。

    -ftree-builtin-call-dce
        对可能设置errno但没有副作用的内置函数的调用执行条件死代码消除(DCE)。
        默认情况下,此标志在-O2时启用,如果未指定-Os,则会更高。

    -ftree-loop-vectorize
        对树执行循环矢量化。默认情况下,该标志在-O2和-ftree vectorize、-fprofile use和-futo-profile中启用。

    -ftree-pre
        对树执行部分冗余消除(PRE)。默认情况下,此标志在-O2和-O3处启用。

    -ftree-slp-vectorize
        对树执行基本块矢量化。默认情况下,该标志在-O2和-ftree vectorize、-fprofile use和-futo-profile中启用。

    -ftree-switch-conversion  

    -ftree-tail-merge
        查找相同的代码序列。找到后,将其中一个替换为跳转到另一个。这种优化被称为尾部合并或交叉跳跃。
        默认情况下,此标志在-O2及更高的温度下启用。
        可以使用最大尾部合并比较参数和最大尾部合并迭代参数来限制此过程中的编译时间。

    -ftree-vrp
        对树执行值范围传播。这类似于常数传播过程,但传播的不是值,而是值的范围。
        这允许优化器删除不必要的范围检查,如数组绑定检查和空指针检查。
        默认情况下,这在-O2及更高的温度下启用。只有启用-fdelete空指针检查时,才能消除空指针检查。

    -fvect-cost-model=very-cheap

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值