您的位置:首页 > 其它

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

2007-07-04 21:16 344 查看
在代码生成的函数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行里调用的。在那个函数里计算着怎么样分配一个寄存器。下次再接着分析。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: