gcc 编译优化标志说明
在编译过程中我们经常会使用gcc及其相关的编译参数来编译源文件。编译Nginx编译debug版本使用的gcc 参数如下:
-pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g 。 这些参数进行分析结果如下:
-O
-O1
优化编译需要更多时间,并且大型函数需要更多内存。
使用-O,编译器会尝试减少代码大小和执行时间,而不执行任何需要大量编译时间的优化。
-O打开以下优化标志:
-fauto-inc-dec
-fbranch-count-reg
-fcombine-stack-adjustments
-fcompare-elim
-fcprop-registers
-fdce
-fdefer-pop
-fdelayed-branch
-fdse
-fforward-propagate
-fguess-branch-probability
-fif-conversion2
-fif-conversion
-finline-functions-called-once
-fipa-pure-const
-fipa-profile
-fipa-reference
-fmerge-constants
-fmove-loop-invariants
-fomit-frame-pointer
-freorder-blocks
-fshrink-wrap
-fshrink-wrap-separate
-fsplit-wide-types
-fssa-backprop
-fssa-phiopt
-ftree-bit-ccp
-ftree-ccp
-ftree-ch
-ftree-coalesce-vars
-ftree-copy-prop
-ftree-dce
-ftree-dominator-opts
-ftree-dse
-ftree-forwprop
-ftree-fre
-ftree-phiprop
-ftree-sink
-ftree-slsr
-ftree-sra
-ftree-pta
-ftree-ter
-funit-at-a-time
-O2
GCC几乎执行所有支持的优化,不涉及空间时间转换。 与-O相比,此选项增加了编译时间和生成代码的性能。
-O2打开-O指定的所有优化标志。 它还会打开以下优化标志:
-fthread-jumps
-falign-functions -falign-jumps
-falign-loops -falign-labels
-fcaller-saves
-fcrossjumping
-fcse-follow-jumps -fcse-skip-blocks
-fdelete-null-pointer-checks
-fdevirtualize -fdevirtualize-speculatively
-fexpensive-optimizations
-fgcse -fgcse-lm
-fhoist-adjacent-loads
-finline-small-functions
-findirect-inlining
-fipa-cp
-fipa-bit-cp
-fipa-vrp
-fipa-sra
-fipa-icf
-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
-fsched-interblock -fsched-spec
-fschedule-insns -fschedule-insns2
-fstore-merging
-fstrict-aliasing
-ftree-builtin-call-dce
-ftree-switch-conversion -ftree-tail-merge
-fcode-hoisting
-ftree-pre
-ftree-vrp
-fipa-ra
-O3
优化更多。 -O3打开-O2指定的所有优化,并打开以下优化标志:
-finline-functions
-funswitch-loops
-fpredictive-commoning
-fgcse-after-reload
-ftree-loop-vectorize
-ftree-loop-distribution
-ftree-loop-distribute-patterns
-floop-interchange
-floop-unroll-and-jam
-fsplit-paths
-ftree-slp-vectorize
-fvect-cost-model
-ftree-partial-pre
-fpeel-loops
-fipa-cp-clone
-O0
减少编译时间并使调试产生预期的结果。 这是默认值。
-Os
优化文件大小。 -Os启用所有通常不会增加代码大小的-O2优化。它还执行旨在减少代码大小的进一步优化。
-Os禁用以下优化标志:
-falign-functions -falign-jumps -falign-loops
-falign-labels -freorder-blocks -freorder-blocks-algorithm = stc
-freorder-blocks-and-partition -fprefetch-loop-arrays
-Ofast
无视严格的标准合规性。 -Ofast启用所有-O3优化。它还支持对所有符合标准的程序无效的优化。除非指定了-fmax-stack-var-size以及-fno-protect-parens,否则它会启用-ffast-math和Fortran特定的-fstack-arrays。
-oG
优化调试体验。 -Og启用不会干扰调试的优化。 它应该是标准编辑 - 编译 - 调试周期的优化级别,提供合理的优化级别,同时保持快速编译和良好的调试体验。
-fflag
-fflag形式的选项指定与机器无关的标志。 大多数flag都有支持和否定形式; -ffoo的否定形式是-fno-foo。
-Wpointer-arith
在void 类型的指针上做加或减操作,使用该扩展的话会警告。
#include <stdio.h>
#include <string.h>
int main(int argc,char* argv[])
{
void *test = NULL;
char value_char[] = {'H', 'e', 'l', 'l', 'o'};
test = (void *)value_char;
printf("%c\n", *(value_char + 1));
printf("%c\n", *((char *)(test + 1)));
printf("sizeof %d\n", sizeof(test));
return 0;
}
gcc test.c -Wpointer-arith
test.c: 在函数‘main’中:
test.c:11:36: 警告:‘void *’型指针用在了算术表达式中 [-Wpointer-arith]
printf("%c\n", *((char *)(test + 1)));
-pipe
常见的标志是-pipe。 此标志对生成的代码没有影响,但它使编译过程更快。 它告诉编译器在编译的不同阶段使用管道而不是临时文件,这会占用更多内存。 在内存不足的系统上,GCC可能会被杀死。 在这些情况下,请勿使用此标志。
-W -Wall
-W禁止所有警告消息。
-Wall这将启用有关某些用户认为有问题且易于避免(或修改以防止警告)的构造的所有警告,即使与宏结合使用也是如此。 这还可以在C ++ Dialect Options和Objective-C以及Objective-C ++ Dialect Options中描述一些特定于语言的警告。
-Wno-unused-parameter
没有使用的变量在编译时使用该参数会警告。需要与-W -Wall同用。
注意
如果使用多个-O选项(包含或不包含级别编号),则最后一个选项是有效的选项。
参考资料
[1].https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#Optimize-Options
[2].https://wiki.gentoo.org/wiki/GCC_optimization#-pipe
[3].https://www.rapidtables.com/code/linux/gcc/gcc-wall.html
[4].https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html