GCC(/ Clang):合并具有相同指令的函数(COMDAT折叠) [英] GCC(/Clang): Merging functions with identical instructions (COMDAT folding)

查看:1171
本文介绍了GCC(/ Clang):合并具有相同指令的函数(COMDAT折叠)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只是好奇,GCC或Clang工具集实现了等同于MSVC的相同的COMDAT折叠(ICF)目前?如果没有,有没有计划?



如果没有,这是否意味着不同类型的模板实例化(即使它们是二进制兼容的,或者是否有其他机制在其他级别处理这个函数)?



此外,有没有人发现ICF在最小化生成的可执行文件的大小在实践中有很大的区别?我没有任何大的MSVC项目方便地测试出来。 (我想如果你碰巧在许多不同的vtable-layout兼容类型实例化模板真的有帮助。)



最后,是C ++ 11标准 - 兼容两个函数指针到不同的函数在运行时比较相等? 此链接似乎意味着它不是,但它是为C99。编辑:在上一个问题上找到本主题

解决方案

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



不同的函数必须有不同的地址...我不记得如果ICF被禁用的任何函数,它的地址被采取,但如果不是,应该可以放置一个无操作指令之前组合函数并使每个不同的实例化在不同的指令上开始,因此它们具有不同的地址。编辑:gold的 - icf = safe 选项仅为可以证明不会占用地址的函数启用ICF,因此依赖于不同地址的代码仍然可以工作。 / p>

ICF是一个整洁的优化,但不是必需的。有点费力,您可以将非依赖代码提升到非模板或具有较少参数的模板,以减少可执行文件中重复代码的数量。有关饮食模板的幻灯片中有更多信息,我做了几个年前。


Just curious, do the GCC or Clang toolsets implement the equivalent of MSVC's identical COMDAT folding (ICF) currently? If not, are there any plans to? I can't seem to find any recent authoritative links on the subject other than old GCC mailing list messages.

If not, does this imply that template instantiations over distinct types are always distinct functions in the resulting binary (in situations where they are not completely inlined), even when they are binary-compatible, or are there other mechanisms in-place to handle this at some other level?

Also, has anyone found ICF making a big difference in minimizing the size of a resulting executable in practice? I don't have any large MSVC projects handy to test it out. (I'm guessing it only really helps if you happened to instantiate templates over many different vtable-layout compatible types.)

Finally, is it C++11 standards-compliant for two functions pointers to different functions to compare equal at runtime? This link seems to imply that it isn't, but it's for C99. EDIT: found previous question on this topic

解决方案

Neither GCC nor Clang is a linker, and ICF needs to be done by the linker, or at least with cooperation with the linker. Edit: They don't do ICF, so yes, distinct instantiations produce distinct code. The GNU gold linker supports ICF with the --icf option, which needs the GCC option -ffunction-sections to be used.

Distinct functions must have distinct addresses ... I can't remember if ICF is disabled for any function that has its address taken, but if not it should be possible to put a load of no-op instructions before the combined function and make each distinct instantiation start on a different instruction, so they have different addresses. Edit: gold's --icf=safe option only enables ICF for functions that can be proven not to have their address taken, so code that relies on distinct addresses will still work.

ICF is a neat optimization, but not essential. With a bit of effort you can hoist out non-dependent code to a non-template, or a template with fewer parameters, to reduce the quantity of duplicated code in the executable. There's more information on this in the slides for a Diet Templates talk I did a couple of years ago.

这篇关于GCC(/ Clang):合并具有相同指令的函数(COMDAT折叠)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆