📄 dag.c
字号:
if (tp->u.sym->generated)
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: assert(IR->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 + -