如何让Clang高效优化该准叶子函数?
如何让Clang高效编译准叶子函数?
我们来看下面这个准叶子函数:
int almost_leaf(int* x) { if (__builtin_expect(*x >= 0, true)) { return *x; } return x_was_negative() + 1; }
它被称为准叶子函数的原因是:它并非严格意义上的叶子函数——当x指向负数时会调用x_was_negative(),但__builtin_expect已向编译器提示:return *x是执行概率更高的路径,而这个路径不会触发任何函数调用。
Clang 16对它的编译结果如下:
almost_leaf(int*): # @almost_leaf(int*) push rax mov eax, dword ptr [rdi] test eax, eax js .LBB0_1 pop rcx ret .LBB0_1: call x_was_negative() inc eax pop rcx ret
可以看到,快速(预期)路径里的push和pop操作完全多余:这个路径既没有使用栈,也不存在需要对齐栈的函数调用。
相比之下,GCC的编译方式更高效——仅在调用x_was_negative()的慢路径上做栈对齐:
almost_leaf(int*): mov eax, DWORD PTR [rdi] test eax, eax js .L8 ret .L8: sub rsp, 8 call x_was_negative() add rsp, 8 inc eax ret
那么,如何让Clang也能高效编译这类准叶子函数?
注意:Clang其实具备不对准栈编译准叶子函数的能力——比如当x是int而非int*时,或者当x_was_negative()可以被编译为尾调用时(这种情况甚至完全不需要栈对齐)。
内容的提问来源于stack exchange,提问作者BeeOnRope
相关产品推荐
相关产品推荐

