php apache mysql google linux HTML5 nginx linux命令 Windows centos 程序员 Python 开源 Firefox Android wordpress 微软 Ubuntu shell java

GCC 4.8 发布

近日,gcc正式发布了GCC 4.8版本,这是GCC又一次重大的升级。下面我们逐一列举之。

亮点

  • 从这个版本开始,GCC开始直接在其源码中使用C++.这意味着在编译GCC的时候,需要现有一个支持C++ 2003的编译器。相关的改动,以及GCC使用C++的情况,请参考这里
  • 基于多面体理论的循环优化Graphite更新了CLOOG和ISL的版本。
  • 更激进的循环上界分析推到算法。 根据新的语言标准中的一些约束,GCC使用了更激进一些的循环上界分析策略,但这有可能导致一些老的程序运行出错。 打算用GCC来跑SPEC CPU分数的朋友注意了,SPEC CPU 2006的464和416会出错。 如果要关闭此优化,需要使用选项: -fno-aggressive-loop-optimizations 。
  • ARM上有关向量-NEON的一个bug修正。因为ABI的变化,和此bug的修正,有可能导致旧的使用intrinsic函数编写的向量化程序,与先前版本GCC编译的binary无法兼容。 自动向量化的程序不受影响。
     

通用优化方面的改进

  • 改用DWARF4标准生成调试信息。现在使用-g选项,默认就会生成DWARF 4格式的调试信息。如果需要使用之前版本GCC采用的DWARF 2格式信息,可以使用选项-gdwarf-2。
  • 增加了一个新的优化级别 -Og,  相比于其他优化级别,该优化级别的亮点是:快速编译、调试信息、一些有必要的程序优化。 虽然不是很具体, 《灵犀志趣》怀疑此选项实际为 “-O0 -g -fXXXX …”(一些常用优化选项)
  • 引入新选项 -ftree-partial-pre用于控制部分冗余删除优化。该选项会在O3中打开。
  • -fconserve-space选项被移除。因为GCC已经支持将变量直接放入BSS段,因此大多数后端CPU已经用不着此优化了。
  • 移除了结构体域重排优化和矩阵重排优化,因为这两个优化bug太多,且对大多数程序无效,无法和链接时优化很好的联合工作。
  • 优化了GCC编译较大函数时的速度
  • 重写了链接时优化的代码,修正了一些bug,提升了代码的可靠性和可维护性。
  • 过程间优化也做了改进: 1)引入了一个新的符号表,该符号表在已有调用图和变量池的基础上构建,并且对外提供一些API。该表对一些别名和变量可见性的分析更准确,能为链接时优化中的,激进冗余代码删除,提供依据; 2)  改进了inline策略,现在即使函数的size较大,如果inline有好处,gcc仍然会inline; 3)不管是值传参还是引用传参, 对于常数,GCC都能做一些常数传播了。
  • 引入了一个新的内存错误检测工具: AddressSanitizer。使用选项-fsanitize=address能打开此检测器。 该检测器会对访存指令插装,帮助快速检测堆、栈以及全局的缓冲区溢出,以及use-after-free bug。 这个检测工具可以在Intel/PowerPC Linux系统,以及Intel Darwin上使用, ARM还不行。
  • 引入了一个新的data race检测器: ThreadSanitizer。 使用选项 -fsanitize=thread能打开此检测器。头疼多线程bug调试的朋友,可以试试。

语言相关改进

C语言

  • 前端的错误和警告输出增加列信息。 现在的GCC可以像LLVM那样,输出更加精确的出错代码的位置了。选项 -fno-diagnostics-show-caret 能关闭此功能.
  • 报警信息中默认包含宏展开栈信息。因为默认打开了选项-ftrack-macro-expansion=2,再结合错误输出的列信息,如果代码中有宏展开引起的错误,GCC能报的更加容易理解了。
  • 增加新的警告选项 -Wsizeof-pointer-memaccess, 默认关闭,但在-wall中会被打开。这样,对于一些需要传入长度的函数,比如memcpy之类的,可以给出一些可能导致出错的sizeof()使用。
  • 调整了两个警报选项的报警规则和打开方式: -Wpedantic 和 -Wshadow

C++语言

  • 支持了C++11中的thread_local关键字,用于声明线程私有变量。
  • 支持了C++11中的属性文法, 和 地址对齐文法
  • 支持了C++11中的继承基类构造函数。
  • 增加了一个新的选项-std=c++1y, 用于支持将于2017年才发布的一些C++语言特性的实验性功能。
  • 还增加了一个-fext-numeric-literal选型来控制数字格式在编译器中,和C++11标准的结合方式。另外还废弃了一个有关命名空间的扩展 __attribute((strong)).

运行时库(libstdc++)

  •  针对ISO C++11标准的一些实验性特性进行了改进。
  • 改进了标准库 <random>和<ext/random>
  • 增加新的选项:–disable-libstdcxx-verbose 。使用该选项configure libstdc++能避免在程序异常崩溃时生成一些调试信息。没有这些信息之后,能减小生成的libstdc++库的大小,这在嵌入式系统中很有用。

Fortran、Go语言

  • Fortran前端增加了几个警告选项,对Fortran 2003的标准支持也有了提升
  • Go语言方面,实现了针对Go 1.1版本的原则性支持,目前还不完善。

后端相关改进

AArch64

  • 增加了AArch64这一新的后端,一个64bit版本的ARM体系结构。该机构和已有的32位ARM完全独立
  • 目前只是针对Cortex-A53和Cortex-A57处理器提供了基本支持。可以分别使用选项-mcpu=cortex-a53 和 -mcpu=coretex-a57 打开对这两个处理器的支持。

ARM

  • 增加一个针对AArch32的基本支持
  • Cortex-A7和Cortex-A15的代码生成阶段做了优化
  • 增加了针对Marvell PJ4处理器的支持,可以使用选项 -mcpu=marvell-pj4打开该支持。
  • 引入了一个新的针对自动向量化的代价模型。
  • 指令调度器也做了更新

IA-32/X86-64

  • 在禁止SSE扩展的条件下,支持 -mpreferred-stack-boundary=3。这个选项用于解决一个栈上的内存对齐问题。 如果你的代码中包含了SSE,推荐使用该选项重新编译一次相关代码库。
  • 支持BroadWell处理器中的 RDSEED, ADCX, ADOX, PREFETCHW。 需要同时使用相应的选项才能打开。
  • 针对处理器的一些新增指令,增加了对应的intrinsic,比如Intel RTM, HLE, FXSR, XSAVE, XSAVEOPT.
  • 增加新的builtin函数,可以在程序运行时判断CPU的类型和指令集
  • 在G++中支持了同名函数的多版本。比如可以指定一个函数有普通标量版本、SSE向量版本、AVX向量版本等。这样可以在运行时,针对不同的ISA选择不同的版本。 详细的内容参考这里
  • 增加了针对AMD的两款CPU的支持: AMD 15h 和 16h

延伸阅读

评论