📄 dag.c
字号:
if (tp->u.sym->temporary) addlocal(tp->u.sym); p = node(tp->op + sizeop(voidptype->size), NULL, NULL, tp->u.sym); } break; default:assert(0); } tp->node = p; return p;}static void list(Node p) { if (p && p->link == NULL) { if (forest) { p->link = forest->link; forest->link = p; } else p->link = p; forest = p; }}static void labelnode(int lab) { assert(lab); if (forest && forest->op == LABEL+V) equatelab(findlabel(lab), forest->syms[0]); else list(newnode(LABEL+V, NULL, NULL, findlabel(lab))); reset();}static void unlist(void) { Node p; assert(forest); assert(forest != forest->link); p = forest->link; while (p->link != forest) p = p->link; p->link = forest->link; forest = p;}Tree cvtconst(Tree p) { Symbol q = constant(p->type, p->u.v); Tree e; if (q->u.c.loc == NULL) q->u.c.loc = genident(STATIC, p->type, GLOBAL); if (isarray(p->type)) { e = simplify(ADDRG, atop(p->type), NULL, NULL); e->u.sym = q->u.c.loc; } else e = idtree(q->u.c.loc); return e;}void gencode(Symbol caller[], Symbol callee[]) { Code cp; Coordinate save; if (prunetemps == -1) prunetemps = !IR->wants_dag; save = src; if (assignargs) { int i; Symbol p, q; cp = codehead.next->next; codelist = codehead.next; for (i = 0; (p = callee[i]) != NULL && (q = caller[i]) != NULL; i++) if (p->sclass != q->sclass || p->type != q->type) walk(asgn(p, idtree(q)), 0, 0); codelist->next = cp; cp->prev = codelist; } if (glevel && IR->stabsym) { int i; Symbol p, q; for (i = 0; (p = callee[i]) != NULL && (q = caller[i]) != NULL; i++) { (*IR->stabsym)(p); if (p->sclass != q->sclass || p->type != q->type) (*IR->stabsym)(q); } swtoseg(CODE); } cp = codehead.next; for ( ; errcnt <= 0 && cp; cp = cp->next) switch (cp->kind) { case Address: (*IR->address)(cp->u.addr.sym, cp->u.addr.base, cp->u.addr.offset); break; case Blockbeg: { Symbol *p = cp->u.block.locals; (*IR->blockbeg)(&cp->u.block.x); for ( ; *p; p++) if ((*p)->ref != 0.0) (*IR->local)(*p); else if (glevel) (*IR->local)(*p); } break; case Blockend: (*IR->blockend)(&cp->u.begin->u.block.x); break; case Defpoint: src = cp->u.point.src; break; case Gen: case Jump: case Label: if (prunetemps) cp->u.forest = prune(cp->u.forest); fixup(cp->u.forest); cp->u.forest = (*IR->gen)(cp->u.forest); break; case Local: (*IR->local)(cp->u.var); break; case Switch: break; default: assert(0); } src = save;}static void fixup(Node p) { for ( ; p; p = p->link) switch (generic(p->op)) { case JUMP: if (specific(p->kids[0]->op) == ADDRG+P) p->kids[0]->syms[0] = equated(p->kids[0]->syms[0]); break; case LABEL: assert(p->syms[0] == equated(p->syms[0])); break; case EQ: case GE: case GT: case LE: case LT: case NE: assert(p->syms[0]); p->syms[0] = equated(p->syms[0]); }}static Symbol equated(Symbol p) { { Symbol q; for (q = p->u.l.equatedto; q; q = q->u.l.equatedto) assert(p != q); } while (p->u.l.equatedto) p = p->u.l.equatedto; return p;}void emitcode(void) { Code cp; Coordinate save; save = src; cp = codehead.next; for ( ; errcnt <= 0 && cp; cp = cp->next) switch (cp->kind) { case Address: break; case Blockbeg: if (glevel && IR->stabblock) { (*IR->stabblock)('{', cp->u.block.level - LOCAL, cp->u.block.locals); swtoseg(CODE); } break; case Blockend: if (glevel && IR->stabblock) { Code bp = cp->u.begin; foreach(bp->u.block.identifiers, bp->u.block.level, typestab, NULL); foreach(bp->u.block.types, bp->u.block.level, typestab, NULL); (*IR->stabblock)('}', bp->u.block.level - LOCAL, bp->u.block.locals); swtoseg(CODE); } break; case Defpoint: src = cp->u.point.src; if (glevel > 0 && IR->stabline) { (*IR->stabline)(&cp->u.point.src); swtoseg(CODE); } break; case Gen: case Jump: case Label: if (cp->u.forest) (*IR->emit)(cp->u.forest); break; case Local: if (glevel && IR->stabsym) { (*IR->stabsym)(cp->u.var); swtoseg(CODE); } break; case Switch: { int i; defglobal(cp->u.swtch.table, LIT); (*IR->defaddress)(equated(cp->u.swtch.labels[0])); for (i = 1; i < cp->u.swtch.size; i++) { long k = cp->u.swtch.values[i-1]; while (++k < cp->u.swtch.values[i]) assert(k < LONG_MAX), (*IR->defaddress)(equated(cp->u.swtch.deflab)); (*IR->defaddress)(equated(cp->u.swtch.labels[i])); } swtoseg(CODE); } break; default: assert(0); } src = save;}static Node undag(Node forest) { Node p; tail = &forest; for (p = forest; p; p = p->link) if (generic(p->op) == INDIR) { assert(p->count >= 1); visit(p, 1); if (p->syms[2]) { assert(p->syms[2]->u.t.cse); p->syms[2]->u.t.cse = NULL; addlocal(p->syms[2]); } } else if (iscall(p->op) && p->count >= 1) visit(p, 1); else { assert(p->count == 0), visit(p, 1); *tail = p; tail = &p->link; } *tail = NULL; return forest;}static Node replace(Node p) { if (p && ( generic(p->op) == INDIR && generic(p->kids[0]->op) == ADDRL && p->kids[0]->syms[0]->temporary && p->kids[0]->syms[0]->u.t.replace)) { p = p->kids[0]->syms[0]->u.t.cse; if (generic(p->op) == INDIR && isaddrop(p->kids[0]->op)) p = newnode(p->op, newnode(p->kids[0]->op, NULL, NULL, p->kids[0]->syms[0]), NULL, NULL); else if (generic(p->op) == ADDRG) p = newnode(p->op, NULL, NULL, p->syms[0]); else assert(0); p->count = 1; } else if (p) { p->kids[0] = replace(p->kids[0]); p->kids[1] = replace(p->kids[1]); } return p;}static Node prune(Node forest) { Node p, *tail = &forest; int count = 0; for (p = forest; p; p = p->link) { if (count > 0) { p->kids[0] = replace(p->kids[0]); p->kids[1] = replace(p->kids[1]); } if (( generic(p->op) == ASGN && generic(p->kids[0]->op) == ADDRL && p->kids[0]->syms[0]->temporary && p->kids[0]->syms[0]->u.t.cse == p->kids[1])) { Symbol tmp = p->kids[0]->syms[0]; if (!tmp->defined) (*IR->local)(tmp); tmp->defined = 1; if (( generic(p->kids[1]->op) == INDIR && isaddrop(p->kids[1]->kids[0]->op) && p->kids[1]->kids[0]->syms[0]->sclass == REGISTER) || (( generic(p->kids[1]->op) == INDIR && isaddrop(p->kids[1]->kids[0]->op)) && tmp->sclass == AUTO) || (generic(p->kids[1]->op) == ADDRG && tmp->sclass == AUTO)) { tmp->u.t.replace = 1; count++; continue; /* and omit the assignment */ } } /* keep the assignment and other roots */ *tail = p; tail = &(*tail)->link; } assert(*tail == NULL); return forest;}static Node visit(Node p, int listed) { if (p) if (p->syms[2]) p = tmpnode(p); else if (p->count <= 1 && !iscall(p->op) || p->count == 0 && iscall(p->op)) { p->kids[0] = visit(p->kids[0], 0); p->kids[1] = visit(p->kids[1], 0); } else if (specific(p->op) == ADDRL+P || specific(p->op) == ADDRF+P) { assert(!listed); p = newnode(p->op, NULL, NULL, p->syms[0]); p->count = 1; } else if (p->op == INDIR+B) { p = newnode(p->op, p->kids[0], NULL, NULL); p->count = 1; p->kids[0] = visit(p->kids[0], 0); p->kids[1] = visit(p->kids[1], 0); } else { p->kids[0] = visit(p->kids[0], 0); p->kids[1] = visit(p->kids[1], 0); p->syms[2] = temporary(REGISTER, btot(p->op, opsize(p->op))); assert(!p->syms[2]->defined); p->syms[2]->ref = 1; p->syms[2]->u.t.cse = p; *tail = asgnnode(p->syms[2], p); tail = &(*tail)->link; if (!listed) p = tmpnode(p); }; return p;}static Node tmpnode(Node p) { Symbol tmp = p->syms[2]; assert(tmp); if (--p->count == 0) p->syms[2] = NULL; p = newnode(INDIR + ttob(tmp->type), newnode(ADDRL + ttob(voidptype), NULL, NULL, tmp), NULL, NULL); p->count = 1; return p;}static Node asgnnode(Symbol tmp, Node p) { p = newnode(ASGN + ttob(tmp->type), newnode(ADDRL + ttob(voidptype), NULL, NULL, tmp), p, NULL); p->syms[0] = intconst(tmp->type->size); p->syms[1] = intconst(tmp->type->align); return p;}/* printdag - print dag p on fd, or the node list if p == 0 */void printdag(Node p, int fd) { FILE *f = fd == 1 ? stdout : stderr; printed(0); if (p == 0) { if ((p = forest) != NULL) do { p = p->link; printdag1(p, fd, 0); } while (p != forest); } else if (*printed(nodeid((Tree)p))) fprint(f, "node'%d printed above\n", nodeid((Tree)p)); else printdag1(p, fd, 0);}/* printdag1 - recursively print dag p */static void printdag1(Node p, int fd, int lev) { int id, i; if (p == 0 || *printed(id = nodeid((Tree)p))) return; *printed(id) = 1; for (i = 0; i < NELEMS(p->kids); i++) printdag1(p->kids[i], fd, lev + 1); printnode(p, fd, lev);}/* printnode - print fields of dag p */static void printnode(Node p, int fd, int lev) { if (p) { FILE *f = fd == 1 ? stdout : stderr; int i, id = nodeid((Tree)p); fprint(f, "%c%d%s", lev == 0 ? '\'' : '#', id, &" "[id < 10 ? 0 : id < 100 ? 1 : 2]); fprint(f, "%s count=%d", opname(p->op), p->count); for (i = 0; i < NELEMS(p->kids) && p->kids[i]; i++) fprint(f, " #%d", nodeid((Tree)p->kids[i])); if (generic(p->op) == CALL && p->syms[0] && p->syms[0]->type) fprint(f, " {%t}", p->syms[0]->type); else for (i = 0; i < NELEMS(p->syms) && p->syms[i]; i++) if (p->syms[i]->name) fprint(f, " %s", p->syms[i]->name); else fprint(f, " %p", p->syms[i]); fprint(f, "\n"); }}/* typestab - emit stab entries for p */static void typestab(Symbol p, void *cl) { if (!isfunc(p->type) && (p->sclass == EXTERN || p->sclass == STATIC) && IR->stabsym) (*IR->stabsym)(p); else if ((p->sclass == TYPEDEF || p->sclass == 0) && IR->stabtype) (*IR->stabtype)(p);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -