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