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