1 static char *sccsid ="@(#)optim.c 4.1 (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 ) 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 } 183