|
|
1.1 ! root 1: static char *sccsid ="%W% (Berkeley) %G%"; ! 2: # include "mfile1" ! 3: ! 4: # define SWAP(p,q) {sp=p; p=q; q=sp;} ! 5: # define RCON(p) (p->in.right->in.op==ICON) ! 6: # define RO(p) p->in.right->in.op ! 7: # define RV(p) p->in.right->tn.lval ! 8: # define LCON(p) (p->in.left->in.op==ICON) ! 9: # define LO(p) p->in.left->in.op ! 10: # define LV(p) p->in.left->tn.lval ! 11: ! 12: int oflag = 0; ! 13: ! 14: NODE * ! 15: fortarg( p ) NODE *p; { ! 16: /* fortran function arguments */ ! 17: ! 18: if( p->in.op == CM ){ ! 19: p->in.left = fortarg( p->in.left ); ! 20: p->in.right = fortarg( p->in.right ); ! 21: return(p); ! 22: } ! 23: ! 24: while( ISPTR(p->in.type) ){ ! 25: p = buildtree( UNARY MUL, p, NIL ); ! 26: } ! 27: return( optim(p) ); ! 28: } ! 29: ! 30: /* mapping relationals when the sides are reversed */ ! 31: short revrel[] ={ EQ, NE, GE, GT, LE, LT, UGE, UGT, ULE, ULT }; ! 32: NODE * ! 33: optim(p) register NODE *p; { ! 34: /* local optimizations, most of which are probably machine independent */ ! 35: ! 36: register o, ty; ! 37: NODE *sp; ! 38: int i; ! 39: TWORD t; ! 40: ! 41: if( (t=BTYPE(p->in.type))==ENUMTY || t==MOETY ) econvert(p); ! 42: if( oflag ) return(p); ! 43: ty = optype( o=p->in.op); ! 44: if( ty == LTYPE ) return(p); ! 45: ! 46: if( ty == BITYPE ) p->in.right = optim(p->in.right); ! 47: p->in.left = optim(p->in.left); ! 48: ! 49: /* collect constants */ ! 50: ! 51: switch(o){ ! 52: ! 53: case SCONV: ! 54: case PCONV: ! 55: return( clocal(p) ); ! 56: ! 57: case FORTCALL: ! 58: p->in.right = fortarg( p->in.right ); ! 59: break; ! 60: ! 61: case UNARY AND: ! 62: if( LO(p) != NAME ) cerror( "& error" ); ! 63: ! 64: if( !andable(p->in.left) ) return(p); ! 65: ! 66: LO(p) = ICON; ! 67: ! 68: setuleft: ! 69: /* paint over the type of the left hand side with the type of the top */ ! 70: p->in.left->in.type = p->in.type; ! 71: p->in.left->fn.cdim = p->fn.cdim; ! 72: p->in.left->fn.csiz = p->fn.csiz; ! 73: p->in.op = FREE; ! 74: return( p->in.left ); ! 75: ! 76: case UNARY MUL: ! 77: if( LO(p) != ICON ) break; ! 78: LO(p) = NAME; ! 79: goto setuleft; ! 80: ! 81: case MINUS: ! 82: if( !nncon(p->in.right) ) break; ! 83: RV(p) = -RV(p); ! 84: o = p->in.op = PLUS; ! 85: ! 86: case MUL: ! 87: case PLUS: ! 88: case AND: ! 89: case OR: ! 90: case ER: ! 91: /* commutative ops; for now, just collect constants */ ! 92: /* someday, do it right */ ! 93: if( nncon(p->in.left) || ( LCON(p) && !RCON(p) ) ) SWAP( p->in.left, p->in.right ); ! 94: /* make ops tower to the left, not the right */ ! 95: if( RO(p) == o ){ ! 96: NODE *t1, *t2, *t3; ! 97: t1 = p->in.left; ! 98: sp = p->in.right; ! 99: t2 = sp->in.left; ! 100: t3 = sp->in.right; ! 101: /* now, put together again */ ! 102: p->in.left = sp; ! 103: sp->in.left = t1; ! 104: sp->in.right = t2; ! 105: p->in.right = t3; ! 106: } ! 107: if(o == PLUS && LO(p) == MINUS && RCON(p) && RCON(p->in.left) && ! 108: conval(p->in.right, MINUS, p->in.left->in.right)){ ! 109: zapleft: ! 110: RO(p->in.left) = FREE; ! 111: LO(p) = FREE; ! 112: p->in.left = p->in.left->in.left; ! 113: } ! 114: if( RCON(p) && LO(p)==o && RCON(p->in.left) && conval( p->in.right, o, p->in.left->in.right ) ){ ! 115: goto zapleft; ! 116: } ! 117: else if( LCON(p) && RCON(p) && conval( p->in.left, o, p->in.right ) ){ ! 118: zapright: ! 119: RO(p) = FREE; ! 120: p->in.left = makety( p->in.left, p->in.type, p->fn.cdim, p->fn.csiz ); ! 121: p->in.op = FREE; ! 122: return( clocal( p->in.left ) ); ! 123: } ! 124: ! 125: /* change muls to shifts */ ! 126: ! 127: if( o==MUL && nncon(p->in.right) && (i=ispow2(RV(p)))>=0){ ! 128: if( i == 0 ){ /* multiplication by 1 */ ! 129: goto zapright; ! 130: } ! 131: o = p->in.op = LS; ! 132: p->in.right->in.type = p->in.right->fn.csiz = INT; ! 133: RV(p) = i; ! 134: } ! 135: ! 136: /* change +'s of negative consts back to - */ ! 137: if( o==PLUS && nncon(p->in.right) && RV(p)<0 ){ ! 138: RV(p) = -RV(p); ! 139: o = p->in.op = MINUS; ! 140: } ! 141: break; ! 142: ! 143: case DIV: ! 144: if( nncon( p->in.right ) && p->in.right->tn.lval == 1 ) goto zapright; ! 145: break; ! 146: ! 147: case EQ: ! 148: case NE: ! 149: case LT: ! 150: case LE: ! 151: case GT: ! 152: case GE: ! 153: case ULT: ! 154: case ULE: ! 155: case UGT: ! 156: case UGE: ! 157: if( !LCON(p) ) break; ! 158: ! 159: /* exchange operands */ ! 160: ! 161: sp = p->in.left; ! 162: p->in.left = p->in.right; ! 163: p->in.right = sp; ! 164: p->in.op = revrel[p->in.op - EQ ]; ! 165: break; ! 166: ! 167: } ! 168: ! 169: return(p); ! 170: } ! 171: ! 172: ispow2( c ) CONSZ c; { ! 173: register i; ! 174: if( c <= 0 || (c&(c-1)) ) return(-1); ! 175: for( i=0; c>1; ++i) c >>= 1; ! 176: return(i); ! 177: } ! 178: ! 179: nncon( p ) NODE *p; { ! 180: /* is p a constant without a name */ ! 181: return( p->in.op == ICON && p->tn.rval == NONAME ); ! 182: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.