Annotation of researchv10no/cmd/lcc/c/tree.c, revision 1.1.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.