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