diff options
Diffstat (limited to 'src/tools/lcc/src/dag.c')
-rw-r--r-- | src/tools/lcc/src/dag.c | 1494 |
1 files changed, 837 insertions, 657 deletions
diff --git a/src/tools/lcc/src/dag.c b/src/tools/lcc/src/dag.c index 420cbe7..ad0ea1c 100644 --- a/src/tools/lcc/src/dag.c +++ b/src/tools/lcc/src/dag.c @@ -1,15 +1,13 @@ #include "c.h" - -#define iscall(op) (generic(op) == CALL \ - || (IR->mulops_calls \ - && (generic(op)==DIV||generic(op)==MOD||generic(op)==MUL) \ - && ( optype(op)==U || optype(op)==I))) +#define iscall(op) \ + (generic(op) == CALL || (IR->mulops_calls && (generic(op) == DIV || generic(op) == MOD || generic(op) == MUL) && \ + (optype(op) == U || optype(op) == I))) static Node forest; static struct dag { - struct node node; - struct dag *hlink; -} *buckets[16]; + struct node node; + struct dag *hlink; +} * buckets[16]; int nodecount; static Tree firstarg; int assignargs = 1; @@ -35,702 +33,884 @@ static void typestab(Symbol, void *); static Node undag(Node); static Node visit(Node, int); static void unlist(void); -void walk(Tree tp, int tlab, int flab) { - listnodes(tp, tlab, flab); - if (forest) { - Node list = forest->link; - forest->link = NULL; - if (!IR->wants_dag) - list = undag(list); - code(Gen)->u.forest = list; - forest = NULL; - } - reset(); - deallocate(STMT); +void walk(Tree tp, int tlab, int flab) +{ + listnodes(tp, tlab, flab); + if (forest) + { + Node list = forest->link; + forest->link = NULL; + if (!IR->wants_dag) list = undag(list); + code(Gen)->u.forest = list; + forest = NULL; + } + reset(); + deallocate(STMT); } -static Node node(int op, Node l, Node r, Symbol sym) { - int i; - struct dag *p; +static Node node(int op, Node l, Node r, Symbol sym) +{ + int i; + struct dag *p; - i = (opindex(op)^((unsigned long)sym>>2))&(NELEMS(buckets)-1); - for (p = buckets[i]; p; p = p->hlink) - if (p->node.op == op && p->node.syms[0] == sym - && p->node.kids[0] == l && p->node.kids[1] == r) - return &p->node; - p = dagnode(op, l, r, sym); - p->hlink = buckets[i]; - buckets[i] = p; - ++nodecount; - return &p->node; + i = (opindex(op) ^ ((unsigned long)sym >> 2)) & (NELEMS(buckets) - 1); + for (p = buckets[i]; p; p = p->hlink) + if (p->node.op == op && p->node.syms[0] == sym && p->node.kids[0] == l && p->node.kids[1] == r) return &p->node; + p = dagnode(op, l, r, sym); + p->hlink = buckets[i]; + buckets[i] = p; + ++nodecount; + return &p->node; } -static struct dag *dagnode(int op, Node l, Node r, Symbol sym) { - struct dag *p; - NEW0(p, FUNC); - p->node.op = op; - if ((p->node.kids[0] = l) != NULL) - ++l->count; - if ((p->node.kids[1] = r) != NULL) - ++r->count; - p->node.syms[0] = sym; - return p; +static Node constnode(int op, Symbol sym) +{ + struct dag *p; + p = dagnode(op, NULL, NULL, sym); + ++nodecount; + return &p->node; } -Node newnode(int op, Node l, Node r, Symbol sym) { - return &dagnode(op, l, r, sym)->node; + +static struct dag *dagnode(int op, Node l, Node r, Symbol sym) +{ + struct dag *p; + + NEW0(p, FUNC); + p->node.op = op; + if ((p->node.kids[0] = l) != NULL) ++l->count; + if ((p->node.kids[1] = r) != NULL) ++r->count; + p->node.syms[0] = sym; + return p; } -static void kill(Symbol p) { - int i; - struct dag **q; +Node newnode(int op, Node l, Node r, Symbol sym) { return &dagnode(op, l, r, sym)->node; } +static void kill(Symbol p) +{ + int i; + struct dag **q; - for (i = 0; i < NELEMS(buckets); i++) - for (q = &buckets[i]; *q; ) - if (generic((*q)->node.op) == INDIR && - (!isaddrop((*q)->node.kids[0]->op) - || (*q)->node.kids[0]->syms[0] == p)) { - *q = (*q)->hlink; - --nodecount; - } else - q = &(*q)->hlink; + for (i = 0; i < NELEMS(buckets); i++) + for (q = &buckets[i]; *q;) + if (generic((*q)->node.op) == INDIR && + (!isaddrop((*q)->node.kids[0]->op) || (*q)->node.kids[0]->syms[0] == p)) + { + *q = (*q)->hlink; + --nodecount; + } + else + q = &(*q)->hlink; } -static void reset(void) { - if (nodecount > 0) - memset(buckets, 0, sizeof buckets); - nodecount = 0; +static void reset(void) +{ + if (nodecount > 0) memset(buckets, 0, sizeof buckets); + nodecount = 0; } -Node listnodes(Tree tp, int tlab, int flab) { - Node p = NULL, l, r; - int op; +Node listnodes(Tree tp, int tlab, int flab) +{ + Node p = NULL, l, r; + int op; - assert(tlab || flab || (tlab == 0 && flab == 0)); - if (tp == NULL) - return NULL; - if (tp->node) - return tp->node; - op = tp->op + sizeop(tp->type->size); - switch (generic(tp->op)) { - case AND: { if (depth++ == 0) reset(); - if (flab) { - listnodes(tp->kids[0], 0, flab); - listnodes(tp->kids[1], 0, flab); - } else { - listnodes(tp->kids[0], 0, flab = genlabel(1)); - listnodes(tp->kids[1], tlab, 0); - labelnode(flab); - } - depth--; } break; - case OR: { if (depth++ == 0) - reset(); - if (tlab) { - listnodes(tp->kids[0], tlab, 0); - listnodes(tp->kids[1], tlab, 0); - } else { - tlab = genlabel(1); - listnodes(tp->kids[0], tlab, 0); - listnodes(tp->kids[1], 0, flab); - labelnode(tlab); - } - depth--; - } break; - case NOT: { return listnodes(tp->kids[0], flab, tlab); } - case COND: { Tree q = tp->kids[1]; - assert(tlab == 0 && flab == 0); - if (tp->u.sym) - addlocal(tp->u.sym); - flab = genlabel(2); - listnodes(tp->kids[0], 0, flab); - assert(q && q->op == RIGHT); - reset(); - listnodes(q->kids[0], 0, 0); - if (forest->op == LABEL+V) { - equatelab(forest->syms[0], findlabel(flab + 1)); - unlist(); - } - list(jump(flab + 1)); - labelnode(flab); - listnodes(q->kids[1], 0, 0); - if (forest->op == LABEL+V) { - equatelab(forest->syms[0], findlabel(flab + 1)); - unlist(); - } - labelnode(flab + 1); + assert(tlab || flab || (tlab == 0 && flab == 0)); + if (tp == NULL) return NULL; + if (tp->node) return tp->node; + op = tp->op + sizeop(tp->type->size); + switch (generic(tp->op)) + { + case AND: + { + if (depth++ == 0) reset(); + if (flab) + { + listnodes(tp->kids[0], 0, flab); + listnodes(tp->kids[1], 0, flab); + } + else + { + listnodes(tp->kids[0], 0, flab = genlabel(1)); + listnodes(tp->kids[1], tlab, 0); + labelnode(flab); + } + depth--; + } + break; + case OR: + { + if (depth++ == 0) reset(); + if (tlab) + { + listnodes(tp->kids[0], tlab, 0); + listnodes(tp->kids[1], tlab, 0); + } + else + { + tlab = genlabel(1); + listnodes(tp->kids[0], tlab, 0); + listnodes(tp->kids[1], 0, flab); + labelnode(tlab); + } + depth--; + } + break; + case NOT: + { + return listnodes(tp->kids[0], flab, tlab); + } + case COND: + { + Tree q = tp->kids[1]; + assert(tlab == 0 && flab == 0); + if (tp->u.sym) addlocal(tp->u.sym); + flab = genlabel(2); + listnodes(tp->kids[0], 0, flab); + assert(q && q->op == RIGHT); + reset(); + listnodes(q->kids[0], 0, 0); + if (forest->op == LABEL + V) + { + equatelab(forest->syms[0], findlabel(flab + 1)); + unlist(); + } + list(jump(flab + 1)); + labelnode(flab); + listnodes(q->kids[1], 0, 0); + if (forest->op == LABEL + V) + { + equatelab(forest->syms[0], findlabel(flab + 1)); + unlist(); + } + labelnode(flab + 1); - if (tp->u.sym) - p = listnodes(idtree(tp->u.sym), 0, 0); } break; - case CNST: { Type ty = unqual(tp->type); - assert(ty->u.sym); - if (tlab || flab) { - assert(ty == inttype); - if (tlab && tp->u.v.i != 0) - list(jump(tlab)); - else if (flab && tp->u.v.i == 0) - list(jump(flab)); - } - else if (ty->u.sym->addressed) - p = listnodes(cvtconst(tp), 0, 0); - else - p = node(op, NULL, NULL, constant(ty, tp->u.v)); } break; - case RIGHT: { if ( tp->kids[0] && tp->kids[1] - && generic(tp->kids[1]->op) == ASGN - && ((generic(tp->kids[0]->op) == INDIR - && tp->kids[0]->kids[0] == tp->kids[1]->kids[0]) - || (tp->kids[0]->op == FIELD - && tp->kids[0] == tp->kids[1]->kids[0]))) { - assert(tlab == 0 && flab == 0); - if (generic(tp->kids[0]->op) == INDIR) { - p = listnodes(tp->kids[0], 0, 0); - list(p); - listnodes(tp->kids[1], 0, 0); - } - else { - assert(generic(tp->kids[0]->kids[0]->op) == INDIR); - list(listnodes(tp->kids[0]->kids[0], 0, 0)); - p = listnodes(tp->kids[0], 0, 0); - listnodes(tp->kids[1], 0, 0); - } - } else if (tp->kids[1]) { - listnodes(tp->kids[0], 0, 0); - p = listnodes(tp->kids[1], tlab, flab); - } else - p = listnodes(tp->kids[0], tlab, flab); } break; - case JUMP: { assert(tlab == 0 && flab == 0); - assert(tp->u.sym == 0); - assert(tp->kids[0]); - l = listnodes(tp->kids[0], 0, 0); - list(newnode(JUMP+V, l, NULL, NULL)); - reset(); } break; - case CALL: { Tree save = firstarg; - firstarg = NULL; - assert(tlab == 0 && flab == 0); - if (tp->op == CALL+B && !IR->wants_callb) { - Tree arg0 = tree(ARG+P, tp->kids[1]->type, - tp->kids[1], NULL); - if (IR->left_to_right) - firstarg = arg0; - l = listnodes(tp->kids[0], 0, 0); - if (!IR->left_to_right || firstarg) { - firstarg = NULL; - listnodes(arg0, 0, 0); - } - p = newnode(CALL+V, l, NULL, NULL); - } else { - l = listnodes(tp->kids[0], 0, 0); - r = listnodes(tp->kids[1], 0, 0); - p = newnode(tp->op == CALL+B ? tp->op : op, l, r, NULL); - } - NEW0(p->syms[0], FUNC); - assert(isptr(tp->kids[0]->type)); - assert(isfunc(tp->kids[0]->type->type)); - p->syms[0]->type = tp->kids[0]->type->type; - list(p); - reset(); - cfunc->u.f.ncalls++; - firstarg = save; - } break; - case ARG: { assert(tlab == 0 && flab == 0); - if (IR->left_to_right) - listnodes(tp->kids[1], 0, 0); - if (firstarg) { - Tree arg = firstarg; - firstarg = NULL; - listnodes(arg, 0, 0); - } - l = listnodes(tp->kids[0], 0, 0); - list(newnode(tp->op == ARG+B ? tp->op : op, l, NULL, NULL)); - forest->syms[0] = intconst(tp->type->size); - forest->syms[1] = intconst(tp->type->align); - if (!IR->left_to_right) - listnodes(tp->kids[1], 0, 0); } break; - case EQ: case NE: case GT: case GE: case LE: - case LT: { assert(tp->u.sym == 0); - assert(errcnt || tlab || flab); - l = listnodes(tp->kids[0], 0, 0); - r = listnodes(tp->kids[1], 0, 0); - assert(errcnt || opkind(l->op) == opkind(r->op)); - assert(errcnt || optype(op) == optype(l->op)); - if (tlab) - assert(flab == 0), - list(newnode(generic(tp->op) + opkind(l->op), l, r, findlabel(tlab))); - else if (flab) { - switch (generic(tp->op)) { - case EQ: op = NE; break; - case NE: op = EQ; break; - case GT: op = LE; break; - case LT: op = GE; break; - case GE: op = LT; break; - case LE: op = GT; break; - default: assert(0); - } - list(newnode(op + opkind(l->op), l, r, findlabel(flab))); - } - if (forest && forest->syms[0]) - forest->syms[0]->ref++; } break; - case ASGN: { assert(tlab == 0 && flab == 0); - if (tp->kids[0]->op == FIELD) { - Tree x = tp->kids[0]->kids[0]; - Field f = tp->kids[0]->u.field; - assert(generic(x->op) == INDIR); - reset(); - l = listnodes(lvalue(x), 0, 0); - if (fieldsize(f) < 8*f->type->size) { - unsigned int fmask = fieldmask(f); - unsigned int mask = fmask<<fieldright(f); - Tree q = tp->kids[1]; - if ((q->op == CNST+I && q->u.v.i == 0) - || (q->op == CNST+U && q->u.v.u == 0)) - q = bittree(BAND, x, cnsttree(unsignedtype, (unsigned long)~mask)); - else if ((q->op == CNST+I && (q->u.v.i&fmask) == fmask) - || (q->op == CNST+U && (q->u.v.u&fmask) == fmask)) - q = bittree(BOR, x, cnsttree(unsignedtype, (unsigned long)mask)); - else { - listnodes(q, 0, 0); - q = bittree(BOR, - bittree(BAND, rvalue(lvalue(x)), - cnsttree(unsignedtype, (unsigned long)~mask)), - bittree(BAND, shtree(LSH, cast(q, unsignedtype), - cnsttree(unsignedtype, (unsigned long)fieldright(f))), - cnsttree(unsignedtype, (unsigned long)mask))); - } - r = listnodes(q, 0, 0); - op = ASGN + ttob(q->type); - } else { - r = listnodes(tp->kids[1], 0, 0); - op = ASGN + ttob(tp->kids[1]->type); - } - } else { - l = listnodes(tp->kids[0], 0, 0); - r = listnodes(tp->kids[1], 0, 0); - } - list(newnode(tp->op == ASGN+B ? tp->op : op, l, r, NULL)); - forest->syms[0] = intconst(tp->kids[1]->type->size); - forest->syms[1] = intconst(tp->kids[1]->type->align); - if (isaddrop(tp->kids[0]->op) - && !tp->kids[0]->u.sym->computed) - kill(tp->kids[0]->u.sym); - else - reset(); - p = listnodes(tp->kids[1], 0, 0); } break; - case BOR: case BAND: case BXOR: - case ADD: case SUB: case RSH: - case LSH: { assert(tlab == 0 && flab == 0); - l = listnodes(tp->kids[0], 0, 0); - r = listnodes(tp->kids[1], 0, 0); - p = node(op, l, r, NULL); } break; - case DIV: case MUL: - case MOD: { assert(tlab == 0 && flab == 0); - l = listnodes(tp->kids[0], 0, 0); - r = listnodes(tp->kids[1], 0, 0); - p = node(op, l, r, NULL); - if (IR->mulops_calls && isint(tp->type)) { - list(p); - cfunc->u.f.ncalls++; - } } break; - case RET: { assert(tlab == 0 && flab == 0); - l = listnodes(tp->kids[0], 0, 0); - list(newnode(op, l, NULL, NULL)); } break; - case CVF: case CVI: case CVP: - case CVU: { assert(tlab == 0 && flab == 0); - assert(optype(tp->kids[0]->op) != optype(tp->op) || tp->kids[0]->type->size != tp->type->size); - l = listnodes(tp->kids[0], 0, 0); - p = node(op, l, NULL, intconst(tp->kids[0]->type->size)); - } break; - case BCOM: - case NEG: { assert(tlab == 0 && flab == 0); - l = listnodes(tp->kids[0], 0, 0); - p = node(op, l, NULL, NULL); } break; - case INDIR: { Type ty = tp->kids[0]->type; - 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 == INDIR+B ? tp->op : op, l, NULL, NULL); - else - p = node(tp->op == INDIR+B ? tp->op : op, l, NULL, NULL); } break; - case FIELD: { Tree q = tp->kids[0]; - if (tp->type == inttype) { - long n = fieldleft(tp->u.field); - q = shtree(RSH, - shtree(LSH, q, cnsttree(inttype, n)), - cnsttree(inttype, n + fieldright(tp->u.field))); - } else if (fieldsize(tp->u.field) < 8*tp->u.field->type->size) - q = bittree(BAND, - shtree(RSH, q, cnsttree(inttype, (long)fieldright(tp->u.field))), - cnsttree(unsignedtype, (unsigned long)fieldmask(tp->u.field))); - assert(tlab == 0 && flab == 0); - p = listnodes(q, 0, 0); } break; - case ADDRG: - case ADDRF: { assert(tlab == 0 && flab == 0); - p = node(tp->op + sizeop(voidptype->size), 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 + sizeop(voidptype->size), NULL, NULL, tp->u.sym); } break; - default:assert(0); - } - tp->node = p; - return p; + if (tp->u.sym) p = listnodes(idtree(tp->u.sym), 0, 0); + } + break; + case CNST: + { + Type ty = unqual(tp->type); + assert(ty->u.sym); + if (tlab || flab) + { + assert(ty == inttype); + if (tlab && tp->u.v.i != 0) + list(jump(tlab)); + else if (flab && tp->u.v.i == 0) + list(jump(flab)); + } + else if (ty->u.sym->addressed) + p = listnodes(cvtconst(tp), 0, 0); + else + /* always generate new node for constants */ + if (isscalar(ty)) + p = constnode(op, constant(ty, tp->u.v)); + else + p = node(op, NULL, NULL, constant(ty, tp->u.v)); + } + break; + case RIGHT: + { + if (tp->kids[0] && tp->kids[1] && generic(tp->kids[1]->op) == ASGN && + ((generic(tp->kids[0]->op) == INDIR && tp->kids[0]->kids[0] == tp->kids[1]->kids[0]) || + (tp->kids[0]->op == FIELD && tp->kids[0] == tp->kids[1]->kids[0]))) + { + assert(tlab == 0 && flab == 0); + if (generic(tp->kids[0]->op) == INDIR) + { + p = listnodes(tp->kids[0], 0, 0); + list(p); + listnodes(tp->kids[1], 0, 0); + } + else + { + assert(generic(tp->kids[0]->kids[0]->op) == INDIR); + list(listnodes(tp->kids[0]->kids[0], 0, 0)); + p = listnodes(tp->kids[0], 0, 0); + listnodes(tp->kids[1], 0, 0); + } + } + else if (tp->kids[1]) + { + listnodes(tp->kids[0], 0, 0); + p = listnodes(tp->kids[1], tlab, flab); + } + else + p = listnodes(tp->kids[0], tlab, flab); + } + break; + case JUMP: + { + assert(tlab == 0 && flab == 0); + assert(tp->u.sym == 0); + assert(tp->kids[0]); + l = listnodes(tp->kids[0], 0, 0); + list(newnode(JUMP + V, l, NULL, NULL)); + reset(); + } + break; + case CALL: + { + Tree save = firstarg; + firstarg = NULL; + assert(tlab == 0 && flab == 0); + if (tp->op == CALL + B && !IR->wants_callb) + { + Tree arg0 = tree(ARG + P, tp->kids[1]->type, tp->kids[1], NULL); + if (IR->left_to_right) firstarg = arg0; + l = listnodes(tp->kids[0], 0, 0); + if (!IR->left_to_right || firstarg) + { + firstarg = NULL; + listnodes(arg0, 0, 0); + } + p = newnode(CALL + V, l, NULL, NULL); + } + else + { + l = listnodes(tp->kids[0], 0, 0); + r = listnodes(tp->kids[1], 0, 0); + p = newnode(tp->op == CALL + B ? tp->op : op, l, r, NULL); + } + NEW0(p->syms[0], FUNC); + assert(isptr(tp->kids[0]->type)); + assert(isfunc(tp->kids[0]->type->type)); + p->syms[0]->type = tp->kids[0]->type->type; + list(p); + reset(); + cfunc->u.f.ncalls++; + firstarg = save; + } + break; + case ARG: + { + assert(tlab == 0 && flab == 0); + if (IR->left_to_right) listnodes(tp->kids[1], 0, 0); + if (firstarg) + { + Tree arg = firstarg; + firstarg = NULL; + listnodes(arg, 0, 0); + } + l = listnodes(tp->kids[0], 0, 0); + list(newnode(tp->op == ARG + B ? tp->op : op, l, NULL, NULL)); + forest->syms[0] = intconst(tp->type->size); + forest->syms[1] = intconst(tp->type->align); + if (!IR->left_to_right) listnodes(tp->kids[1], 0, 0); + } + break; + case EQ: + case NE: + case GT: + case GE: + case LE: + case LT: + { + assert(tp->u.sym == 0); + assert(errcnt || tlab || flab); + l = listnodes(tp->kids[0], 0, 0); + r = listnodes(tp->kids[1], 0, 0); + assert(errcnt || opkind(l->op) == opkind(r->op)); + assert(errcnt || optype(op) == optype(l->op)); + if (tlab) + assert(flab == 0), list(newnode(generic(tp->op) + opkind(l->op), l, r, findlabel(tlab))); + else if (flab) + { + switch (generic(tp->op)) + { + case EQ: + op = NE; + break; + case NE: + op = EQ; + break; + case GT: + op = LE; + break; + case LT: + op = GE; + break; + case GE: + op = LT; + break; + case LE: + op = GT; + break; + default: + assert(0); + } + list(newnode(op + opkind(l->op), l, r, findlabel(flab))); + } + if (forest && forest->syms[0]) forest->syms[0]->ref++; + } + break; + case ASGN: + { + assert(tlab == 0 && flab == 0); + if (tp->kids[0]->op == FIELD) + { + Tree x = tp->kids[0]->kids[0]; + Field f = tp->kids[0]->u.field; + assert(generic(x->op) == INDIR); + reset(); + l = listnodes(lvalue(x), 0, 0); + if (fieldsize(f) < 8 * f->type->size) + { + unsigned int fmask = fieldmask(f); + unsigned int mask = fmask << fieldright(f); + Tree q = tp->kids[1]; + if ((q->op == CNST + I && q->u.v.i == 0) || (q->op == CNST + U && q->u.v.u == 0)) + q = bittree(BAND, x, cnsttree(unsignedtype, (unsigned long)~mask)); + else if ((q->op == CNST + I && (q->u.v.i & fmask) == fmask) || + (q->op == CNST + U && (q->u.v.u & fmask) == fmask)) + q = bittree(BOR, x, cnsttree(unsignedtype, (unsigned long)mask)); + else + { + listnodes(q, 0, 0); + q = bittree(BOR, bittree(BAND, rvalue(lvalue(x)), cnsttree(unsignedtype, (unsigned long)~mask)), + bittree(BAND, shtree(LSH, cast(q, unsignedtype), + cnsttree(unsignedtype, (unsigned long)fieldright(f))), + cnsttree(unsignedtype, (unsigned long)mask))); + } + r = listnodes(q, 0, 0); + op = ASGN + ttob(q->type); + } + else + { + r = listnodes(tp->kids[1], 0, 0); + op = ASGN + ttob(tp->kids[1]->type); + } + } + else + { + l = listnodes(tp->kids[0], 0, 0); + r = listnodes(tp->kids[1], 0, 0); + } + list(newnode(tp->op == ASGN + B ? tp->op : op, l, r, NULL)); + forest->syms[0] = intconst(tp->kids[1]->type->size); + forest->syms[1] = intconst(tp->kids[1]->type->align); + if (isaddrop(tp->kids[0]->op) && !tp->kids[0]->u.sym->computed) + kill(tp->kids[0]->u.sym); + else + reset(); + p = listnodes(tp->kids[1], 0, 0); + } + break; + case BOR: + case BAND: + case BXOR: + case ADD: + case SUB: + case RSH: + case LSH: + { + assert(tlab == 0 && flab == 0); + l = listnodes(tp->kids[0], 0, 0); + r = listnodes(tp->kids[1], 0, 0); + p = node(op, l, r, NULL); + } + break; + case DIV: + case MUL: + case MOD: + { + assert(tlab == 0 && flab == 0); + l = listnodes(tp->kids[0], 0, 0); + r = listnodes(tp->kids[1], 0, 0); + p = node(op, l, r, NULL); + if (IR->mulops_calls && isint(tp->type)) + { + list(p); + cfunc->u.f.ncalls++; + } + } + break; + case RET: + { + assert(tlab == 0 && flab == 0); + l = listnodes(tp->kids[0], 0, 0); + list(newnode(op, l, NULL, NULL)); + } + break; + case CVF: + case CVI: + case CVP: + case CVU: + { + assert(tlab == 0 && flab == 0); + assert(optype(tp->kids[0]->op) != optype(tp->op) || tp->kids[0]->type->size != tp->type->size); + l = listnodes(tp->kids[0], 0, 0); + p = node(op, l, NULL, intconst(tp->kids[0]->type->size)); + } + break; + case BCOM: + case NEG: + { + assert(tlab == 0 && flab == 0); + l = listnodes(tp->kids[0], 0, 0); + p = node(op, l, NULL, NULL); + } + break; + case INDIR: + { + Type ty = tp->kids[0]->type; + 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 == INDIR + B ? tp->op : op, l, NULL, NULL); + else + p = node(tp->op == INDIR + B ? tp->op : op, l, NULL, NULL); + } + break; + case FIELD: + { + Tree q = tp->kids[0]; + if (tp->type == inttype) + { + long n = fieldleft(tp->u.field); + q = shtree(RSH, shtree(LSH, q, cnsttree(inttype, n)), cnsttree(inttype, n + fieldright(tp->u.field))); + } + else if (fieldsize(tp->u.field) < 8 * tp->u.field->type->size) + q = bittree(BAND, shtree(RSH, q, cnsttree(inttype, (long)fieldright(tp->u.field))), + cnsttree(unsignedtype, (unsigned long)fieldmask(tp->u.field))); + assert(tlab == 0 && flab == 0); + p = listnodes(q, 0, 0); + } + break; + case ADDRG: + case ADDRF: + { + assert(tlab == 0 && flab == 0); + p = node(tp->op + sizeop(voidptype->size), 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 + 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 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 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; +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; + 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; +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; + 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; +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; + 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 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; +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; +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; + 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; +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; + 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 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; +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; + 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); - } +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; + 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; + *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]; +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; + 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; +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; +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); + 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; +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); + 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"); - } +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); +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); } - |