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

时间:2011-06-23 13:02:25

标签: 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

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

-finline-functions -funswitch-loops -fpredictive-commoning -fgcse-after-reload
-ftree-vectorize -fipa-cp-clone

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

-O3 != -O2 x

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

2 个答案:

答案 0 :(得分: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

您的问题的另一个信息来源是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 },

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

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

更新:There are questions about it in GCC WIKI

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

没有。首先,单个优化选项(-f *)不启用优化,选项-Os或-Ox with x> 0是必需的。其次,-Ox标志启用许多不受任何单独的-f *选项控制的优化。 There are no plans to add individual options for controlling all these optimizations.

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

因平台和GCC版本而异。您可以通过这样做让GCC告诉您它启用了哪些标志:

touch empty.c
gcc -O1 -S -fverbose-asm empty.c
cat empty.s

答案 1 :(得分:3)

如果您的编译器挂起,那么是 - 我认为这是一个编译器错误。编译器也有bug。

(即使用于编译编译器的编译器存在错误,也可能在新编译器中引入了一个错误 - gcc采取了一些步骤来通过它的暂存引导来避免这种错误。)

也可能是其他事情,例如完成优化只需要花费更多,更多时间来执行,或者增加的优化级别会导致使用更多内存,并且您的系统开始无用。