Annotation of researchv10no/cmd/lcc/c/tree.c, revision 1.1

1.1     ! root        1: /* C compiler: tree management */
        !             2: 
        !             3: #include "c.h"
        !             4: 
        !             5: static struct arena first[] = {
        !             6:        0, 0, 0, &first[0], 0,
        !             7:        0, 0, 0, &first[1], 0,
        !             8: };
        !             9: Arena permanent = &first[0];   /* permanent storage */
        !            10: Arena transient = &first[1];   /* transient storage; released at function end */
        !            11: static Arena freearenas;       /* list of free arenas */
        !            12: 
        !            13: /* allocate - allocate n bytes in arena **p, adding a new arena if necessary */
        !            14: char *allocate(n, p) Arena *p; {
        !            15:        Arena ap = *p;
        !            16: 
        !            17:        while (ap->avail + n > ap->limit)
        !            18:                if (ap->next) {         /* move to next arena */
        !            19:                        ap = ap->next;
        !            20:                        ap->avail = (char *)ap + roundup(sizeof *ap, sizeof (double));
        !            21:                } else if (ap->next = freearenas) {
        !            22:                        freearenas = freearenas->next;
        !            23:                        ap = ap->next;
        !            24:                        ap->avail = (char *)ap + roundup(sizeof *ap, sizeof (double));
        !            25:                        ap->first = (*p)->first;
        !            26:                        ap->next = 0;
        !            27:                } else {                /* allocate a new arena */
        !            28:                        int m = n + MEMINCR*1024 + roundup(sizeof *ap, sizeof (double));
        !            29:                        ap->next = (Arena) malloc(m);
        !            30:                        assert(ap->next && (int)ap->next >= 0);
        !            31:                        if ((char *)ap->next == ap->limit) /* extend previous arena? */
        !            32:                                ap->limit = (char *)ap->next + m;
        !            33:                        else {                  /* link to a new arena */
        !            34:                                ap = ap->next;
        !            35:                                ap->limit = (char *)ap + m;
        !            36:                                ap->avail = (char *)ap + roundup(sizeof *ap, sizeof (double));
        !            37:                        }
        !            38:                        ap->first = (*p)->first;
        !            39:                        ap->next = 0;
        !            40:                }
        !            41:        *p = ap;
        !            42:        ap->avail += n;
        !            43:        return ap->avail - n;
        !            44: }
        !            45: 
        !            46: /* deallocate - release all space in arena *p, except the first arena; reset *p */
        !            47: void deallocate(p) Arena *p; {
        !            48:        Arena first = (*p)->first;
        !            49: 
        !            50:        (*p)->next = freearenas;
        !            51:        freearenas = first->next;
        !            52:        first->next = 0;
        !            53:        *p = first;
        !            54: }
        !            55: 
        !            56: 
        !            57: /* cvtconst - convert a constant tree into tree for a global variable */
        !            58: Tree cvtconst(p) Tree p; {
        !            59:        Symbol q = constant(p->type, p->u.v);
        !            60:        Tree e;
        !            61: 
        !            62:        if (q->u.c.loc == 0)
        !            63:                q->u.c.loc = genident(STATIC, p->type, GLOBAL);
        !            64:        if (isarray(p->type)) {
        !            65:                e = tree(ADDRG+P, atop(p->type), 0, 0);
        !            66:                e->u.sym = q->u.c.loc;
        !            67:        } else
        !            68:                e = idnode(q->u.c.loc);
        !            69:        return e;
        !            70: }
        !            71: 
        !            72: /* hascall - does tree p contain a CALL? */
        !            73: int hascall(p) Tree p; {
        !            74:        if (p == 0)
        !            75:                return 0;
        !            76:        if (generic(p->op) == CALL || (IR->mulops_are_calls &&
        !            77:          (p->op == DIV+I || p->op == MOD+I || p->op == MUL+I
        !            78:        || p->op == DIV+U || p->op == MOD+U || p->op == MUL+U)))
        !            79:                return 1;
        !            80:        return hascall(p->kids[0]) || hascall(p->kids[1]);
        !            81: }
        !            82: 
        !            83: /* opname - return string for operator op */
        !            84: char *opname(op) {
        !            85:        static char *opnames[] = {
        !            86:        "",
        !            87: #define NEEDNAMES
        !            88: #include "ops.h"
        !            89:        };
        !            90:        char *name;
        !            91: 
        !            92:        switch (op) {
        !            93:        case AND:  return "AND";
        !            94:        case NOT:  return "NOT";
        !            95:        case OR:   return "OR";
        !            96:        case COND: return "COND";
        !            97:        case RIGHT:return "RIGHT";
        !            98:        case FIELD:return "FIELD";
        !            99:        }
        !           100:        if (opindex(op) > 0 && opindex(op) < sizeof opnames/sizeof opnames[0])
        !           101:                name = opnames[opindex(op)];
        !           102:        else
        !           103:                name = stringd(opindex(op));
        !           104:        if (optype(op) > 0 && optype(op) < sizeof (TYPENAMES) - 1)
        !           105:                return stringf("%s%c", name, TYPENAMES[optype(op)]);
        !           106:        else
        !           107:                return stringf("%s+%d", name, optype(op));
        !           108: }
        !           109: 
        !           110: /* tree - allocate and initialize a tree node */
        !           111: int ntree = 0;                 /* next free tree in trees */
        !           112: static struct tree trees[100]; /* default allocation area for trees */
        !           113: 
        !           114: Tree tree(op, type, left, right) Type type; Tree left, right; {
        !           115:        register Tree p;
        !           116: 
        !           117:        if (ntree < sizeof trees/sizeof trees[0])
        !           118:                p = &trees[ntree++];
        !           119:        else
        !           120:                p = (Tree)talloc(sizeof *p);
        !           121:        BZERO(p, struct tree);
        !           122:        p->op = op;
        !           123:        p->type = type;
        !           124:        p->kids[0] = left;
        !           125:        p->kids[1] = right;
        !           126:        return p;
        !           127: }
        !           128: 
        !           129: /* retype - return a copy of tree p with type field = ty */
        !           130: Tree retype(p, ty) Tree p; Type ty;{
        !           131:        Tree q;
        !           132: 
        !           133:        if (p->type == ty)
        !           134:                return p;
        !           135:        q = tree(p->op, ty, p->kids[0], p->kids[1]);
        !           136:        q->u = p->u;
        !           137:        return q;
        !           138: }
        !           139: 
        !           140: /* root - tree p will be a root; remove unnecessary temporaries */
        !           141: Tree root(p) Tree p; {
        !           142:        if (p == 0)
        !           143:                return p;
        !           144:        switch (generic(p->op)) {
        !           145:        case COND: {
        !           146:                Tree q = p->kids[1];
        !           147:                assert(q && q->op == RIGHT);
        !           148:                if (p->u.sym && q->kids[0] && generic(q->kids[0]->op) == ASGN)
        !           149:                        q->kids[0] = root(q->kids[0]->kids[1]);
        !           150:                else
        !           151:                        q->kids[0] = root(q->kids[0]);
        !           152:                if (p->u.sym && q->kids[1] && generic(q->kids[1]->op) == ASGN)
        !           153:                        q->kids[1] = root(q->kids[1]->kids[1]);
        !           154:                else
        !           155:                        q->kids[1] = root(q->kids[1]);
        !           156:                if (p->u.sym)
        !           157:                        release(p->u.sym);
        !           158:                p->u.sym = 0;
        !           159:                if (q->kids[0] == 0 && q->kids[1] == 0)
        !           160:                        p = root(p->kids[0]);
        !           161:                }
        !           162:                break;
        !           163:        case AND: case OR:
        !           164:                if ((p->kids[1] = root(p->kids[1])) == 0)
        !           165:                        p = root(p->kids[0]);
        !           166:                break;
        !           167:        case NOT:
        !           168:                return root(p->kids[0]);
        !           169:        case RIGHT:
        !           170:                if (p->kids[1] == 0)
        !           171:                        return root(p->kids[0]);
        !           172:                if (p->kids[0] && p->kids[0]->op == CALL+B
        !           173:                &&  p->kids[1] && p->kids[1]->op == INDIR+B)
        !           174:                        /* avoid premature release of the CALL+B temporary */
        !           175:                        return p->kids[0];
        !           176:                if (p->kids[0] && p->kids[0]->op == RIGHT
        !           177:                &&  p->kids[1] == p->kids[0]->kids[0])
        !           178:                        /* de-construct e++ construction */
        !           179:                        return p->kids[0]->kids[1];
        !           180:                /* fall thru */
        !           181:        case EQ:  case NE:  case GT:   case GE:  case LE:  case LT: 
        !           182:        case ADD: case SUB: case MUL:  case DIV: case MOD:
        !           183:        case LSH: case RSH: case BAND: case BOR: case BXOR:
        !           184:                p = tree(RIGHT, p->type, root(p->kids[0]), root(p->kids[1]));
        !           185:                return p->kids[0] || p->kids[1] ? p : 0;
        !           186:        case INDIR:
        !           187:                if (p->type->size == 0 && unqual(p->type) != voidtype)
        !           188:                        warning("reference to `%t' elided\n", p->type);
        !           189:                if (isptr(p->kids[0]->type) && isvolatile(p->kids[0]->type->type))
        !           190:                        warning("reference to `volatile %t' elided\n", p->type);
        !           191:                /* fall thru */
        !           192:        case CVI: case CVF:  case CVD:   case CVU: case CVC: case CVS: case CVP:
        !           193:        case NEG: case BCOM: case FIELD:
        !           194:                return root(p->kids[0]);
        !           195:        case ADDRL:
        !           196:                if (p->u.sym->temporary)
        !           197:                        release(p->u.sym);
        !           198:                /* fall thru */
        !           199:        case ADDRG: case ADDRF: case CNST:
        !           200:                return 0;
        !           201:        case ARG: case ASGN: case CALL: case JUMP: case LABEL:
        !           202:                break;
        !           203:        default: assert(0);
        !           204:        }
        !           205:        return p;
        !           206: }
        !           207: 
        !           208: /* texpr - parse an expression via f(tok), allocating trees in transient area */
        !           209: Tree texpr(f, tok) dclproto(Tree (*f),(int)); {
        !           210:        int n = ntree;
        !           211:        Tree p;
        !           212: 
        !           213:        ntree = sizeof trees/sizeof trees[0];
        !           214:        p = (*f)(tok);
        !           215:        ntree = n;
        !           216:        return p;
        !           217: }
        !           218: 
        !           219: /* tfree - release space in all transient arenas and default tree area */
        !           220: void tfree() {
        !           221:        if (glevel < 3 && !xref)
        !           222:                deallocate(&transient);
        !           223:        ntree = 0;
        !           224: }
        !           225: 
        !           226: static int nid = 1;            /* identifies trees & nodes in debugging output */
        !           227: static struct nodeid {
        !           228:        int printed;
        !           229:        Tree node;
        !           230: } ids[500];                    /* if ids[i].node == p, then p's id is i */
        !           231: 
        !           232: dclproto(static void printtree1,(Tree, int, int));
        !           233: 
        !           234: /* nodeid - lookup id for tree or node p */
        !           235: int nodeid(p) Tree p; {
        !           236:        int i = 1;
        !           237: 
        !           238:        ids[nid].node = p;
        !           239:        while (ids[i].node != p)
        !           240:                i++;
        !           241:        if (i == nid)
        !           242:                ids[nid++].printed = 0;
        !           243:        return i;
        !           244: }
        !           245: 
        !           246: /* printed - return pointer to ids[id].printed */
        !           247: int *printed(id) {
        !           248:        if (id)
        !           249:                return &ids[id].printed;
        !           250:        nid = 1;
        !           251:        return 0;
        !           252: }
        !           253: 
        !           254: /* printtree - print tree p on fd */
        !           255: void printtree(p, fd) Tree p; {
        !           256:        (void)printed(0);
        !           257:        printtree1(p, fd, 1);
        !           258: }
        !           259: 
        !           260: /* printtree1 - recursively print tree p */
        !           261: static void printtree1(p, fd, lev) Tree p; {
        !           262:        int i;
        !           263:        static char blanks[] = "                                         ";
        !           264: 
        !           265:        if (p == 0 || *printed(i = nodeid(p)))
        !           266:                return;
        !           267:        fprint(fd, "#%d%s%s", i, &"   "[i < 10 ? 0 : i < 100 ? 1 : 2],
        !           268:                 &blanks[sizeof blanks - lev]);
        !           269:        fprint(fd, "%s %t", opname(p->op), p->type);
        !           270:        *printed(i) = 1;
        !           271:        for (i = 0; i < sizeof p->kids/sizeof p->kids[0]; i++)
        !           272:                if (p->kids[i])
        !           273:                        fprint(fd, " #%d", nodeid(p->kids[i]));
        !           274:        if (generic(p->op) == FIELD && p->u.field)
        !           275:                fprint(fd, " %s %d..%d", p->u.field->name,
        !           276:                        fieldsize(p->u.field) + fieldright(p->u.field), fieldright(p->u.field));
        !           277:        else if (generic(p->op) == CNST)
        !           278:                fprint(fd, " %s", vtoa(p->type, p->u.v));
        !           279:        else if (p->u.sym)
        !           280:                fprint(fd, " %s", p->u.sym->name);
        !           281:        if (p->node)
        !           282:                fprint(fd, " node=0x%x", p->node);
        !           283:        fprint(fd, "\n");
        !           284:        for (i = 0; i < sizeof p->kids/sizeof p->kids[0]; i++)
        !           285:                printtree1(p->kids[i], fd, lev + 1);
        !           286: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.