连接器如何应对快速返回的功能?

mab*_*ham 6 c linker micro-optimization lto

在C中,如果我有一个看起来像的函数调用

// main.c
...
do_work_on_object(object, arg1, arg2);
...

// object.c
void do_work_on_object(struct object_t *object, int arg1, int arg2)
{
  if(object == NULL)
  {
    return;
  }
  // do lots of work
}
Run Code Online (Sandbox Code Playgroud)

那么编译器会在main.o中生成很多东西来保存状态,传递参数(在这种情况下希望在寄存器中),以及恢复状态.

但是,在链接时可以观察到arg1和arg2没有用在快速返回路径中,因此清理和状态恢复可以短路.链接器是否会自动执行此类操作,或者是否需要启用链接时优化(LTO)才能使此类工作正常工作?

(是的,我可以检查反汇编代码,但我对编译器和链接器的行为以及多种体系结构感兴趣,所以希望从别人的经验中学习.)

假设分析显示此函数调用值得优化,我们是否应该期望以下代码明显更快(例如,无需使用LTO)?

// main.c
...
if(object != NULL)
{
  do_work_on_object(object, arg1, arg2);
}
...

// object.c
void do_work_on_object(struct object_t *object, int arg1, int arg2)
{
  assert(object != NULL) // generates no code in release build
  // do lots of work
}
Run Code Online (Sandbox Code Playgroud)

Cri*_*tik 0

设置或清理状态代码都不能短路,因为生成的编译代码是静态的,它不知道程序执行时会发生什么。因此编译器总是必须设置整个参数堆栈。

考虑两种情况:一种objectnil,另一种不是。汇编代码如何知道是否将参数的其余部分放入堆栈?特别是因为调用者负责将参数放置在正确的位置(堆栈或注册表)。

  • LLVM 指出这是他们希望改进的一个领域:http://llvm.org/OpenProjects.html#codegen (2认同)