Annotation of coherent/d/bin/cc/c/n1/mtree1.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * The routines in this file
        !             3:  * are a portable associative tree
        !             4:  * reorderer and constant expression
        !             5:  * folder. They may not be general
        !             6:  * enough for all machines.
        !             7:  */
        !             8: #ifdef   vax
        !             9: #include "INC$LIB:cc1.h"
        !            10: #else
        !            11: #include "cc1.h"
        !            12: #endif
        !            13: 
        !            14: #define  NLNODE  20
        !            15: #define  NONODE  20
        !            16: 
        !            17: static char    cltc[]  = "associative expression too complex";
        !            18: TREE *fold1();
        !            19: TREE *foldaddr();
        !            20: 
        !            21: /*
        !            22:  * Fancy folder.
        !            23:  * Gathers up all the constants that
        !            24:  * in can, by digging through the
        !            25:  * subtrees of commutative/associative
        !            26:  * operations. Simpler things are
        !            27:  * done for operations that are not quite
        !            28:  * so friendly.
        !            29:  * Returns a pointer to the new
        !            30:  * tree.
        !            31:  */
        !            32: TREE *
        !            33: modfold(tp)
        !            34: register TREE *tp;
        !            35: {
        !            36:        register TREE *lp, **rp;
        !            37:        int i, nl, nn, op, cop;
        !            38:        lval_t c1;
        !            39:        TREE *leaves[NLNODE], *onodes[NONODE];
        !            40: 
        !            41:        op = tp->t_op;
        !            42:        if (op==NEG && tp->t_lp->t_op==DCON) {
        !            43:                tp = tp->t_lp;
        !            44: #if IEEE|DECVAX
        !            45:                tp->t_dval[DVALIS] ^= DVALMS;
        !            46: #else
        !            47: #if MCFFP
        !            48:                if ((((int)tp->t_dval[3])&0377) != 0)
        !            49:                        tp->t_dval[3] ^= 0200;
        !            50: #else
        !            51:                dvalneg((char *)tp->t_dval);
        !            52: #endif
        !            53: #endif
        !            54:                return (tp);
        !            55:        }
        !            56:        if (isleaf(op) || isflt(tp->t_type))
        !            57:                return (tp);
        !            58:        if (op==CONVERT || op==CAST) {
        !            59:                lp = tp->t_lp;
        !            60:                if ((cop=lp->t_op)==ICON || cop==LCON) {
        !            61:                        c1 = grabnval(lp);
        !            62:                        if (islong(tp->t_type))
        !            63:                                lp = lvalnode(c1);  else
        !            64:                                lp = ivalnode((int) c1);
        !            65:                        lp->t_type = tp->t_type;
        !            66:                        lp->t_size = tp->t_size;
        !            67:                        return (lp);
        !            68:                }
        !            69:        }
        !            70:        if (op!=ADD && op!=MUL && op!=AND && op!=OR && op!=XOR) {
        !            71:                lp = fold1(op, tp->t_lp, tp->t_rp);
        !            72:                if (lp != NULL)
        !            73:                        return (lp);
        !            74:                return (tp);
        !            75:        }
        !            76:        nn = nl = 0;
        !            77:        cluster(tp, op, tp->t_type, &nn, &nl, onodes, leaves);
        !            78:        rp = &leaves[--nl];
        !            79:        for (i = nl; i > 0; ) {
        !            80:                lp = fold1(op, rp[0], rp[-1]);
        !            81:                if (lp == NULL)
        !            82:                        break;
        !            83:                --nl;
        !            84:                --rp;
        !            85:                rp[0] = lp;
        !            86:                --i;
        !            87:        }
        !            88:        tp = rp[0];
        !            89:        if (op==ADD || op==OR || op==XOR) {
        !            90:                if (nl>0 && isnval(tp, 0))
        !            91:                        --nl;
        !            92:                if (nl <= 0)
        !            93:                        return (leaves[0]);
        !            94:        }
        !            95:        if (op==MUL || op==AND) {
        !            96:                if (isnval(tp, 0))
        !            97:                        return (tp);
        !            98:                if (op==MUL && nl>0 && isnval(tp, 1))
        !            99:                        --nl;
        !           100:        }
        !           101:        if (nl <= 0)
        !           102:                return (leaves[0]);
        !           103:        rp = &leaves[0];
        !           104:        tp =  leaves[0];
        !           105:        for (i=0; i<nl; ++i) {
        !           106:                lp = onodes[i];
        !           107:                lp->t_rp = *++rp;
        !           108:                lp->t_lp = tp;
        !           109:                tp = lp;
        !           110:                if (op==ADD && isblkp(tp->t_type)==0)
        !           111:                        fixaddtype(tp);
        !           112:        }
        !           113:        return (tp);
        !           114: }
        !           115: 
        !           116: /*
        !           117:  * Collect up an associative
        !           118:  * operator cluster. Pack it into the
        !           119:  * supplied buffers.
        !           120:  */
        !           121: cluster(tp, op, type, ann, anl, onodes, leaves)
        !           122: register TREE *tp;
        !           123: int *ann, *anl;
        !           124: register TREE *onodes[], *leaves[];
        !           125: {
        !           126:        register i, nl;
        !           127:        int nn;
        !           128:        TREE *xp;
        !           129: 
        !           130:        if (tp->t_op==op && tp->t_type==type) {
        !           131:                nn = *ann;
        !           132:                if ((*ann)++ >= NONODE)
        !           133:                        cfatal(cltc);
        !           134:                onodes[nn] = tp;
        !           135:                cluster(tp->t_lp, op, type, ann, anl, onodes, leaves);
        !           136:                cluster(tp->t_rp, op, type, ann, anl, onodes, leaves);
        !           137:                return;
        !           138:        }
        !           139:        nl = *anl;
        !           140:        if ((*anl)++ >= NLNODE)
        !           141:                cfatal(cltc);
        !           142:        if (isncon(tp->t_op)) {
        !           143:                leaves[nl] = tp;
        !           144:                return;
        !           145:        }
        !           146:        for (i = nl; i > 0; ) {
        !           147:                xp = leaves[i-1];
        !           148:                if (tp->t_op==ADDR && !isncon(xp->t_op))
        !           149:                        break;
        !           150:                if (tp->t_op==STAR && xp->t_op==STAR)
        !           151:                        break;
        !           152:                leaves[i] = xp;
        !           153:                --i;
        !           154:        }
        !           155:        leaves[i] = tp;
        !           156: }
        !           157: 
        !           158: /*
        !           159:  * Fold an operation.
        !           160:  * Return a pointer to the folded
        !           161:  * tree, or NULL if no fold is
        !           162:  * possible.
        !           163:  */
        !           164: TREE *
        !           165: fold1(op, lp, rp)
        !           166: TREE *lp, *rp;
        !           167: {
        !           168:        register TREE *fp;
        !           169:        register sop, lrf;
        !           170:        register tt;
        !           171:        lval_t c1, c2;
        !           172: 
        !           173:        if ((fp = foldaddr(op, lp, rp)) != NULL)
        !           174:                return (fp);
        !           175:        lrf = 0;
        !           176:        if ((sop=lp->t_op)!=ICON && sop!=LCON)
        !           177:                return (NULL);
        !           178:        c1 = grabnval(lp);
        !           179:        tt = lp->t_type;
        !           180:        if (sop == LCON)
        !           181:                ++lrf;
        !           182:        if (op == QUEST) {
        !           183:                return (c1 ? rp->t_lp : rp->t_rp);
        !           184:        }
        !           185:        if (rp != NULL) {
        !           186:                if ((sop=rp->t_op)!=ICON && sop!=LCON)
        !           187:                        return (NULL);
        !           188:                c2 = grabnval(rp);
        !           189:                if (rp->t_type > tt)
        !           190:                        tt = rp->t_type;
        !           191:                if (sop == LCON)
        !           192:                        ++lrf;
        !           193:        }
        !           194:        switch (op) {
        !           195: 
        !           196:        case COM:
        !           197:                c1 = ~c1;
        !           198:                break;
        !           199: 
        !           200:        case NOT:
        !           201:                c1 = !c1;
        !           202:                break;
        !           203: 
        !           204:        case NEG:
        !           205:                c1 = -c1;
        !           206:                break;
        !           207: 
        !           208:        case ADD:
        !           209:                c1 += c2;
        !           210:                break;
        !           211: 
        !           212:        case SUB:
        !           213:                c1 -= c2;
        !           214:                break;
        !           215: 
        !           216:        case MUL:
        !           217:                c1 *= c2;
        !           218:                break;
        !           219: 
        !           220:        case DIV:
        !           221:                if (c2 == 0)
        !           222:                        return (NULL);
        !           223:                c1 /= c2;
        !           224:                break;
        !           225: 
        !           226:        case REM:
        !           227:                if (c2 == 0)
        !           228:                        return (NULL);
        !           229:                c1 %= c2;
        !           230:                break;
        !           231: 
        !           232:        case AND:
        !           233:                c1 &= c2;
        !           234:                break;
        !           235: 
        !           236:        case OR:
        !           237:                c1 |= c2;
        !           238:                break;
        !           239: 
        !           240:        case XOR:
        !           241:                c1 ^= c2;
        !           242:                break;
        !           243: 
        !           244:        case SHL:
        !           245:                c1 <<= c2;
        !           246:                break;
        !           247: 
        !           248:        case SHR:
        !           249:                c1 >>= c2;
        !           250:                break;
        !           251: 
        !           252:        case EQ:
        !           253:                c1 = c1==c2;
        !           254:                break;
        !           255: 
        !           256:        case NE:
        !           257:                c1 = c1!=c2;
        !           258:                break;
        !           259: 
        !           260:        case LT:
        !           261:                c1 = c1<c2;
        !           262:                break;
        !           263: 
        !           264:        case LE:
        !           265:                c1 = c1<=c2;
        !           266:                break;
        !           267: 
        !           268:        case GT:
        !           269:                c1 = c1>c2;
        !           270:                break;
        !           271: 
        !           272:        case GE:
        !           273:                c1 = c1>=c2;
        !           274:                break;
        !           275: 
        !           276:        case ANDAND:
        !           277:                c1 = (c1 && c2);
        !           278:                break;
        !           279: 
        !           280:        case OROR:
        !           281:                c1 = (c1 || c2);
        !           282:                break;
        !           283: 
        !           284:        default:
        !           285:                return (NULL);
        !           286:        }
        !           287:        if (lrf && op!=ANDAND && op!=OROR && !isrelop(op))
        !           288:                fp = lvalnode(c1);
        !           289:        else
        !           290:                fp = ivalnode((int) c1);
        !           291:        fp->t_type = tt;
        !           292:        return (fp);
        !           293: }
        !           294: 
        !           295: /*
        !           296:  * Fold things that look like
        !           297:  * `&array[constant]' where the array
        !           298:  * is an external or a static.
        !           299:  */
        !           300: TREE *
        !           301: foldaddr(op, lp, rp)
        !           302: register TREE *lp, *rp;
        !           303: {
        !           304:        register TREE *xp;
        !           305:        long val;
        !           306: 
        !           307:        if (op==ADD || op==SUB) {
        !           308:                if (lp->t_op==ADDR
        !           309:                 && (rp->t_op==LCON || rp->t_op==ICON)) {
        !           310:                        xp = lp->t_lp;
        !           311:                        if (xp->t_op==LID || xp->t_op==GID) {
        !           312:                                val = grabnval(rp);
        !           313:                                if (op == ADD)
        !           314:                                        xp->t_offs += val;
        !           315:                                else
        !           316:                                        xp->t_offs -= val;
        !           317:                                return (lp);
        !           318:                        }
        !           319:                }
        !           320:                if (op==ADD &&  rp->t_op==ADDR
        !           321:                 && (lp->t_op==LCON || lp->t_op==ICON)) {
        !           322:                        xp = rp->t_lp;
        !           323:                        if (xp->t_op==LID || xp->t_op==GID) {
        !           324:                                xp->t_offs += grabnval(lp);
        !           325:                                return (rp);
        !           326:                        }
        !           327:                }
        !           328:        }
        !           329:        return (NULL);
        !           330: }

unix.superglobalmegacorp.com

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