1*16936Sralph static char *sccsid ="@(#)optim.c 4.2 (Berkeley) 08/13/84"; 216935Sralph # include "mfile1" 316935Sralph 416935Sralph # define SWAP(p,q) {sp=p; p=q; q=sp;} 516935Sralph # define RCON(p) (p->in.right->in.op==ICON) 616935Sralph # define RO(p) p->in.right->in.op 716935Sralph # define RV(p) p->in.right->tn.lval 816935Sralph # define LCON(p) (p->in.left->in.op==ICON) 916935Sralph # define LO(p) p->in.left->in.op 1016935Sralph # define LV(p) p->in.left->tn.lval 1116935Sralph 1216935Sralph int oflag = 0; 1316935Sralph 1416935Sralph NODE * 1516935Sralph fortarg( p ) NODE *p; { 1616935Sralph /* fortran function arguments */ 1716935Sralph 1816935Sralph if( p->in.op == CM ){ 1916935Sralph p->in.left = fortarg( p->in.left ); 2016935Sralph p->in.right = fortarg( p->in.right ); 2116935Sralph return(p); 2216935Sralph } 2316935Sralph 2416935Sralph while( ISPTR(p->in.type) ){ 2516935Sralph p = buildtree( UNARY MUL, p, NIL ); 2616935Sralph } 2716935Sralph return( optim(p) ); 2816935Sralph } 2916935Sralph 3016935Sralph /* mapping relationals when the sides are reversed */ 3116935Sralph short revrel[] ={ EQ, NE, GE, GT, LE, LT, UGE, UGT, ULE, ULT }; 3216935Sralph NODE * 3316935Sralph optim(p) register NODE *p; { 3416935Sralph /* local optimizations, most of which are probably machine independent */ 3516935Sralph 3616935Sralph register o, ty; 3716935Sralph NODE *sp; 3816935Sralph int i; 3916935Sralph TWORD t; 4016935Sralph 4116935Sralph if( (t=BTYPE(p->in.type))==ENUMTY || t==MOETY ) econvert(p); 4216935Sralph if( oflag ) return(p); 4316935Sralph ty = optype( o=p->in.op); 4416935Sralph if( ty == LTYPE ) return(p); 4516935Sralph 4616935Sralph if( ty == BITYPE ) p->in.right = optim(p->in.right); 4716935Sralph p->in.left = optim(p->in.left); 4816935Sralph 4916935Sralph /* collect constants */ 5016935Sralph 5116935Sralph switch(o){ 5216935Sralph 5316935Sralph case SCONV: 5416935Sralph case PCONV: 5516935Sralph return( clocal(p) ); 5616935Sralph 5716935Sralph case FORTCALL: 5816935Sralph p->in.right = fortarg( p->in.right ); 5916935Sralph break; 6016935Sralph 6116935Sralph case UNARY AND: 62*16936Sralph if( LO(p) != NAME || !andable(p->in.left) ) return(p); 6316935Sralph 6416935Sralph LO(p) = ICON; 6516935Sralph 6616935Sralph setuleft: 6716935Sralph /* paint over the type of the left hand side with the type of the top */ 6816935Sralph p->in.left->in.type = p->in.type; 6916935Sralph p->in.left->fn.cdim = p->fn.cdim; 7016935Sralph p->in.left->fn.csiz = p->fn.csiz; 7116935Sralph p->in.op = FREE; 7216935Sralph return( p->in.left ); 7316935Sralph 7416935Sralph case UNARY MUL: 7516935Sralph if( LO(p) != ICON ) break; 7616935Sralph LO(p) = NAME; 7716935Sralph goto setuleft; 7816935Sralph 7916935Sralph case MINUS: 8016935Sralph if( !nncon(p->in.right) ) break; 8116935Sralph RV(p) = -RV(p); 8216935Sralph o = p->in.op = PLUS; 8316935Sralph 8416935Sralph case MUL: 8516935Sralph case PLUS: 8616935Sralph case AND: 8716935Sralph case OR: 8816935Sralph case ER: 8916935Sralph /* commutative ops; for now, just collect constants */ 9016935Sralph /* someday, do it right */ 9116935Sralph if( nncon(p->in.left) || ( LCON(p) && !RCON(p) ) ) SWAP( p->in.left, p->in.right ); 9216935Sralph /* make ops tower to the left, not the right */ 9316935Sralph if( RO(p) == o ){ 9416935Sralph NODE *t1, *t2, *t3; 9516935Sralph t1 = p->in.left; 9616935Sralph sp = p->in.right; 9716935Sralph t2 = sp->in.left; 9816935Sralph t3 = sp->in.right; 9916935Sralph /* now, put together again */ 10016935Sralph p->in.left = sp; 10116935Sralph sp->in.left = t1; 10216935Sralph sp->in.right = t2; 10316935Sralph p->in.right = t3; 10416935Sralph } 10516935Sralph if(o == PLUS && LO(p) == MINUS && RCON(p) && RCON(p->in.left) && 10616935Sralph conval(p->in.right, MINUS, p->in.left->in.right)){ 10716935Sralph zapleft: 10816935Sralph RO(p->in.left) = FREE; 10916935Sralph LO(p) = FREE; 11016935Sralph p->in.left = p->in.left->in.left; 11116935Sralph } 11216935Sralph if( RCON(p) && LO(p)==o && RCON(p->in.left) && conval( p->in.right, o, p->in.left->in.right ) ){ 11316935Sralph goto zapleft; 11416935Sralph } 11516935Sralph else if( LCON(p) && RCON(p) && conval( p->in.left, o, p->in.right ) ){ 11616935Sralph zapright: 11716935Sralph RO(p) = FREE; 11816935Sralph p->in.left = makety( p->in.left, p->in.type, p->fn.cdim, p->fn.csiz ); 11916935Sralph p->in.op = FREE; 12016935Sralph return( clocal( p->in.left ) ); 12116935Sralph } 12216935Sralph 12316935Sralph /* change muls to shifts */ 12416935Sralph 12516935Sralph if( o==MUL && nncon(p->in.right) && (i=ispow2(RV(p)))>=0){ 12616935Sralph if( i == 0 ){ /* multiplication by 1 */ 12716935Sralph goto zapright; 12816935Sralph } 12916935Sralph o = p->in.op = LS; 13016935Sralph p->in.right->in.type = p->in.right->fn.csiz = INT; 13116935Sralph RV(p) = i; 13216935Sralph } 13316935Sralph 13416935Sralph /* change +'s of negative consts back to - */ 13516935Sralph if( o==PLUS && nncon(p->in.right) && RV(p)<0 ){ 13616935Sralph RV(p) = -RV(p); 13716935Sralph o = p->in.op = MINUS; 13816935Sralph } 13916935Sralph break; 14016935Sralph 14116935Sralph case DIV: 14216935Sralph if( nncon( p->in.right ) && p->in.right->tn.lval == 1 ) goto zapright; 14316935Sralph break; 14416935Sralph 14516935Sralph case EQ: 14616935Sralph case NE: 14716935Sralph case LT: 14816935Sralph case LE: 14916935Sralph case GT: 15016935Sralph case GE: 15116935Sralph case ULT: 15216935Sralph case ULE: 15316935Sralph case UGT: 15416935Sralph case UGE: 15516935Sralph if( !LCON(p) ) break; 15616935Sralph 15716935Sralph /* exchange operands */ 15816935Sralph 15916935Sralph sp = p->in.left; 16016935Sralph p->in.left = p->in.right; 16116935Sralph p->in.right = sp; 16216935Sralph p->in.op = revrel[p->in.op - EQ ]; 16316935Sralph break; 16416935Sralph 16516935Sralph } 16616935Sralph 16716935Sralph return(p); 16816935Sralph } 16916935Sralph 17016935Sralph ispow2( c ) CONSZ c; { 17116935Sralph register i; 17216935Sralph if( c <= 0 || (c&(c-1)) ) return(-1); 17316935Sralph for( i=0; c>1; ++i) c >>= 1; 17416935Sralph return(i); 17516935Sralph } 17616935Sralph 17716935Sralph nncon( p ) NODE *p; { 17816935Sralph /* is p a constant without a name */ 17916935Sralph return( p->in.op == ICON && p->tn.rval == NONAME ); 18016935Sralph } 181