本页是对GCC 10中大量改进中的一些改进的简要总结。您可能还想查看我们的“移植到GCC 10”页和完整的GCC文档。
修复了C++14和C++17之间的ABI不兼容问题。在某些目标上,带有零子对象的类在编译为C++17或C++20时会被错误传递。有关详细信息,请参阅下面的C++注释。
非标准std::__is_nullptr_t类型特征已弃用,将在未来版本中从libstdc++中删除。标准特征STD::IS_NULL_POINTER应该改为。
构建GCC所需的mpfr库的最低版本已经增加到3.1.0版(发布于2011年10月03日)。
删除了--param allow-store-data-races内部参数,而采用了新的官方选项-falow-store-data-races。虽然默认行为没有改变,并且新的选项允许在链接时间优化期间正确地维护每个编译单元的设置,但是现在将诊断默认的via--param allow-store-data-race的更改,并且必须相应地调整构建系统。
卸载到异构系统架构中间语言(HSAIL)已被弃用,可能会在将来的版本中删除。
新增内置函数:可以使用__HAS_BUTHIN内置预处理器运算符查询对GCC等编译器提供的内置函数的支持情况。
新的命令行选项:-fprofile-Partial-Training现在可以用来通知编译器,培训运行未覆盖的代码路径不应针对大小进行优化。
-fprofile-reducable控制由-fprofile-GENERATE收集的配置文件的可重现性级别。这使得重建具有相同结果的程序成为可能,例如,这对于分发包是有用的。
-fprofile-prefix-path可以与-fprofile-Generate=profile_dir和-fprofile-use=profile_dir组合使用,用于通知GCC构建源树的基目录在哪里,以防检测和优化构建有所不同。
-fAnalyzer启用新的静态分析过程和相关警告。此遍对代码中的路径执行耗时的探索,希望检测各种常见错误,如双重释放的错误。此选项在此版本中应视为试验性选项。特别是,对非C代码的分析不太可能起作用。
过程间优化改进:重新实现了聚合的过程间标量替换(IPA-SRA)传递,以便在链接时工作,现在还可以删除计算和返回未使用的返回值。
-finline-Functions现在在-O2处启用,并重新优化以获得更好的代码大小,而不是运行时性能权衡。内联启发式也大大加快了速度,避免了对-flto-O2编译时间的负面影响。
内联启发式和函数克隆现在可以使用值范围信息来预测单个转换的有效性。
在链接时间优化过程中,使用C++One Definition Rule来提高基于类型的别名分析的精度。
链接时间优化改进:添加了新的二进制LTO-DUMP。该程序可以转储有关LTO字节码目标文件的各种信息。
LTO的并行阶段可以自动检测正在运行的make';的jviewer,或者可以回退到可用核心的数量。
LTO字节码可以用ZSTD算法进行压缩。配置脚本可以自动检测zstd支持。
MOST--参数值现在可以按转换单元粒度指定。这包括控制内联和其他过程间优化的所有参数。与早期版本不同,GCC 10将忽略控制在链接时指定的优化的参数,并以与优化标志相同的方式应用在编译时指定的参数。
配置文件驱动的优化改进:使用-fprofile-value,插入指令的二进制文件可以跟踪间接调用的多个值(最多4个),并提供更精确的配置文件信息。
C、C++和Fortran编译器现在支持openacc规范的2.6版。有关详细信息,请参阅openacc wiki页面上的实现状态部分和运行时库文档。
GCC 10在GCC 9版本的基础上增加了多个新实现的OpenMP5.0功能,如条件lastprivate子句、扫描和循环指令、ORDER(并发)和USE_DEVICE_ADDR子句支持、SIMD构造上的IF子句或对DECLARE_DEVANT VARIANT指令的部分支持,更加接近对OpenMP 5.0标准的全面支持。
OpenMP和openacc现在支持卸载到AMD Radeon(GCN)GPU;支持的是第三代斐济(斐济)和第五代Vega 10/Vega 20(gfx900或gfx906)。
新属性:添加了access函数和type属性,以描述函数如何访问通过指针或引用传递给它的对象,并将此类参数与表示对象大小的整数参数相关联。该属性用于检测用户定义函数的无效访问,例如由-Wstringop-overflow诊断的函数。
symver属性可用于将符号绑定到ELF平台上的特定版本节点。这比将GNU作为symver指令使用内联汇编更可取,因为后者与链接时优化不兼容。
新警告:-Wstring-Compare,由-WExtra启用,警告零与调用strcmp和strncmp的结果之间的相等和不等表达式,这是由于一个参数的长度大于另一个参数所指向的数组的大小而导致的常量。
-WzerLength-Bound由-Warray-Bound启用,警告对可能与同一对象的其他成员重叠的零长度数组元素的访问。
对现有警告的增强:-Warray-bound检测到更多对成员数组的越界访问以及对零长度数组元素的访问。
-Wstringop-overflow检测到成员数组的更多越界存储,包括零长度数组、动态分配的对象和可变长度数组,以及字符串内置函数读取未终止字符数组的更多实例。该警告还检测到通过调用使用新属性访问声明的用户定义函数进行的越界访问。
除了已经支持的UCN语法(\uNNNN或\UNNNNNNN)之外,现在可以在输入编码(默认情况下为UTF-8)中直接指定标识符中的扩展字符:
使用-std=c2x和-std=gnu2x支持即将发布的ISO C标准C2X修订版中的几个新功能。在编译旧语言版本时,还支持将其中一些功能作为扩展。除了列出的功能外,在C2X模式下默认启用了一些以前支持作为扩展并现在添加到C标准中的功能,并且没有使用-std=c2x-Wpedtic进行诊断。与在C++中一样,支持[[]]属性语法。现有属性可以与此语法一起使用,格式如[[gnu::const]]。支持标准属性[[Deproated]]、[[Fall Through]]和[[Mayse_Unussed]]。
支持十进制浮点算术时,除以前仅在包含<;float.h>;之前定义了__STDC_WANT_DEC_FP__时才定义的宏外,<;float.h>;还定义了宏DEC32_TRUE_MIN、DEC64_TRUE_MIN和DEC128_TRUE_MIN。
在C2X模式下,函数定义中的空括号为该函数提供了一个具有原型的类型,以供后续调用;在C2X模式下,默认情况下会诊断其他旧式函数定义。
GCC现在默认为-fno-common。因此,对各种目标的全局变量访问效率更高。在C语言中,具有多个试探性定义的全局变量现在会导致链接器错误。使用-fcommon,这样的定义在链接期间以静默方式合并。
新警告:-Wmismatted-Tags,默认情况下禁用,警告有关结构、类和类模板的声明及其专门化,如果未提供定义,则类键与定义或第一个声明都不匹配。提供该选项是为了简化对基于Windows的编译器的可移植性。
-wredundant-tag默认禁用,在可以消除键而不会导致语法歧义的上下文中警告冗余的class-key和enum-key。
GCC 10中的几个目标(包括AArch64、ARM、PowerPC ELFv2、S/390和Itanium)改变了按值传递和返回某些C++类的ABI。这些更改影响具有零大小的子对象(空基类,或具有[[NO_UNIQUE_ADDRESS]]属性的数据成员)的类,而所有其他非静态数据成员具有相同的类型(在某些ABI规范中称为同构聚合,或者如果只有一个这样的成员,即单个元素)。在-std=c++17和-std=c++20模式中,基类为空的类不会被视为具有单个元素或同构聚合,因此可能会以不同方式传递(在错误的寄存器或在错误的堆栈地址)。这可能会使使用-std=c++17和-std=c++14ABI编译的代码不兼容。此问题已更正,并且在那些ABI决策中忽略了空基,因此使用-std=c++14和-std=c++17编译的函数现在再次与ABI兼容。示例:struct Empty{};struct S:Empty{Float f;};void f(S);。类似地,在包含使用C++20[[NO_UNIQUE_ADDRESS]]属性的类类型为空的非静态数据成员的类中,这些成员在传递决策的ABI参数中没有被忽略。这两种ABI变化现在都被诊断为-Wpsabi。
现在可以从任何返回符号或元组的__特征直接创建别名。以前,需要使用AliasSeq来为它们的返回设置别名。
现在可以使用__特征(getLinkage,.)检测为结构、类或接口指定的ABI语言。添加了对core.math.toPrec内部功能的支持。这些内部函数保证在代码中的指定点四舍五入到特定的浮点精度。
已经实现了对杂注(内联)的支持。以前,杂注可以识别,但对编译没有影响。
ASM操作数中的可选括号已弃用,并将在将来的版本中删除。
现在,使用-M编译时,所有内容导入的文件都包含在Make Dependency列表中。
由gcc.attribute模块提供的编译器识别的属性现在将在应用于函数原型以及应用于完整函数声明时生效。
添加了--enable-libphobos-check配置选项,以控制是否将运行时检查编译到D运行时库中。
添加了--with-libphobos-druntime-only配置选项,以指示是只将核心D运行时库构建到libphobos中,还是将核心库和标准库都构建到libphobos中。
现在支持OpenMP规范5.0版的use_device_addr。请注意,除此之外,Fortran编译器还部分支持OpenMP 4.5;缺少的最大项是结构元素映射。
使用未格式化文件的I/O的默认缓冲区大小已增加到1048576。现在,可以在运行时通过格式化文件和未格式化文件的环境变量GFORTRAN_FORMACTED_BUFFER_SIZE和GFORTRAN_UNFORMACTED_BUFFER_SIZE分别设置的缓冲区大小。
单个文件中的实际参数列表和伪参数列表之间的不匹配现在会被拒绝,并返回错误。使用新选项-fallow-argument-mismatch将这些错误转换为警告;此选项隐含在-std=Legacy中。-Wargument-已删除不匹配。
对BOZ文字常量的处理进行了修改,以更好地符合Fortran 2008和2018标准。在这些Fortran标准中,BOZ文字常量是无类型和无类型的实体。作为返工的一部分,Fortran标准的有文档和无文档的扩展现在会在编译期间发出错误。其中一些扩展可以与-fallow-invalid-boz一起使用,其中错误会降级为警告,并且代码会像以前的gfortran一样进行编译。
在除-Os之外的任何优化级别,gfortran现在对参数使用内联打包,而不是调用库例程。如果源代码包含大量需要重新打包的参数,则代码大小或编译时间可能会变得过大。如果是这种情况,可以使用-fno-inline-arg-pack来禁用内联参数打包。
传统扩展:对于格式化的输入/输出,如果省略了数据编辑描述符I、F和G之后的显式宽度,则使用默认宽度。
格式规范末尾的格式项目不允许为空,即最后一个逗号后不允许有任何内容。使用选项-FDEC-BLACK-FORMAT-ITEM;此选项隐含在-FDEC中。
已扩展对自动和静态属性的现有支持,以允许在等价语句中使用具有自动属性的变量。使用-FDEC-STATIC;此选项由-FDEC隐含。
允许在数值(整数、实数或复数)或逻辑变量的赋值和数据语句中使用字符文字。使用选项-fdec-char-Conversions;此选项隐含在-fdec中。
十进制比较,即允许使用霍尔瑞斯常量与整数、实数、复数和字符表达式进行比较。使用选项-FDEC。
错误和警告中的字符类型名称现在除了种类之外还包括len;*用于假定长度。如果是默认类型,则省略该类型。例如:Character(12)、Character(6,4)。
Co_Broadcast现在支持派生类型变量,包括具有可分配组件的对象。在本例中,可选参数STAT=和ERRMSG=当前被忽略。
对模块和子模块名称的处理进行了修改,以允许标准要求的63个字符的完整长度。以前,如果模块、子模块和函数名称的总长度超过126个字符,则符号名称会被截断。因此,此更改违反了ABI,但仅适用于超过126个字符限制的情况。
AArch64和ARM端口现在支持串联组件中的条件标志输出约束,如__GCC_ASM_FLAG_OUTPUTS__所示。在ARM上,此功能仅适用于A32和T32目标。有关更多详细信息,请参阅文档。
与可伸缩向量扩展(Scalable Vector Extension,SVE)相关的改进有几个:现在支持SVE Acle类型和内部函数。可以使用头文件arm_sve.h访问它们。
现在可以使用ARM_SVE_VECTOR_BITS属性创建固定长度的SVE类型。例如:
-MSVE-VECTOR-BITS=128现在为小端目标生成特定于向量长度的代码。它继续为大端目标生成矢量长度不可知的代码,就像以前的版本对所有目标所做的那样。
向量化器现在可以使用扩展加载和截断存储,包括聚集加载和分散存储。
向量化器现在比较使用SVE和Advanced SIMD进行矢量化的成本,并尝试选择最好的。以前,如果可能的话,它总是使用SVE。
如果向量循环使用Advanced SIMD而不是SVE,那么向量化器现在会考虑使用SVE来向量化剩余元素(“标量尾”或“尾部”)。
除了这些特定点之外,向量化器使用SVE的方式还有许多一般性的改进。
mBranch-Protection=pac-ret选项现在接受可选的参数+b-key扩展,以使用B-key而不是A-key执行返回地址签名。
添加了选项-mOutline-Atomics,以帮助在GNU/Linux系统上部署大型系统扩展(LSE),该系统以面向ARMv8-A的基准架构构建。当指定该选项时,将发出代码以在运行时检测LSE指令的存在,并将其用于标准原子操作。有关详细信息,请参阅文档。
现在通过ALE内部功能支持事务性内存扩展。它可以通过+tme选项扩展来启用(例如,-march=armv8.5-a+tme)。
Armv8.5-A中的许多功能现在通过Acle内部功能得到支持。其中包括:可通过(GCC 9.1中已有)+RNG选项扩展启用的随机数指令。
类似地,下面的Armv8.6-A特性现在通过Acle内部功能得到支持:bfloat16扩展。当选择Armv8.6-A时,该扩展会自动启用(例如by-march=armv8.6-a)。还可以使用+bf16选项扩展为Armv8.2-A及更高版本启用它。
矩阵乘法扩展。此扩展分为三个部分,每个部分对应于每种支持的数据类型:支持8位整数矩阵乘法指令。选择Armv8.6-A时,此扩展会自动启用。也可以使用+i8 mm选项扩展为Armv8.2-A和更高版本启用。
支持32位浮点矩阵乘法指令。可以使用+f32 mm选项扩展来启用此扩展,这也具有启用SVE的效果。
支持64位浮点矩阵乘法指令。可以使用+f64 mm选项扩展来启用此扩展,这同样具有启用SVE的效果。
SVE2现在通过ACLE内部功能和(在有限范围内)自动矢量化来支持。它可以通过+sve2选项扩展来启用(例如,-march=armv8.5-a+sve2)。可以通过+sve2-sm4、+sve2-aes、+sve2-sha3和+sve2-bitperm启用其他扩展。
添加了对以下处理器的支持(括号中的GCC标识符):GCC标识符可以用作-mcpu或-mtune选项的参数,例如:-mcpu=corest-a77或-mtune=cortical-a65ae或用作等效目标属性和编译指示的参数。
添加了对FDPIC ABI的支持。它使用64位函数描述符来表示指向函数的指针,并在无MMU的系统上实现代码共享。对应的目标三元组是arm-uclinuxfdpiceabi,C库是uclibc-ng。
在使用64位整数数据类型时,对64位整数操作的处理进行了显着的修改和改进,从而提高了性能并减少了堆栈使用量。选项-mneon-for-64位现在已弃用,并将在将来的版本中删除。
添加了对以下处理器的支持(括号中的GCC标识符):GCC标识符可以用作-mcpu或-mtune选项的参数,例如:-mcpu=corest-a77或-mtune=cortical-m35p。
对ALE数据处理内部功能的支持已经扩展到包括32位SIMD、饱和算术、16位乘法和其他旨在优化DSP算法的相关内部功能。
在Thumb-1(V6m)中添加了对-mpury-code的支持:此M-profile功能不再局限于具有movt的目标。例如,-mcpu=corcorp-m0现在支持此选项。
添加了对MVE测试版Acle内部特性的支持。可以通过包括arm_mve.h头文件并传递+mve或+mve.fp选项扩展名来启用这些内部功能(例如:-march=armv8.1-m.main+mve)。
中断服务例程功能保存所有使用的寄存器,包括零开销环路使用的扩展寄存器和辅助寄存器。
通过使用多条短指令提高代码大小。
..