Compiler construction 如何处理多个溢出值作为单个指令的操作数?

Compiler construction 如何处理多个溢出值作为单个指令的操作数?,compiler-construction,register-allocation,Compiler Construction,Register Allocation,我想实施这个计划。它非常简单,为每个活动间隔分配寄存器或堆栈位置 当已分配寄存器的活动间隔数等于寄存器数时(即不再有空闲寄存器),堆栈位置仅分配给间隔 算法: 假设一条x86指令添加a,b,其中a和b都是通过该算法分配堆栈位置(溢出)的变量。无法使用两个内存操作数对此指令进行编码,因此寄存器中必须至少有一个操作数。我会在指令前插入一个mov REG,一个,但据我所知,在代码的这一点上没有空闲寄存器。这通常是如何解决的?根据这一点(在第7节中),线性扫描寄存器分配算法需要保留一个暂存寄存器 这对

我想实施这个计划。它非常简单,为每个活动间隔分配寄存器或堆栈位置

当已分配寄存器的活动间隔数等于寄存器数时(即不再有空闲寄存器),堆栈位置仅分配给间隔

算法:

假设一条x86指令
添加a,b
,其中
a
b
都是通过该算法分配堆栈位置(溢出)的变量。无法使用两个内存操作数对此指令进行编码,因此寄存器中必须至少有一个操作数。我会在指令前插入一个
mov REG,一个
,但据我所知,在代码的这一点上没有空闲寄存器。这通常是如何解决的?

根据这一点(在第7节中),线性扫描寄存器分配算法需要保留一个暂存寄存器

这对寄存器较少的体系结构(如英特尔IA-32体系结构)有负面影响,因为它增加了寄存器压力。特别是,如果不保留暂存寄存器,则无法实现该算法:当要求寄存器中的操作数的指令使用溢出的间隔时,必须将该间隔临时重新加载到暂存寄存器

假设您有以下程序集和3个寄存器:

mov t1, 1
mov t2, 2
mov t3, 3
mov t4, 4
mov t5, 5
add t4, t5
push t1
push t2
push t3
push t4
push t5
您将分配前两个寄存器(保留第三个用于溢出):

似乎有一种不需要临时寄存器的替代方法,称为拆分,但我尚未对此进行研究,但前面的文章对此进行了描述

另一个想法是使用一种不同的算法,使用溢出生成的新指令重新运行自身,并使用溢出启发式算法将溢出更长的范围,这样溢出生成的新临时值就不会再次溢出

mov r1, 1
mov r2, 2
mov r3, 3
mov [sp + 4], r3
mov r3, 4
mov [sp + 8], r3
mov r3, 5
mov [sp + 12], r3
mov r3, [sp + 8]
add r3, [sp + 12]
push r1
push r2
mov r3, [sp + 4]
push r3
mov r3, [sp + 8]
push r3
mov r3, [sp + 12]
push r3