📄 dag.c
字号:
if (tp->kids[0]->op != (CNST+P)) {
sym = tp->kids[0]->u.sym;
if (sym == NULL) {
if (tp->kids[0] && tp->kids[0]->kids[0])
sym = tp->kids[0]->kids[0]->u.sym;
}
}
else sym = NULL;
#if 1
if (sym && !sym->generated && sym->name) {
if (sym->scope == LOCAL &&
sym->sclass == AUTO &&
sym->type->op == POINTER &&
sym->assigned == 0) {
warning(StrTab[388],sym->name);// <possible usage of %s before definition\n>
sym->assigned = 1;
}
}
#endif
assert(tlab == 0 && flab == 0);
l = listnodes(tp->kids[0], 0, 0);
if (isptr(ty))
ty = unqual(ty)->type;
if (isvolatile(ty)
|| (isstruct(ty) && unqual(ty)->u.sym->u.s.vfields))
p = newnode(tp->op, l, NULL, NULL);
else
p = node(tp->op, l, NULL, NULL);
} break;
case FIELD:{
Tree q = shtree(RSH,
shtree(LSH, tp->kids[0],
consttree(fieldleft(tp->u.field), inttype)),
consttree(8 * tp->type->size - fieldsize(tp->u.field),
inttype));
assert(tlab == 0 && flab == 0);
p = listnodes(q, 0, 0);
} break;
case ADDRG:
case ADDRF:{
assert(tlab == 0 && flab == 0);
if (tp->op == ADDRGP &&
tp->u.sym->Flags == DLLIMPORTATTRIBUTE) {
p = node(INDIRP,
node(tp->op,NULL,NULL,tp->u.sym),
NULL,
NULL);
}
else
p = node(tp->op, NULL, NULL, tp->u.sym);
} break;
case ADDRL:{
assert(tlab == 0 && flab == 0);
if (tp->u.sym->temporary)
addlocal(tp->u.sym);
p = node(tp->op, 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 == LABELV)
equatelab(findlabel(lab), forest->syms[0]);
else
list(newnode(LABELV, 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 = tree(ADDRG + P, atop(p->type), NULL, NULL);
e->u.sym = q->u.c.loc;
}
else
e = idtree(q->u.c.loc);
return e;
}
extern void GenBlockDebugInfo(Code cp);
static char *nodeTypeTable[] = {
"if start",
"else",
"endif",
"for",
"end for",
"while",
"end while",
"do",
"end do",
"switch",
"end switch",
"case",
"break",
"goto",
"call",
"start function",
"end function",
"return",
"???",
"???(1)"
};
static void printNodeType(Code cp)
{
int i = cp->u.point.type;
int j=0;
if (i == 0) return;
while (i != 0) {
i = i >> 1;
j++;
}
if (j > 0)
j--;
fprintf(ilFile,"%70s\n", nodeTypeTable[j]);
}
void gencode(Symbol caller[],Symbol callee[])
{
Code cp;
Coordinate save;
save = src;
{
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) {
if (p->sclass == q->sclass && q->type->op == INT &&
p->type->op == ENUM)
;
else
if (p->sclass == q->sclass && q->type->op == INT &&
p->type->op == CHAR)
;
else
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 (1/*glevel*/)
(*IR->local) (*p);
}
if (glevel) GenBlockDebugInfo(cp);
}
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 (!IR->wants_dag)
cp->u.forest = undag(cp->u.forest);
fixup(cp->u.forest);
cp->u.forest = (*IR->gen) (cp->u.forest);
// AddCodeBlock(cp->kind,src,cp->u.forest);
break;
case Local:
(*IR->local) (cp->u.var);
break;
case Switch:
// AddCodeBlock(cp->kind,src,(Node)cp);
break;
#ifdef BUILTIN_ASM
case Start:
case Asm:
break;
#endif
default:
assert(0);
}
src = save;
}
static void fixup(Node p)
{
for (; p; p = p->link)
switch (generic(p->op)) {
case JUMP:
if (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]);
}
}
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) {
#ifdef BUILTIN_ASM
case Start:
break;
case Asm:
asmcode(cp->u.acode.code, cp->u.acode.argv);
break;
#endif
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, Dagtypestab, NULL);
foreach(bp->u.block.types, bp->u.block.level, Dagtypestab, NULL);
(*IR->stabblock) ('}', bp->u.block.level - LOCAL, bp->u.block.locals);
swtoseg(CODE);
}
break;
case Defpoint:
src = cp->u.point.src;
if (IntermediateLanguageFile) {
fprintf(ilFile,"; Line %d\n",src.y);
printNodeType(cp);
}
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;
int k = cp->u.swtch.values[0];
defglobal(cp->u.swtch.table, LIT);
for (i = 0; i < cp->u.swtch.size; i++, k++) {
for (; k < cp->u.swtch.values[i]; k++)
(*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
|| iscall(p) && p->count >= 1)
#ifndef NDEBUG
assert(p->count >= 1),
#endif
visit(p, 1);
else {
#ifndef NDEBUG
assert(p->count == 0),
#endif
visit(p, 1);
*tail = p;
tail = &p->link;
}
*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)
|| p->count == 0 && iscall(p)) {
p->kids[0] = visit(p->kids[0], 0);
p->kids[1] = visit(p->kids[1], 0);
}
else if (p->op == ADDRLP || p->op == ADDRFP ||
(OptimizeFlag && p->count == 2 && p->op == ADDRGP)) {
assert(!listed);
p = newnode(p->op, NULL, NULL, p->syms[0]);
p->count = 1;
}
else if (p->op == CNSTI /*|| p->op == CNSTD*/) {
assert(!listed);
p = newnode(p->op, NULL, NULL, p->syms[0]);
p->count = 1;
}
else if (generic(p->op) == INDIR && !listed
&& (p->kids[0]->op == ADDRLP || p->kids[0]->op == ADDRFP)
&& p->kids[0]->syms[0]->sclass == REGISTER) {
p = newnode(p->op, newnode(p->kids[0]->op, NULL, NULL,
p->kids[0]->syms[0]), NULL, NULL);
p->count = 1;
}
else if (p->op == LSHI && !listed
&& (p->kids[0]->op == INDIRI || p->kids[0]->op == INDIRP)
&& p->kids[1]->op == CNSTI &&
(p->kids[0]->kids[0]->op == ADDRLP || p->kids[0]->kids[0]->op == ADDRFP) &&
(p->kids[1]->syms[0]->u.value == 2 ||
p->kids[1]->syms[0]->u.value == 1 ||
p->kids[1]->syms[0]->u.value == 3)) {
p = newnode(LSHI,
newnode(p->kids[0]->op,
newnode(p->kids[0]->kids[0]->op,NULL,NULL,p->kids[0]->kids[0]->syms[0]),
NULL,
p->kids[0]->syms[0]),
newnode(CNSTI,NULL,NULL,p->kids[1]->syms[0]),
p->syms[0]);
p->count = 1;
}
else if (p->op == INDIRB ||
(p->op == INDIRD) ||
(p->op == INDIRL)) {
--p->count;
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), LOCAL);
assert(!p->syms[2]->defined);
p->syms[2]->ref = (float)1.0;
Initreferences(p->syms[2]);
p->syms[2]->u.t.cse = p;
(*IR->local) (p->syms[2]);
p->syms[2]->defined = 1;
*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 + (isunsigned(tmp->type) ? I : ttob(tmp->type)),
newnode(ADDRLP, NULL, NULL, tmp), NULL, NULL);
p->count = 1;
return p;
}
static Node asgnnode(Symbol tmp,Node p)
{
p = newnode(ASGN + (isunsigned(tmp->type) ? I : ttob(tmp->type)),
newnode(ADDRLP, 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)
{
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(fd, StrTab[389], nodeid((Tree) p));// <node'%d printed above\n>
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) {
int i, id = nodeid((Tree) p);
fprint(fd, "%c%d%s", lev == 0 ? '\'' : '#', id,
&" "[id < 10 ? 0 : id < 100 ? 1 : 2]);
fprint(fd, "%s count=%d", opname(p->op), p->count);
for (i = 0; i < NELEMS(p->kids) && p->kids[i]; i++)
fprint(fd, " #%d", nodeid((Tree) p->kids[i]));
for (i = 0; i < NELEMS(p->syms) && p->syms[i]; i++)
fprint(fd, " %s", p->syms[i]->name);
fprint(fd, "\n");
}
}
/* typestab - emit stab entries for p */
static void Dagtypestab(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 && xrefFile)
(*IR->stabtype) (p);
}
int SetForestFlags(int f)
{
forest->x.Flags = f;
return(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -