1 #ifndef lint 2 static char *sccsid ="@(#)optim.c 4.5 (Berkeley) 03/19/85"; 3 #endif lint 4 5 # include "pass1.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 || !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 /*FALLTHROUGH*/ 143 case RS: 144 case LS: 145 /* Operations with zero -- DAS 1/20/85 */ 146 if( (o==PLUS || o==MINUS || o==OR || o==ER || o==LS || o==RS) 147 && nncon(p->in.right) && RV(p)==0 ) goto zapright; 148 break; 149 150 case DIV: 151 if( nncon( p->in.right ) && p->in.right->tn.lval == 1 ) goto zapright; 152 /* Unsigned division by a power of two -- DAS 1/13/85 */ 153 if( nncon(p->in.right) && (i=ispow2(RV(p)))>=0 && 154 ISUNSIGNED(p->in.type) ){ 155 o = p->in.op = RS; 156 p->in.right->in.type = p->in.right->fn.csiz = INT; 157 RV(p) = i; 158 } 159 break; 160 161 case MOD: 162 /* Unsigned mod by a power of two -- DAS 1/13/85 */ 163 if( nncon(p->in.right) && (i=ispow2(RV(p)))>=0 && 164 ISUNSIGNED(p->in.type) ){ 165 o = p->in.op = AND; 166 RV(p)--; 167 } 168 break; 169 170 case EQ: 171 case NE: 172 case LT: 173 case LE: 174 case GT: 175 case GE: 176 case ULT: 177 case ULE: 178 case UGT: 179 case UGE: 180 if( !LCON(p) ) break; 181 182 /* exchange operands */ 183 184 sp = p->in.left; 185 p->in.left = p->in.right; 186 p->in.right = sp; 187 p->in.op = revrel[p->in.op - EQ ]; 188 break; 189 190 } 191 192 return(p); 193 } 194 195 ispow2( c ) CONSZ c; { 196 register i; 197 if( c <= 0 || (c&(c-1)) ) return(-1); 198 for( i=0; c>1; ++i) c >>= 1; 199 return(i); 200 } 201 202 nncon( p ) NODE *p; { 203 /* is p a constant without a name */ 204 return( p->in.op == ICON && p->tn.rval == NONAME ); 205 } 206