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里调用的,接着来分析这个函数的代码,如下:
#001Node gen(Node forest) {
#002int i;
#003struct node sentinel;
#004Node dummy, p;
#005
#006head = forest;
#007for (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}
#019for (p = forest; p; p = p->link)
#020 prune(p, &dummy);
#021relink(&sentinel, &sentinel);
#022for (p = forest; p; p = p->link)
#023 linearize(p, &sentinel);
#024forest = sentinel.x.next;
#025assert(forest);
#026sentinel.x.next->x.prev = NULL;
#027sentinel.x.prev->x.next = NULL;
#028for (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 }
#037for (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}
#045return forest;
#046}
其它的代码后面再分析,现在只关心寄存器分配的函数ralloc,它是在第38行里调用的。在那个函数里计算着怎么样分配一个寄存器。下次再接着分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值