home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / mip / optim.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  3.6 KB  |  182 lines

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