LCC编译器的源程序分析(50) 分配一个寄存器

本文分析了一段关于代码生成过程中寄存器分配的实现细节,包括如何为临时变量分配寄存器,以及相关的函数调用流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在代码生成的函数gencode里,需要产生寄存器给临时变量使用。下面就来分析这段代码,如下:
#056          case Gen: case Jump:
#057          case Label:   
#058                if (prunetemps)
#059                     cp->u.forest = prune(cp->u.forest);
#060                fixup(cp->u.forest);
#061                cp->u.forest = (*IR->gen)(cp->u.forest); break;
当代码表里的代码类型是Gen时就会运行上面的代码。寄存器分配是在函数IR->gen里调用的,接着来分析这个函数的代码,如下:
#001 Node gen(Node forest) {
#002  int i;
#003  struct node sentinel;
#004  Node dummy, p;
#005 
#006  head = forest;
#007  for (p = forest; p; p = p->link) {
#008         assert(p->count == 0);
#009         if (generic(p->op) == CALL)
#010               docall(p);
#011         else if (   generic(p->op) == ASGN
#012         && generic(p->kids[1]->op) == CALL)
#013               docall(p->kids[1]);
#014         else if (generic(p->op) == ARG)
#015               (*IR->x.doarg)(p);
#016         rewrite(p);
#017         p->x.listed = 1;
#018  }
#019  for (p = forest; p; p = p->link)
#020         prune(p, &dummy);
#021  relink(&sentinel, &sentinel);
#022  for (p = forest; p; p = p->link)
#023         linearize(p, &sentinel);
#024  forest = sentinel.x.next;
#025  assert(forest);
#026  sentinel.x.next->x.prev = NULL;
#027  sentinel.x.prev->x.next = NULL;
#028  for (p = forest; p; p = p->x.next)
#029         for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) {
#030               assert(p->x.kids[i]->syms[RX]);
#031               if (p->x.kids[i]->syms[RX]->temporary) {
#032                    p->x.kids[i]->x.prevuse =
#033                          p->x.kids[i]->syms[RX]->x.lastuse;
#034                    p->x.kids[i]->syms[RX]->x.lastuse = p->x.kids[i];
#035               }
#036         }
#037  for (p = forest; p; p = p->x.next) {
#038         ralloc(p);
#039         if (p->x.listed && NeedsReg[opindex(p->op)]
#040         && (*IR->x.rmap)(opkind(p->op))) {
#041               assert(generic(p->op) == CALL || generic(p->op) == LOAD);
#042               putreg(p->syms[RX]);
#043         }
#044  }
#045  return forest;
#046 }
其它的代码后面再分析,现在只关心寄存器分配的函数ralloc,它是在第38行里调用的。在那个函数里计算着怎么样分配一个寄存器。下次再接着分析。
 
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

caimouse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值