我正在尝试使用x86进行简单的寄存器分配。我使用线性寄存器分配器,但我对一些简单的事情有一些问题,我没有找到有关的信息。
int main()
{
int a, b, c;
a = 10;
b = 20;
c = 2;
a = a + b;
b = b * 5;
c = c * b + a;
return c;
}
对于这个简单的代码,忽略常量传播,g ++& msvc生成类似的代码,它将所有临时代码推送到堆栈上,然后仅对ALU操作使用eax,ebx等。 Clang使用O0生成以下代码。
main: # @main
movl $0, -4(%rsp)
movl $10, -8(%rsp)
movl $20, -12(%rsp)
movl $2, -16(%rsp)
movl -8(%rsp), %eax
addl -12(%rsp), %eax
movl %eax, -8(%rsp)
imull $5, -12(%rsp), %eax
movl %eax, -12(%rsp)
movl -16(%rsp), %eax
imull -12(%rsp), %eax
addl -8(%rsp), %eax
movl %eax, -16(%rsp)
movl -16(%rsp), %eax
ret
很明显,所有临时工作都在堆叠中。所以我的问题是基于同样的事情。 在任何时候,如果在add / mul / div操作等中使用的eax / ebx等中的任何内容都有超过1条指令的生命周期。也就是说,如果任何有效范围间隔的值都存储在这些寄存器中,或者一旦完成寄存器分配并将它们的值推送到临时值,它们是否应该被逐出?
或者我们可以使用其中一些寄存器,直到遇到下一条ALU指令,并在必要时进行延迟推送?