有一个功能
int foo(int num) {
if(num)
return 1;
else
return 3;
}
我理解没有优化的输出:
foo(int):
pushq %rbp
movq %rsp, %rbp
movl %edi, -4(%rbp)
cmpl $0, -4(%rbp)
je .L2
movl $1, %eax
jmp .L3
.L2:
movl $3, %eax
.L3:
popq %rbp
ret
但目前还不清楚 O2 发生了什么:
foo(int):
cmpl $1, %edi
sbbl %eax, %eax
andl $2, %eax
addl $1, %eax
ret
为什么要使用 SubBtract 和 Borrow ......此外,如果你用 return 2 替换 return 3 的返回值,那么总的来说,奇怪的是一切都解决了
foo(int):
xorl %eax, %eax
testl %edi, %edi
sete %al
addl $1, %eax
ret
澄清一点优化的地方......否则我无法以任何方式输入一些东西
编译器不需要生成可理解和/或易于理解的代码。另一方面,如果您在一张纸上对所有输入和输出进行所有计算,那么函数的逻辑将完全相同:
在第二种情况下,一切都更简单,您可以用示例性 C 伪代码重写它:
这些优化的想法是摆脱条件分支指令,在现代(i586+)CPU 上,如果预测块没有正确猜测,会导致管道重置,从而显着减慢计算速度。
如果您在函数中尝试使用不同的常量作为返回值
那么您可以看到,在模式下的一般情况下,
-O2编译器选择以下方法作为计算结果的最佳策略组合
它只不过是一种计算运算符值的有效方法
?:。进一步的代码与上面的代码基本对应。在返回的常量相差不超过 1 的情况下,编译器会选择不同的方法 - through
sete。