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