2013-03-01 81 views
23

只是好奇,GCC或Clang工具集目前是否实现了MSVC的identical COMDAT folding(ICF)的等价物?如果不是,有没有计划?除了旧的GCC邮件列表消息外,我似乎无法找到有关此主题的最新权威链接。GCC(/ Clang):使用相同指令合并函数(COMDAT折叠)

如果不是,这是否意味着对于不同类型的模板实例在结果二进制文件中(即它们没有完全内联的情况下)通常是不同的函数,即使它们是二进制兼容的,在其他层面处理这个问题?

另外,是否有人发现ICF在最小化实际生成的可执行文件的大小方面有很大的不同?我没有任何大的MSVC项目可以方便地进行测试。 (我猜这只是真的有帮助,如果你碰巧通过许多不同的vtable-layout兼容类型实例化模板)。

最后,它是C++ 11标准兼容的两个函数指针,以不同的函数比较相等在运行时? This link似乎暗示它不是,但它是为C99。编辑:found previous question on this topic

+1

找到[MSFT的Larry Osterman引用](http://blogs.msdn.com/b/oldnewthing/archive/2005/03/22/400373.aspx):“这个特性[ICF]是什么使得C++模板是应用程序的可行解决方案...否则,模板会导致代码大小的充分膨胀,以至于它们几乎无法用于生产软件。“......好奇GCC/Clang如果不执行此操作,该如何处理 – 2013-03-02 00:09:03

+3

他们确实很顺利,很多软件都使用标准库中的模板,所以显然不是模板“几乎不可用” – 2013-03-02 00:12:34

+0

@JonathanWakely哈,我喜欢GCC,这只是他的引用:) – 2013-03-02 00:16:04

回答

16

GCC和Clang都不是链接器,并且ICF需要由链接器完成,或者至少与链接器进行合作。编辑: 他们不做ICF,所以是的,不同的实例产生不同的代码。 GNU gold链接器支持ICF和--icf选项,该选项需要使用GCC选项-ffunction-sections

不同的函数必须有不同的地址......我不记得ICF是否对任何有地址的函数禁用,但如果不是这样,应该可以在组合之前加载一个非操作指令函数,并使每个不同的实例在不同的指令上开始,因此它们具有不同的地址。编辑:黄金的--icf=safe选项只启用ICF的功能,可以证明没有他们的地址,所以依赖于不同地址的代码仍然可以工作。

ICF是一个整洁的优化,但不是必需的。通过一点努力,您可以将非相关代码提取到非模板或具有较少参数的模板,以减少可执行文件中重复代码的数量。关于这一点,我在几年前做了一次Diet Templates的演讲。

+0

对不起,我意识到我有点松散的术语......我应该怎么称呼这个链接器 - 通常打包的,但是与GCC-on-linux-x86/64? (它是特定于平台的,对吧?) – 2013-03-02 00:20:32

+1

这个链接器通常被称为“GNU ld”或者GNU链接器,整套工具通常被称为GNU工具链(意思是GCC,GNU as,GNU ld,有时包括GNU libc中)。连接器通常是操作系统的一部分,例如Solaris有自己的链接器,但GNU链接器是跨平台的,支持很多可执行格式并可以在很多不同的操作系统上运行,所以例如Solaris上的GCC可以配置为使用本地Solaris链接器或GNU链接器。 – 2013-03-02 00:24:59

+0

感谢您的澄清。铛仍默认使用GNU ID,对吧?实际上,我想这取决于你的配置,好像他们也有自己的配置。 – 2013-03-02 00:28:27