1: #ifndef lint
   2: static char *sccsid ="@(#)optim.c	4.7 (Berkeley) 1/8/86";
   3: #endif lint
   4: 
   5: # include "pass1.h"
   6: 
   7: # define SWAP(p,q) {sp=p; p=q; q=sp;}
   8: # define RCON(p) (p->in.right->in.op==ICON)
   9: # define RO(p) p->in.right->in.op
  10: # define RV(p) p->in.right->tn.lval
  11: # define LCON(p) (p->in.left->in.op==ICON)
  12: # define LO(p) p->in.left->in.op
  13: # define LV(p) p->in.left->tn.lval
  14: 
  15:     /* is p a constant without a name */
  16: # define nncon(p)   ((p)->in.op == ICON && (p)->tn.rval == NONAME)
  17: 
  18: int oflag = 0;
  19: 
  20: NODE *
  21: fortarg( p ) NODE *p; {
  22:     /* fortran function arguments */
  23: 
  24:     if( p->in.op == CM ){
  25:         p->in.left = fortarg( p->in.left );
  26:         p->in.right = fortarg( p->in.right );
  27:         return(p);
  28:         }
  29: 
  30:     while( ISPTR(p->in.type) ){
  31:         p = buildtree( UNARY MUL, p, NIL );
  32:         }
  33:     return( optim(p) );
  34:     }
  35: 
  36:     /* mapping relationals when the sides are reversed */
  37: short revrel[] ={ EQ, NE, GE, GT, LE, LT, UGE, UGT, ULE, ULT };
  38: NODE *
  39: optim(p) register NODE *p; {
  40:     /* local optimizations, most of which are probably machine independent */
  41: 
  42:     register o, ty;
  43:     NODE *sp;
  44:     int i;
  45:     TWORD t;
  46: 
  47:     if( (t=BTYPE(p->in.type))==ENUMTY || t==MOETY ) econvert(p);
  48:     if( oflag ) return(p);
  49:     ty = optype( o=p->in.op);
  50:     if( ty == LTYPE ) return(p);
  51: 
  52:     if( ty == BITYPE ) p->in.right = optim(p->in.right);
  53:     p->in.left = optim(p->in.left);
  54: 
  55:     /* collect constants */
  56: 
  57:     switch(o){
  58: 
  59:     case SCONV:
  60:     case PCONV:
  61:         return( clocal(p) );
  62: 
  63:     case FORTCALL:
  64:         p->in.right = fortarg( p->in.right );
  65:         break;
  66: 
  67:     case UNARY AND:
  68:         if( LO(p) != NAME || !andable(p->in.left) ) return(p);
  69: 
  70:         LO(p) = ICON;
  71: 
  72:         setuleft:
  73:         /* paint over the type of the left hand side with the type of the top */
  74:         p->in.left->in.type = p->in.type;
  75:         p->in.left->fn.cdim = p->fn.cdim;
  76:         p->in.left->fn.csiz = p->fn.csiz;
  77:         p->in.op = FREE;
  78:         return( p->in.left );
  79: 
  80:     case UNARY MUL:
  81:         if( LO(p) != ICON ) break;
  82:         LO(p) = NAME;
  83:         goto setuleft;
  84: 
  85:     case MINUS:
  86:         if( !nncon(p->in.right) ) break;
  87:         RV(p) = -RV(p);
  88:         o = p->in.op = PLUS;
  89: 
  90:     case MUL:
  91:     case PLUS:
  92:     case AND:
  93:     case OR:
  94:     case ER:
  95:         /* commutative ops; for now, just collect constants */
  96:         /* someday, do it right */
  97:         if( nncon(p->in.left) || ( LCON(p) && !RCON(p) ) ) SWAP( p->in.left, p->in.right );
  98:         /* make ops tower to the left, not the right */
  99:         if( RO(p) == o ){
 100:             NODE *t1, *t2, *t3;
 101:             t1 = p->in.left;
 102:             sp = p->in.right;
 103:             t2 = sp->in.left;
 104:             t3 = sp->in.right;
 105:             /* now, put together again */
 106:             p->in.left = sp;
 107:             sp->in.left = t1;
 108:             sp->in.right = t2;
 109:             p->in.right = t3;
 110:             }
 111:         if(o == PLUS && LO(p) == MINUS && RCON(p) && RCON(p->in.left) &&
 112:            conval(p->in.right, MINUS, p->in.left->in.right)){
 113:             zapleft:
 114:             RO(p->in.left) = FREE;
 115:             LO(p) = FREE;
 116:             p->in.left = p->in.left->in.left;
 117:         }
 118:         if( RCON(p) && LO(p)==o && RCON(p->in.left) &&
 119:             conval( p->in.right, o, p->in.left->in.right ) ){
 120:             goto zapleft;
 121:             }
 122:         else if( LCON(p) && RCON(p) &&
 123:              conval( p->in.left, o, p->in.right ) ){
 124:             zapright:
 125:             RO(p) = FREE;
 126:             p->in.left = makety( p->in.left, p->in.type, p->fn.cdim, p->fn.csiz );
 127:             p->in.op = FREE;
 128:             return( clocal( p->in.left ) );
 129:             }
 130:         /* FALL THROUGH */
 131: 
 132:     case ASG MUL:
 133:         /* change muls to adds or shifts */
 134: 
 135:         if( (o == MUL || o == ASG MUL) &&
 136:             nncon(p->in.right) && (i=ispow2(RV(p)))>=0){
 137:             if( i == 0 ) /* multiplication by 1 */
 138:                 goto zapright;
 139:             /* c2 will turn 'i << 1' into 'i + i' for us */
 140:             else {
 141:                 p->in.op = (asgop(o) ? ASG LS : LS);
 142:                 o = p->in.op;
 143:                 p->in.right->in.type = p->in.right->fn.csiz = INT;
 144:                 RV(p) = i;
 145:                 }
 146:             }
 147: 
 148:         /* change +'s of negative consts back to - */
 149:         if( o==PLUS && nncon(p->in.right) && RV(p)<0 ){
 150:             RV(p) = -RV(p);
 151:             o = p->in.op = MINUS;
 152:             }
 153:         /* FALL THROUGH */
 154:     case ASG AND:
 155:     case ASG PLUS:
 156:     case ASG MINUS:
 157:     case RS:
 158:     case LS:
 159:         /* Operations with zero */
 160:         if( nncon(p->in.right) && RV(p) == 0 ) {
 161:             if( o == MUL || o == ASG MUL ||
 162:                 o == AND || o == ASG AND ) {
 163:                 if( asgop(o) )
 164:                     p->in.op = ASSIGN;
 165:                 else if( optype(LO(p)) == LTYPE ) {
 166:                     p->in.op = FREE;
 167:                     LO(p) = FREE;
 168:                     p = p->in.right;
 169:                     }
 170:                 else
 171:                     p->in.op = COMOP; /* side effects */
 172:                 }
 173:             else if( o == PLUS || o == MINUS ||
 174:                  o == ASG PLUS || o == ASG MINUS ||
 175:                  o == OR || o == ER ||
 176:                  o == LS || o == RS )
 177:                 goto zapright;
 178:             }
 179:         if( o != LS && o != RS )
 180:             break;
 181:         /* FALL THROUGH */
 182: 
 183:     case ASG RS:
 184:     case ASG LS:
 185:         if( !ISUNSIGNED(p->in.left->in.type) )
 186:             break;
 187:         if( p->in.right->in.op == ICON &&
 188:             p->in.right->tn.lval < 0 ) {
 189:             /*
 190: 			 * Technically negative shifts are illegal
 191: 			 * but we can support them, at least with
 192: 			 * constants; you take potluck with variables.
 193: 			 */
 194:             p->in.right->tn.lval = -p->in.right->tn.lval;
 195:             switch( o ){
 196:             case LS:    p->in.op = RS; break;
 197:             case ASG LS:    p->in.op = ASG RS; break;
 198:             case RS:    p->in.op = LS; break;
 199:             case ASG RS:    p->in.op = ASG LS; break;
 200:                 }
 201:             }
 202:         break;
 203: 
 204:     case ASG DIV:
 205:     case DIV:
 206:         if( nncon( p->in.right ) ){
 207:             if( RV(p) == 0 ) uerror("division by zero");
 208:             else if( RV(p) == 1 ) goto zapright;
 209:             /* Unsigned division by a power of two */
 210:             else if( (i=ispow2(RV(p)))>=0 &&
 211:                  (ISUNSIGNED(p->in.left->in.type) ||
 212:                   ISUNSIGNED(p->in.right->in.type)) ){
 213:                 p->in.op = (asgop(o) ? ASG RS : RS);
 214:                 p->in.right->in.type = p->in.right->fn.csiz = INT;
 215:                 RV(p) = i;
 216:                 }
 217:             }
 218:         break;
 219: 
 220:     case ASG MOD:
 221:     case MOD:
 222:         if( nncon(p->in.right) ){
 223:             if( RV(p) == 0 ) uerror("modulus of zero");
 224:             else if( RV(p) == 1 ){ /* mod by one gives zero */
 225:                 RV(p) = 0;
 226:                 if( asgop(o) )
 227:                     p->in.op = ASSIGN;
 228:                 else if( optype(LO(p)) == LTYPE ) {
 229:                     p->in.op = FREE;
 230:                     LO(p) = FREE;
 231:                     p = p->in.right;
 232:                     }
 233:                 else
 234:                     p->in.op = COMOP; /* side effects */
 235:                 }
 236:             else if ((i=ispow2(RV(p)))>=0 &&
 237:                  (ISUNSIGNED(p->in.left->in.type) ||
 238:                   ISUNSIGNED(p->in.right->in.type)) ){
 239:                 /* Unsigned mod by a power of two */
 240:                 p->in.op = (asgop(o) ? ASG AND : AND);
 241:                 RV(p)--;
 242:                 }
 243:             }
 244:         break;
 245: 
 246:     case EQ:
 247:     case NE:
 248:     case LT:
 249:     case LE:
 250:     case GT:
 251:     case GE:
 252:     case ULT:
 253:     case ULE:
 254:     case UGT:
 255:     case UGE:
 256:         if( !LCON(p) ) break;
 257: 
 258:         /* exchange operands */
 259: 
 260:         sp = p->in.left;
 261:         p->in.left = p->in.right;
 262:         p->in.right = sp;
 263:         p->in.op = revrel[p->in.op - EQ ];
 264:         break;
 265: 
 266:         }
 267: 
 268:     return(p);
 269:     }
 270: 
 271: ispow2( c ) CONSZ c; {
 272:     register i;
 273:     if( c <= 0 || (c&(c-1)) ) return(-1);
 274:     for( i=0; c>1; ++i) c >>= 1;
 275:     return(i);
 276:     }

Defined functions

fortarg defined in line 20; used 3 times
ispow2 defined in line 271; used 3 times
optim defined in line 38; used 8 times

Defined variables

oflag defined in line 18; used 1 times
  • in line 48
revrel defined in line 37; used 1 times
sccsid defined in line 2; never used

Defined macros

LCON defined in line 11; used 3 times
LO defined in line 12; used 11 times
LV defined in line 13; never used
RCON defined in line 8; used 6 times
RO defined in line 9; used 3 times
RV defined in line 10; used 17 times
SWAP defined in line 7; used 1 times
  • in line 97
nncon defined in line 16; used 7 times
Last modified: 1986-01-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1158
Valid CSS Valid XHTML 1.0 Strict