从这个问题开始:how-do-i-check-if-gcc-is-performing-tail-recursion-optimization,我注意到使用 gcc 和 -fPIC 似乎破坏了这种优化。我正在创建一个共享库,但我似乎不需要 -fPIC 选项。
好吧,我的问题是,为什么 -fPIC 会改变 gcc 优化?我是否需要出于任何原因保留 -fPIC ?
从这个问题开始:how-do-i-check-if-gcc-is-performing-tail-recursion-optimization,我注意到使用 gcc 和 -fPIC 似乎破坏了这种优化。我正在创建一个共享库,但我似乎不需要 -fPIC 选项。
好吧,我的问题是,为什么 -fPIC 会改变 gcc 优化?我是否需要出于任何原因保留 -fPIC ?
在没有目标架构和编译器版本等细节的情况下,一个可能的解释是:
在位置相关代码中,尾递归优化本质上是重用当前栈帧,并将考虑call
的栈帧替换为jump
. 语法可以call function
替换为jmp <small offset of function>
.
call function@PLT
在与位置无关的代码中,如果指令集允许,可以编写调用(此示例为 amd64)。它完全可以被 替换jmp <small offset of function>@PLT
,但是这两个设置确实会干扰,也许 gcc 开发人员没有解决在后一种模式下实现尾调用优化的问题。
在 ia32 linux 中,使用 fpic 意味着您没有可用于通用用途的 ebx,这肯定会影响优化。由于寄存器调度压力,编译器可能决定反对尾递归优化。