什么是-O3和(-O2 +标志,男人gcc说-O3加到-O2)?

csc*_*wan 27 gcc

我最近收到一个关于程序无法使用-O3开关编译的错误报告(请参阅https://github.com/cschwan/sage-on-gentoo/issues/66).特别是,问题是编译在某个时刻挂起.通过使用-O2编译来解决这个问题(我很清楚使用-O3编译的程序可能会被破坏,但我不知道-O3可能会挂起编译器).如果要重现问题运行

wget http://perso.ens-lyon.fr/xavier.pujol/fplll/libfplll-3.0.12.tar.gz
tar -xf libfplll-3.0.12.tar.gz
cd libfplll-3.0.12
./configure CXXFLAGS="-O3"
make
Run Code Online (Sandbox Code Playgroud)

我想知道为什么-O3挂起编译器,所以我试图追查这个问题.首先,我试图找出-O3之间的-O2之间的差异.Gcc的手册页指出-O3启用-O2和以下的开关(让我们调用它们x):

-finline-functions -funswitch-loops -fpredictive-commoning -fgcse-after-reload
-ftree-vectorize -fipa-cp-clone
Run Code Online (Sandbox Code Playgroud)

我验证通过时调用gcc的比较器的输出-Q -O2 --help=optimizers-Q -O3 --help=optimizers.然后,我计划有选择地删除开关,以便找到导致问题的开关.但是,编译与-O2以及上面的附加开关一起工作正常,所以我总结道

-O3 != -O2 x
Run Code Online (Sandbox Code Playgroud)

现在我的问题是:有人知道-O2和-O3之间是否存在进一步的区别(未记录?),有没有人经历过类似的行为?这可能是编译器错误吗?

osg*_*sgx 21

手册页可能已过时,但您可以找到O2和O3的实际列表.

要获得实际使用的优化选项的完整列表(几乎检查"更新")-f,我建议您使用-fverbose-asm -save-temps (或-fverbose-asm -S) - 在asm文件(*.s)的顶部有一个完整列表.

对于gcc-4.6.0,我得到x(O2和O3之间的差异):

 -fgcse-after-reload
 -finline-functions
 -fipa-cp-clone
 -fpredictive-commoning
 -ftree-loop-distribute-patterns
 -ftree-vectorize
 -funswitch-loops
Run Code Online (Sandbox Code Playgroud)

您的问题的另一个信息来源是GCC(文件gcc/opts.c和可能gcc/common.opt)的来源为gcc-4.6.0:

/* -O3 optimizations.  */
{ OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_fpredictive_commoning, NULL, 1 },
/* Inlining of functions reducing size is a good idea with -Os
   regardless of them being declared inline.  */
{ OPT_LEVELS_3_PLUS_AND_SIZE, OPT_finline_functions, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_ftree_vectorize, NULL, 1 },
{ OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 },
Run Code Online (Sandbox Code Playgroud)

我也检查过,gcc检查-On其他文件(cscope符号搜索x_optimize).

nfrom选项的唯一额外用法-On是将其值保存到宏中__OPTIMIZE__.因此,对于此宏的值等于2或3,某些标头的行为可能不同.

更新:在GCC WIKI中有关于它的问题:

  • " -O1(-O2,-O3或-Os)是否等同于个别优化选项? "

首先,单个优化选项(-f*)不启用优化,需要选项-Os或-Ox,其中x> 0.其次,-Ox标志启用许多不受任何单独的-f*选项控制的优化.没有计划添加用于控制所有这些优化的单个选项.

  • " -O1(-O2,-O3或-Os)启用了哪些特定标志? "

因平台和GCC版本而异.您可以通过执行以下操作让GCC告诉您它启用了哪些标志:

touch empty.c
gcc -O1 -S -fverbose-asm empty.c
cat empty.s
Run Code Online (Sandbox Code Playgroud)

  • 你的回答给了我正确的提示 - 在gcc/opts.c中我找到了用-O3设置的附加参数:`max-aliased-vops`和`avg-aliased-vops`.后者是我的问题的根源.设置为"3"(默认为-O3)时,编译器显示相同的行为.谢谢! (4认同)