1 #ifndef lint 2 static char *sccsid ="@(#)optim.c 4.3 (Berkeley) 01/18/85"; 3 #endif lint 4 5 # include "mfile1" 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 || !andable(p->in.left) ) return(p); 66 67 LO(p) = ICON; 68 69 setuleft: 70 /* paint over the type of the left hand side with the type of the top */ 71 p->in.left->in.type = p->in.type; 72 p->in.left->fn.cdim = p->fn.cdim; 73 p->in.left->fn.csiz = p->fn.csiz; 74 p->in.op = FREE; 75 return( p->in.left ); 76 77 case UNARY MUL: 78 if( LO(p) != ICON ) break; 79 LO(p) = NAME; 80 goto setuleft; 81 82 case MINUS: 83 if( !nncon(p->in.right) ) break; 84 RV(p) = -RV(p); 85 o = p->in.op = PLUS; 86 87 case MUL: 88 case PLUS: 89 case AND: 90 case OR: 91 case ER: 92 /* commutative ops; for now, just collect constants */ 93 /* someday, do it right */ 94 if( nncon(p->in.left) || ( LCON(p) && !RCON(p) ) ) SWAP( p->in.left, p->in.right ); 95 /* make ops tower to the left, not the right */ 96 if( RO(p) == o ){ 97 NODE *t1, *t2, *t3; 98 t1 = p->in.left; 99 sp = p->in.right; 100 t2 = sp->in.left; 101 t3 = sp->in.right; 102 /* now, put together again */ 103 p->in.left = sp; 104 sp->in.left = t1; 105 sp->in.right = t2; 106 p->in.right = t3; 107 } 108 if(o == PLUS && LO(p) == MINUS && RCON(p) && RCON(p->in.left) && 109 conval(p->in.right, MINUS, p->in.left->in.right)){ 110 zapleft: 111 RO(p->in.left) = FREE; 112 LO(p) = FREE; 113 p->in.left = p->in.left->in.left; 114 } 115 if( RCON(p) && LO(p)==o && RCON(p->in.left) && conval( p->in.right, o, p->in.left->in.right ) ){ 116 goto zapleft; 117 } 118 else if( LCON(p) && RCON(p) && conval( p->in.left, o, p->in.right ) ){ 119 zapright: 120 RO(p) = FREE; 121 p->in.left = makety( p->in.left, p->in.type, p->fn.cdim, p->fn.csiz ); 122 p->in.op = FREE; 123 return( clocal( p->in.left ) ); 124 } 125 126 /* change muls to shifts */ 127 128 if( o==MUL && nncon(p->in.right) && (i=ispow2(RV(p)))>=0){ 129 if( i == 0 ){ /* multiplication by 1 */ 130 goto zapright; 131 } 132 o = p->in.op = LS; 133 p->in.right->in.type = p->in.right->fn.csiz = INT; 134 RV(p) = i; 135 } 136 137 /* change +'s of negative consts back to - */ 138 if( o==PLUS && nncon(p->in.right) && RV(p)<0 ){ 139 RV(p) = -RV(p); 140 o = p->in.op = MINUS; 141 } 142 break; 143 144 case DIV: 145 if( nncon( p->in.right ) && p->in.right->tn.lval == 1 ) goto zapright; 146 break; 147 148 case EQ: 149 case NE: 150 case LT: 151 case LE: 152 case GT: 153 case GE: 154 case ULT: 155 case ULE: 156 case UGT: 157 case UGE: 158 if( !LCON(p) ) break; 159 160 /* exchange operands */ 161 162 sp = p->in.left; 163 p->in.left = p->in.right; 164 p->in.right = sp; 165 p->in.op = revrel[p->in.op - EQ ]; 166 break; 167 168 } 169 170 return(p); 171 } 172 173 ispow2( c ) CONSZ c; { 174 register i; 175 if( c <= 0 || (c&(c-1)) ) return(-1); 176 for( i=0; c>1; ++i) c >>= 1; 177 return(i); 178 } 179 180 nncon( p ) NODE *p; { 181 /* is p a constant without a name */ 182 return( p->in.op == ICON && p->tn.rval == NONAME ); 183 } 184