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

1.1     ! root        1: /*
        !             2:  * n1/mtree1.c
        !             3:  * A portable associative tree reorderer and constant expression folder.
        !             4:  * This may not be general enough for all machines.
        !             5:  */
        !             6: 
        !             7: #ifdef   vax
        !             8: #include "INC$LIB:cc1.h"
        !             9: #else
        !            10: #include "cc1.h"
        !            11: #endif
        !            12: 
        !            13: #if    _I386
        !            14: #define  NLNODE  128
        !            15: #define  NONODE  128
        !            16: #else
        !            17: #define  NLNODE  20
        !            18: #define  NONODE  20
        !            19: #endif
        !            20: 
        !            21: static char    cltc[]  = "associative expression too complex";
        !            22: TREE *fold1();
        !            23: TREE *foldaddr();
        !            24: 
        !            25: /*
        !            26:  * Fancy folder.
        !            27:  * This gathers up all the constants that it can
        !            28:  * by digging through the subtrees of commutative/associative operations.
        !            29:  * Simpler things are done for operations that are not quite so friendly.
        !            30:  * Returns a pointer to the new 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 = constcvt(tp->t_type, grabnval(lp));
        !            62:                        if (islong(tp->t_type))
        !            63:                                lp = lvalnode(c1);  else
        !            64:                                lp = ivalnode((ival_t) 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 operator cluster.
        !           118:  * Pack it into the supplied buffers.
        !           119:  */
        !           120: cluster(tp, op, type, ann, anl, onodes, leaves)
        !           121: register TREE *tp;
        !           122: int *ann, *anl;
        !           123: register TREE *onodes[], *leaves[];
        !           124: {
        !           125:        register i, nl;
        !           126:        int nn;
        !           127:        TREE *xp;
        !           128: 
        !           129:        if (tp->t_op==op && tp->t_type==type) {
        !           130:                nn = *ann;
        !           131:                if ((*ann)++ >= NONODE)
        !           132:                        cfatal(cltc);
        !           133:                onodes[nn] = tp;
        !           134:                cluster(tp->t_lp, op, type, ann, anl, onodes, leaves);
        !           135:                cluster(tp->t_rp, op, type, ann, anl, onodes, leaves);
        !           136:                return;
        !           137:        }
        !           138:        nl = *anl;
        !           139:        if ((*anl)++ >= NLNODE)
        !           140:                cfatal(cltc);
        !           141:        if (isncon(tp->t_op)) {
        !           142:                leaves[nl] = tp;
        !           143:                return;
        !           144:        }
        !           145:        for (i = nl; i > 0; ) {
        !           146:                xp = leaves[i-1];
        !           147:                if (tp->t_op==ADDR && !isncon(xp->t_op))
        !           148:                        break;
        !           149:                if (tp->t_op==STAR && xp->t_op==STAR)
        !           150:                        break;
        !           151:                leaves[i] = xp;
        !           152:                --i;
        !           153:        }
        !           154:        leaves[i] = tp;
        !           155: }
        !           156: 
        !           157: /*
        !           158:  * Fold an operation.
        !           159:  * Return a pointer to the folded tree,
        !           160:  * or NULL if no fold is possible.
        !           161:  * FIX_ME This should pay attention to unsigned types like n0/fold.c/fold0().
        !           162:  */
        !           163: TREE *
        !           164: fold1(op, lp, rp) int op; TREE *lp, *rp;
        !           165: {
        !           166:        register TREE *fp;
        !           167:        register int sop, lflag, tt, bool;
        !           168:        lval_t lv, rv;
        !           169: 
        !           170:        if ((fp = foldaddr(op, lp, rp)) != NULL)
        !           171:                return fp;
        !           172:        if ((sop = lp->t_op)!=ICON && sop!=LCON)
        !           173:                return NULL;
        !           174:        lv = grabnval(lp);
        !           175:        tt = lp->t_type;
        !           176:        lflag = (sop == LCON);
        !           177:        if (op == QUEST)
        !           178:                return (lv) ? rp->t_lp : rp->t_rp;
        !           179:        if (rp != NULL) {
        !           180:                if ((sop = rp->t_op)!=ICON && sop!=LCON)
        !           181:                        return NULL;
        !           182:                rv = grabnval(rp);
        !           183:                if (rp->t_type > tt)
        !           184:                        tt = rp->t_type;
        !           185:                if (sop == LCON)
        !           186:                        ++lflag;
        !           187:        }
        !           188:        bool = -1;
        !           189: 
        !           190:        /* Perform the folding, result to lv or bool. */
        !           191:        switch (op) {
        !           192: 
        !           193:        case COM:       lv = ~lv;               break;
        !           194:        case NEG:       lv = -lv;               break;
        !           195:        case ADD:       lv += rv;               break;
        !           196:        case SUB:       lv -= rv;               break;
        !           197:        case MUL:       lv *= rv;               break;
        !           198:        case AND:       lv &= rv;               break;
        !           199:        case OR:        lv |= rv;               break;
        !           200:        case XOR:       lv ^= rv;               break;
        !           201:        case SHL:       lv <<= rv;              break;
        !           202:        case SHR:       lv >>= rv;              break;
        !           203: 
        !           204:        case DIV:
        !           205:                if (rv == 0)
        !           206:                        return NULL;
        !           207:                lv /= rv;
        !           208:                break;
        !           209: 
        !           210:        case REM:
        !           211:                if (rv == 0)
        !           212:                        return NULL;
        !           213:                lv %= rv;
        !           214:                break;
        !           215: 
        !           216:        case NOT:       bool = !lv;             break;
        !           217:        case EQ:        bool = lv == rv;        break;
        !           218:        case NE:        bool = lv != rv;        break;
        !           219:        case LT:        bool = lv <  rv;        break;
        !           220:        case LE:        bool = lv <= rv;        break;
        !           221:        case GT:        bool = lv >  rv;        break;
        !           222:        case GE:        bool = lv >= rv;        break;
        !           223:        case ANDAND:    bool = (lv && rv);      break;
        !           224:        case OROR:      bool = (lv || rv);      break;
        !           225: 
        !           226:        default:
        !           227:                return NULL;
        !           228:        }
        !           229: 
        !           230:        if (bool != -1)
        !           231:                fp = ivalnode((ival_t)bool);
        !           232:        else if (lflag)
        !           233:                fp = lvalnode(lv);
        !           234:        else
        !           235:                fp = ivalnode((ival_t) lv);
        !           236:        fp->t_type = tt;
        !           237:        return fp;
        !           238: }
        !           239: 
        !           240: /*
        !           241:  * Fold things that look like '&array[constant]'
        !           242:  * where the array is an external or a static.
        !           243:  */
        !           244: TREE *
        !           245: foldaddr(op, lp, rp)
        !           246: register TREE *lp, *rp;
        !           247: {
        !           248:        register TREE *xp;
        !           249:        long val;
        !           250: 
        !           251:        if (op==ADD || op==SUB) {
        !           252:                if (lp->t_op==ADDR
        !           253:                 && (rp->t_op==LCON || rp->t_op==ICON)) {
        !           254:                        xp = lp->t_lp;
        !           255:                        if (xp->t_op==LID || xp->t_op==GID) {
        !           256:                                val = grabnval(rp);
        !           257:                                if (op == ADD)
        !           258:                                        xp->t_offs += val;
        !           259:                                else
        !           260:                                        xp->t_offs -= val;
        !           261:                                return lp;
        !           262:                        }
        !           263:                }
        !           264:                if (op==ADD &&  rp->t_op==ADDR
        !           265:                 && (lp->t_op==LCON || lp->t_op==ICON)) {
        !           266:                        xp = rp->t_lp;
        !           267:                        if (xp->t_op==LID || xp->t_op==GID) {
        !           268:                                xp->t_offs += grabnval(lp);
        !           269:                                return rp;
        !           270:                        }
        !           271:                }
        !           272:        }
        !           273:        return NULL;
        !           274: }
        !           275: 
        !           276: /* end of n1/mtree1.c */

unix.superglobalmegacorp.com

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