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