117746Sralph #ifndef lint 2*18019Sralph static char *sccsid ="@(#)optim.c 4.4 (Berkeley) 02/20/85"; 317746Sralph #endif lint 417746Sralph 516935Sralph # include "mfile1" 616935Sralph 716935Sralph # define SWAP(p,q) {sp=p; p=q; q=sp;} 816935Sralph # define RCON(p) (p->in.right->in.op==ICON) 916935Sralph # define RO(p) p->in.right->in.op 1016935Sralph # define RV(p) p->in.right->tn.lval 1116935Sralph # define LCON(p) (p->in.left->in.op==ICON) 1216935Sralph # define LO(p) p->in.left->in.op 1316935Sralph # define LV(p) p->in.left->tn.lval 1416935Sralph 1516935Sralph int oflag = 0; 1616935Sralph 1716935Sralph NODE * 1816935Sralph fortarg( p ) NODE *p; { 1916935Sralph /* fortran function arguments */ 2016935Sralph 2116935Sralph if( p->in.op == CM ){ 2216935Sralph p->in.left = fortarg( p->in.left ); 2316935Sralph p->in.right = fortarg( p->in.right ); 2416935Sralph return(p); 2516935Sralph } 2616935Sralph 2716935Sralph while( ISPTR(p->in.type) ){ 2816935Sralph p = buildtree( UNARY MUL, p, NIL ); 2916935Sralph } 3016935Sralph return( optim(p) ); 3116935Sralph } 3216935Sralph 3316935Sralph /* mapping relationals when the sides are reversed */ 3416935Sralph short revrel[] ={ EQ, NE, GE, GT, LE, LT, UGE, UGT, ULE, ULT }; 3516935Sralph NODE * 3616935Sralph optim(p) register NODE *p; { 3716935Sralph /* local optimizations, most of which are probably machine independent */ 3816935Sralph 3916935Sralph register o, ty; 4016935Sralph NODE *sp; 4116935Sralph int i; 4216935Sralph TWORD t; 4316935Sralph 4416935Sralph if( (t=BTYPE(p->in.type))==ENUMTY || t==MOETY ) econvert(p); 4516935Sralph if( oflag ) return(p); 4616935Sralph ty = optype( o=p->in.op); 4716935Sralph if( ty == LTYPE ) return(p); 4816935Sralph 4916935Sralph if( ty == BITYPE ) p->in.right = optim(p->in.right); 5016935Sralph p->in.left = optim(p->in.left); 5116935Sralph 5216935Sralph /* collect constants */ 5316935Sralph 5416935Sralph switch(o){ 5516935Sralph 5616935Sralph case SCONV: 5716935Sralph case PCONV: 5816935Sralph return( clocal(p) ); 5916935Sralph 6016935Sralph case FORTCALL: 6116935Sralph p->in.right = fortarg( p->in.right ); 6216935Sralph break; 6316935Sralph 6416935Sralph case UNARY AND: 6516936Sralph if( LO(p) != NAME || !andable(p->in.left) ) return(p); 6616935Sralph 6716935Sralph LO(p) = ICON; 6816935Sralph 6916935Sralph setuleft: 7016935Sralph /* paint over the type of the left hand side with the type of the top */ 7116935Sralph p->in.left->in.type = p->in.type; 7216935Sralph p->in.left->fn.cdim = p->fn.cdim; 7316935Sralph p->in.left->fn.csiz = p->fn.csiz; 7416935Sralph p->in.op = FREE; 7516935Sralph return( p->in.left ); 7616935Sralph 7716935Sralph case UNARY MUL: 7816935Sralph if( LO(p) != ICON ) break; 7916935Sralph LO(p) = NAME; 8016935Sralph goto setuleft; 8116935Sralph 8216935Sralph case MINUS: 8316935Sralph if( !nncon(p->in.right) ) break; 8416935Sralph RV(p) = -RV(p); 8516935Sralph o = p->in.op = PLUS; 8616935Sralph 8716935Sralph case MUL: 8816935Sralph case PLUS: 8916935Sralph case AND: 9016935Sralph case OR: 9116935Sralph case ER: 9216935Sralph /* commutative ops; for now, just collect constants */ 9316935Sralph /* someday, do it right */ 9416935Sralph if( nncon(p->in.left) || ( LCON(p) && !RCON(p) ) ) SWAP( p->in.left, p->in.right ); 9516935Sralph /* make ops tower to the left, not the right */ 9616935Sralph if( RO(p) == o ){ 9716935Sralph NODE *t1, *t2, *t3; 9816935Sralph t1 = p->in.left; 9916935Sralph sp = p->in.right; 10016935Sralph t2 = sp->in.left; 10116935Sralph t3 = sp->in.right; 10216935Sralph /* now, put together again */ 10316935Sralph p->in.left = sp; 10416935Sralph sp->in.left = t1; 10516935Sralph sp->in.right = t2; 10616935Sralph p->in.right = t3; 10716935Sralph } 10816935Sralph if(o == PLUS && LO(p) == MINUS && RCON(p) && RCON(p->in.left) && 10916935Sralph conval(p->in.right, MINUS, p->in.left->in.right)){ 11016935Sralph zapleft: 11116935Sralph RO(p->in.left) = FREE; 11216935Sralph LO(p) = FREE; 11316935Sralph p->in.left = p->in.left->in.left; 11416935Sralph } 11516935Sralph if( RCON(p) && LO(p)==o && RCON(p->in.left) && conval( p->in.right, o, p->in.left->in.right ) ){ 11616935Sralph goto zapleft; 11716935Sralph } 11816935Sralph else if( LCON(p) && RCON(p) && conval( p->in.left, o, p->in.right ) ){ 11916935Sralph zapright: 12016935Sralph RO(p) = FREE; 12116935Sralph p->in.left = makety( p->in.left, p->in.type, p->fn.cdim, p->fn.csiz ); 12216935Sralph p->in.op = FREE; 12316935Sralph return( clocal( p->in.left ) ); 12416935Sralph } 12516935Sralph 12616935Sralph /* change muls to shifts */ 12716935Sralph 12816935Sralph if( o==MUL && nncon(p->in.right) && (i=ispow2(RV(p)))>=0){ 12916935Sralph if( i == 0 ){ /* multiplication by 1 */ 13016935Sralph goto zapright; 13116935Sralph } 13216935Sralph o = p->in.op = LS; 13316935Sralph p->in.right->in.type = p->in.right->fn.csiz = INT; 13416935Sralph RV(p) = i; 13516935Sralph } 13616935Sralph 13716935Sralph /* change +'s of negative consts back to - */ 13816935Sralph if( o==PLUS && nncon(p->in.right) && RV(p)<0 ){ 13916935Sralph RV(p) = -RV(p); 14016935Sralph o = p->in.op = MINUS; 14116935Sralph } 142*18019Sralph /*FALLTHROUGH*/ 143*18019Sralph case RS: 144*18019Sralph case LS: 145*18019Sralph /* Operations with zero -- DAS 1/20/85 */ 146*18019Sralph if( (o==PLUS || o==MINUS || o==OR || o==ER || o==LS || o==RS) 147*18019Sralph && nncon(p->in.right) && RV(p)==0 ) goto zapright; 148*18019Sralph break; 14916935Sralph 15016935Sralph case DIV: 15116935Sralph if( nncon( p->in.right ) && p->in.right->tn.lval == 1 ) goto zapright; 152*18019Sralph /* Unsigned division by a power of two -- DAS 1/13/85 */ 153*18019Sralph if( nncon(p->in.right) && (i=ispow2(RV(p)))>=0 && 154*18019Sralph ISUNSIGNED(p->in.type) ){ 155*18019Sralph o = p->in.op = RS; 156*18019Sralph p->in.right->in.type = p->in.right->fn.csiz = INT; 157*18019Sralph RV(p) = i; 158*18019Sralph } 15916935Sralph break; 16016935Sralph 161*18019Sralph case MOD: 162*18019Sralph /* Unsigned mod by a power of two -- DAS 1/13/85 */ 163*18019Sralph if( nncon(p->in.right) && (i=ispow2(RV(p)))>=0 && 164*18019Sralph ISUNSIGNED(p->in.type) ){ 165*18019Sralph o = p->in.op = AND; 166*18019Sralph RV(p)--; 167*18019Sralph } 168*18019Sralph break; 169*18019Sralph 17016935Sralph case EQ: 17116935Sralph case NE: 17216935Sralph case LT: 17316935Sralph case LE: 17416935Sralph case GT: 17516935Sralph case GE: 17616935Sralph case ULT: 17716935Sralph case ULE: 17816935Sralph case UGT: 17916935Sralph case UGE: 18016935Sralph if( !LCON(p) ) break; 18116935Sralph 18216935Sralph /* exchange operands */ 18316935Sralph 18416935Sralph sp = p->in.left; 18516935Sralph p->in.left = p->in.right; 18616935Sralph p->in.right = sp; 18716935Sralph p->in.op = revrel[p->in.op - EQ ]; 18816935Sralph break; 18916935Sralph 19016935Sralph } 19116935Sralph 19216935Sralph return(p); 19316935Sralph } 19416935Sralph 19516935Sralph ispow2( c ) CONSZ c; { 19616935Sralph register i; 19716935Sralph if( c <= 0 || (c&(c-1)) ) return(-1); 19816935Sralph for( i=0; c>1; ++i) c >>= 1; 19916935Sralph return(i); 20016935Sralph } 20116935Sralph 20216935Sralph nncon( p ) NODE *p; { 20316935Sralph /* is p a constant without a name */ 20416935Sralph return( p->in.op == ICON && p->tn.rval == NONAME ); 20516935Sralph } 206