猿问

停用GCC中的所有优化选项

使用GCC编译C程序的默认优化级别是-O0。这会根据GCC文档关闭所有优化。例如:


    gcc -O0 test.c 

但是,要检查-O0是否真的关闭了所有优化。我执行了以下命令:


    gcc -Q -O0 --help=optimizers 

在这里,我有点惊讶。我启用了大约50个选项。然后,我使用以下命令检查了传递给gcc的默认参数:


    gcc -v 

我懂了:


Using built-in specs.

COLLECT_GCC=gcc

COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.8/lto-wrapper

Target: x86_64-linux-gnu

Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.4-       

2ubuntu1~14.04' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --      

enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --

program-suffix=-4.8 --enable-shared --enable-linker-build-id --

libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-

gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-

sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-

time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --

with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-

cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-

java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-

jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-

directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-

gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --

with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release 

--build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu


Thread model: posix


gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04) 

所以我的结论是,-O0我提供给程序的标志没有被其他东西覆盖。


实际上,我正在寻求从头开始实现一种工具,该工具可以生成优化选项的随机序列,并将生成的序列与默认级别0-3进行比较。就像“ acovea”一样。因此,我想将生成的序列与零优化级别(应该是-O0)进行比较


您能解释一下为什么默认情况下启用了50个选项-O0吗?


我想到的一个想法是使用50次编译-O0并关闭默认优化。你怎么看?-O0-fno-OPTIMIZATION_NAME



侃侃无极
浏览 1273回答 3
3回答

精慕HU

Stricto sensu,GCC编译器的中端由优化遍历的序列(实际上是嵌套树,在编译过程中会动态更改)组成,因此,如果GCC没有进行优化,则将无法发出任何代码。想想另一种方式:输入语言GCC是相当丰富的(即使是纯C,在那里你有while,for,...),但中间GIMPLE语言是更差(特别是GIMPLE / SSA),所以你需要到应用一些转换以将源AST转换为Gimple。这些转换是优化过程,几乎可以定义为。另请参阅该答案和该答案的图片(SVG图片),并阅读此处提到的参考资料。您应该理解-O0为禁用生成某些可执行文件不需要的任何其他优化(例如,-O1etc等提供的优化)。

海绵宝宝撒

为了回答我的问题,我做出了一些结论和假设:因此,我想说用O0进行编译并不意味着不会应用任何优化。如上面@abligh所述,可以减少编译时间并改善调试效果的选项将打开。换句话说,O0在编译级别上正在优化。生成的二进制文件未经过优化,以简化调试过程。我举一个例子:该选项在O0级别启用渐进式循环优化在GCC文档中:此选项告诉循环优化器使用语言约束来得出循环迭代次数的界限。这假定循环代码不会通过例如引起有符号整数溢出或超出范围的数组访问来调用未定义的行为。循环迭代次数的界限用于指导循环展开和剥离以及循环退出测试优化。默认情况下启用此选项。因此,对于GCC 4.8.x,默认情况下将启用近50个选项。
随时随地看视频慕课网APP
我要回答