Annotation of coherent/d/bin/cc/c/n1/mtree1.c, revision 1.1.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.