gpt4 book ai didi

c++ - 寄存器分配算法

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:10:13 25 4
gpt4 key购买 nike

我正在尝试为树实现一个代码生成/寄存器分配算法以支持我的旧算法,我将所有东西都放在堆栈上。现在我正在尝试实现 Sethi-Ullman algorithm但仅从我在维基百科和一些网页上找到的内容来看,算法的某些部分对我来说仍然不清楚。

我正在寻找一些伪代码/C/C++ 工作代码中缺少的部分的解释。

1)选择免费注册应该用什么方法?即,正在使用的寄存器堆栈。我正在使用我认为非常差的一个:交替返回寄存器:如果以前使用的寄存器是 R0,则返回 R1。如果是 R1,则返回 R0,依此类推。它不适用于小表达式。

2) label(left) >= K and label(right) >= K 时怎么办?

这是 labelsethi-ullman 函数

REG reg()
{
static REG r = REG_NONE;

switch(r) {
case REG_NONE:
r = REG_r0;
break;
case REG_r0:
r = REG_r1;
break;
case REG_r1:
r = REG_r0;
break;
default:
assert(0);
break;
}
return r;
}

void SethiUllman(AST *node)
{
static const int K = 2;

if(node->left != NULL && node->right != NULL) {
int l = node->left->n;
int r = node->right->n;

if(l >= K && r >= K) {
SethiUllman(node->right);
node->n = node->n - 1;
//emit(node->right, REG_r0);
SethiUllman(node->left);
//emit(node->left, REG_r1);
}
else if(l >= r) {
SethiUllman(node->left);
SethiUllman(node->right);
node->n = node->n - 1;
}
else if(l < r) {
SethiUllman(node->right);
SethiUllman(node->left);
node->n = node->n - 1;
}

node->reg = reg();

printf("%s %s,%s\n",
op_string(node->type),
reg_string(node->left->reg),
reg_string(node->right->reg));

}
else if(node->type == TYPE::id) {
node->n = node->n + 1;
node->reg = reg();
emit(node);
}
else {
node->reg = reg();
emit(node);
}
}

void label(AST *node)
{
if(node == NULL)
return;

label(node->left);
label(node->right);

if(node->left != NULL && node->right != NULL) {
int l = node->left->n;
int r = node->right->n;
if(l == r)
node->n = 1 + l;
else
node->n = max(1, l, r);
}
else if(node->type == TYPE::id) {
node->n = 1;
} else if(node->type == TYPE::number) {
node->n = 0;
}
}

对于像这样的 exp 的树:

2+b*3

它会产生:

LOAD R0,[b]
LOAD R1,3
MUL R0,R1
LOAD R1,2
ADD R1,R0

从这样的一个:

8+(2+b*3)

它会产生:

LOAD R0,[b]
LOAD R1,3
MUL R0,R1
LOAD R1,2
ADD R1,R0
LOAD R1,8 < R1 is not preserved. I don't know how it should be done.
ADD R0,R1

上面我只提供了主要算法,但如果需要,我可以在您的机器上提供完整的测试用例代码。

最佳答案

我不太明白为什么 8+(2+b*3) 表达式不只是“工作”,因为对我来说,表达式不应该需要超过 2 个寄存器在计算中。但是,如果您不能在两个寄存器中执行整个计算,那么您需要进行“溢出”——将寄存器存储在临时(堆栈)位置,然后在您再次需要时从该临时位置恢复值。

这是您发布的代码:

LOAD R0,[b]
LOAD R1,3
MUL R0,R1 ; R0 = b*3
LOAD R1,2
ADD R1,R0 ; R1 = 2+(b*3)
LOAD R1,8 < R1 is not preserved. I don't know how it should be done.
ADD R0,R1

我们可以重写它,使用溢出:

LOAD R0,[b]
LOAD R1,3
MUL R0,R1 ; R0 = b*3
LOAD R1,2
ADD R1,R0 ; R1 = 2+(b*3)
STORE R1, [tmp]
LOAD R1,8 < R1 is not preserved. I don't know how it should be done.
LOAD R0, [tmp]
ADD R0,R1

但是,可以做到不溢出,这表明您使用的实际算法是错误的:

LOAD R0,[b]
LOAD R1,3
MUL R0,R1 ; R0 = b*3
LOAD R1,2
ADD R0,R1 ; R0 = 2+(b*3)
LOAD R1,8 ; Use R0 above -> R1 is now free.
ADD R0,R1

或者,同样地:

LOAD R0,[b]
LOAD R1,3
MUL R0,R1 ; R0 = b*3
LOAD R1,2
ADD R1,R0 ; R1 = 2+(b*3)
LOAD R0,8 ; Store in R1 above -> R0 is now free.
ADD R0,R1

我不确定,但我认为这很可能是您选择第一个 ADD 指令的左/右操作数的方式。

我会在代码后面添加一些打印输出,看看它在不同情况下的作用。

关于c++ - 寄存器分配算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23401809/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com