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