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)
设置或清理状态代码都不能短路,因为生成的编译代码是静态的,它不知道程序执行时会发生什么。因此编译器总是必须设置整个参数堆栈。
考虑两种情况:一种object是nil,另一种不是。汇编代码如何知道是否将参数的其余部分放入堆栈?特别是因为调用者负责将参数放置在正确的位置(堆栈或注册表)。