gcc 处理过程:
1. 预处理 -E (.c->.i)
gcc -E test.c -o test.i
2. 编译 -S (.i->.s)
gcc -S test.i
3. 汇编 -c (.s->.o)
gcc -c test.s
4. 链接并生成可执行文件
gcc test.o -o test
5. 生成目标文件依赖关系:
gcc -M test.c
输出:
test.o: test.c /usr/include/stdio.h /usr/include/features.h \
/usr/include/bits/predefs.h /usr/include/sys/cdefs.h \
/usr/include/bits/wordsize.h /usr/include/gnu/stubs.h \
/usr/include/gnu/stubs-32.h \
/usr/lib/gcc/i686-linux-gnu/4.4.5/include/stddef.h \
/usr/include/bits/types.h /usr/include/bits/typesizes.h \
/usr/include/libio.h /usr/include/_G_config.h /usr/include/wchar.h \
/usr/lib/gcc/i686-linux-gnu/4.4.5/include/stdarg.h \
/usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h
6. 打印编译器相关信息
the version number of the compiler driver program and of the preprocessor and the compiler proper.
打印更多信息,比如:头文件搜索路径,可以用如下方法:
新建一个空的cpp文件, touch test.cpp,然后,g++ -E -v -P test.cpp,输出如下:
使用内建 specs。
COLLECT_GCC=/usr/bin/g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/i686-redhat-linux/4.6.2/lto-wrapper
目标:i686-redhat-linux
配置为:../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch=i686 --build=i686-redhat-linux
线程模型:posix
gcc 版本 4.6.2 20111027 (Red Hat 4.6.2-1) (GCC)
COLLECT_GCC_OPTIONS='-E' '-v' '-P' '-shared-libgcc' '-mtune=generic' '-march=i686'
/usr/libexec/gcc/i686-redhat-linux/4.6.2/cc1plus -E -quiet -v -P -D_GNU_SOURCE test1.cpp -mtune=generic -march=i686
忽略不存在的目录“/usr/lib/gcc/i686-redhat-linux/4.6.2/include-fixed”
忽略不存在的目录“/usr/lib/gcc/i686-redhat-linux/4.6.2/../../../../i686-redhat-linux/include”
#include "..." 搜索从这里开始:
#include <...> 搜索从这里开始:
/usr/lib/gcc/i686-redhat-linux/4.6.2/../../../../include/c++/4.6.2
/usr/lib/gcc/i686-redhat-linux/4.6.2/../../../../include/c++/4.6.2/i686-redhat-linux
/usr/lib/gcc/i686-redhat-linux/4.6.2/../../../../include/c++/4.6.2/backward
/usr/lib/gcc/i686-redhat-linux/4.6.2/include
/usr/local/include
/usr/include
搜索列表结束。
COMPILER_PATH=/usr/libexec/gcc/i686-redhat-linux/4.6.2/:/usr/libexec/gcc/i686-redhat-linux/4.6.2/:/usr/libexec/gcc/i686-redhat-linux/:/usr/lib/gcc/i686-redhat-linux/4.6.2/:/usr/lib/gcc/i686-redhat-linux/
LIBRARY_PATH=/usr/lib/gcc/i686-redhat-linux/4.6.2/:/usr/lib/gcc/i686-redhat-linux/4.6.2/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-E' '-v' '-P' '-shared-libgcc' '-mtune=generic' '-march=i686'
7. 禁止预处理(-E)的输出中包含行号
-P Inhibit generation oflinemarkers in the output from the preprocessor. This might be useful when
running the preprocessor on something that is not C code, and will be sent to a program which might
be confused by the linemarkers.
8. 优化
-O0 不优化
-O1
-O2 默认优化级别
摘自:http://bbs.nankai.edu.cn/cgi-bin/bbs/bbsanc?path=/groups/GROUP_2/Linux/D4CC04B15/M.1211877692.A
优化级别:
-O0 不优化(默认级别)
-O , -O1 减少编译的时间以及镜像的大小
-O2 比-O1更进一步的优化(只对那些don’t increase over speed (或者相反的)
适用)
-Os 使产生的镜像大小更为优化(除了那些增加大小的所有 –O2)
-O3 更多的优化(-O2,再加两三个)
-O0 优化
当指定了-O0优化选项(或者根本没有任何优化器说明指定)时,编译器将仅仅产生提
供了所希望的结果并可以简单地被一个源代码调试器(比如GNU Debugger,gdb)调试的
代码。编译当不优化的时候是十分快捷的,这是因为优化器根本没有被调用。
-O1 优化(-O)
在优化的第一个级别当中,优化器的目标是尽可能快地进行编译同时减少产生的代码以
及执行时间。与-O1级别相比,用-O0级别进行编译需要消耗更多的时间同时这还取决于
被编译的源代码,而这通常是不可见。
defer-pop 推迟从堆栈当中弹出函数参数直到必要的时候
thread-jumps 执行跳转(jump)穿线(threading)优化(避免跳转到跳转)
branch-probabilities 用分支(branch) profiling(模型)来优化分支
cprop-registers 执行一个寄存器复制传播优化遍数
guess-branch-probability 激活分支可能性推测
Omit-frame-pointer 不要产生栈帧(尽可能地)
-O2 优化
优化的第二级别提供了更多的优化选项(同时包括了在-o1中的那些优化),但是它不
包含那些为了空间而牺牲速度的优化(反之亦然)
align-loops 对齐循环的起点
align-jumps 对齐那些只有跳转可获取的标签
align-labels 对齐所有标签
align-functions 对齐函数的起点
optimize-sibling-calls 优化sibling(兄弟)以及尾部(tail)的递归调用
ces-follow-jumps 当执行CSE时,跟随跳转转移到跳转的目标
ces-skip-blocks 当执行CSE时,跟随条件跳转转移
gcse 执行公共的全局子表达式的消除
expensive-optimizations 执行一套开销大的优化
strength-reduce 执行减少强度的优化
rerun-cse-after-loop 在循环优化之后返回CSE
caller-saves 激活寄存器来保存around函数调用
force-mem 在使用之前拷贝操作数内存到寄存器当中
peephole2 在sched2之前激活一个rtl peephole
regmove 激活寄存器迁移优化选项
strict-aliasing 假定严格的别名使用规则应用
delete-null-pointer-checks 删除无用的空指针检查
reorder-blocks 记录基本的块来改善代码的布局
schedule-insns 在寄存器分配之前重新调度指令
schedule-insns2 在寄存器分配之后重新调度指令
rerun-loop-opt 再运行循环优化器两次
-Os级别的优化只是简单地禁止了-O2当中的一些选项,否则的话这些选项将会导致产生
的镜像的体积变大。这些被禁止的出现在-O2当中的选项为:-falign-labels,
-falign-jumps, -falign-labels以及-falign-functions。它们当中的每一个都极有可
能导致产生的镜像的体积变大,因此禁止它们有助于构建应该体积更小的可执行文件?
-O3优化
-O3级别的优化是GCC提供的最高级别的优化。除了那些提供在-O2当中的优化选项
-finline-functions 在调用函数当中嵌入一些简单的函数
-frename-registers 为带有大量寄存器(这使得调试十分可能)的架构优化寄存
器分配
用volatile 关键字修设变量,可以防止优化;
给某段代码设定优化级别:
1 #pragma GCC push_options
2 #pragma GCC optimize ("O0")
3
4 your code
5
6 #pragma GCC pop_options
摘自:http://blog.csdn.net/fyfhust/article/details/5793482
另外一个相关概念:memeory barier,令处于memory barrier 中的代码按照顺序执行。
9. -Wl,options 把options传递给链接器
如: gcc -Wl,--verbose a.c