【发布时间】:2011-07-01 19:16:56
【问题描述】:
我正在处理一些在编译为 PIC(位置无关代码)时会变慢 70-80% 的代码,并正在寻找缓解问题的方法。问题的很大一部分是 gcc 坚持在每个函数中插入以下内容:
call __i686.get_pc_thunk.bx
addl $_GLOBAL_OFFSET_TABLE_,%ebx
即使这最终是函数内容的 20%。现在,ebx 是一个保留调用的寄存器,相关翻译单元(源文件)中的每个 函数都在将 GOT 的地址加载到其中,很容易检测到 static不能从翻译单元外部调用函数(它们的地址永远不会被占用)。那么为什么 gcc 不能在大外部链接函数的开头加载一次ebx,并生成静态链接函数,以便它们假设ebx 已经加载了 GOT 的地址?是否有任何优化标志我可以用来强制 gcc 进行这种明显且大规模的优化,而不是将内联限制提高到天价,以便所有内容都内联到外部函数中?
【问题讨论】:
-
这看起来相关且令人失望:gcc.gnu.org/bugzilla/show_bug.cgi?id=23756
-
仅仅因为你的函数是静态的并不意味着它们不能作为函数指针传递给其他编译单元。我想知道添加 GOT 表是否真的会大大减慢这些功能。你真的介绍过它吗?如果是这样,那么这样短的函数是内联的好候选,这也节省了创建堆栈帧的开销。
-
@datenwolf:正如我在问题中所说,它们的地址永远不会被占用,因此它们不能作为函数指针传递。 gcc 已经对永远不能被外部调用的函数进行了一些优化(比如切换到寄存器传递)。
标签: c optimization gcc pic