1*17746Sralph #ifndef lint 2*17746Sralph static char *sccsid ="@(#)optim.c 4.3 (Berkeley) 01/18/85"; 3*17746Sralph #endif lint 4*17746Sralph 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 } 14216935Sralph break; 14316935Sralph 14416935Sralph case DIV: 14516935Sralph if( nncon( p->in.right ) && p->in.right->tn.lval == 1 ) goto zapright; 14616935Sralph break; 14716935Sralph 14816935Sralph case EQ: 14916935Sralph case NE: 15016935Sralph case LT: 15116935Sralph case LE: 15216935Sralph case GT: 15316935Sralph case GE: 15416935Sralph case ULT: 15516935Sralph case ULE: 15616935Sralph case UGT: 15716935Sralph case UGE: 15816935Sralph if( !LCON(p) ) break; 15916935Sralph 16016935Sralph /* exchange operands */ 16116935Sralph 16216935Sralph sp = p->in.left; 16316935Sralph p->in.left = p->in.right; 16416935Sralph p->in.right = sp; 16516935Sralph p->in.op = revrel[p->in.op - EQ ]; 16616935Sralph break; 16716935Sralph 16816935Sralph } 16916935Sralph 17016935Sralph return(p); 17116935Sralph } 17216935Sralph 17316935Sralph ispow2( c ) CONSZ c; { 17416935Sralph register i; 17516935Sralph if( c <= 0 || (c&(c-1)) ) return(-1); 17616935Sralph for( i=0; c>1; ++i) c >>= 1; 17716935Sralph return(i); 17816935Sralph } 17916935Sralph 18016935Sralph nncon( p ) NODE *p; { 18116935Sralph /* is p a constant without a name */ 18216935Sralph return( p->in.op == ICON && p->tn.rval == NONAME ); 18316935Sralph } 184