BSD 4 development
[unix-history] / usr / src / cmd / mip / optim.c
CommitLineData
18dc15e5
BJ
1static 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
12int oflag = 0;
13
14NODE *
15fortarg( 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 */
31short revrel[] ={ EQ, NE, GE, GT, LE, LT, UGE, UGT, ULE, ULT };
32NODE *
33optim(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
172ispow2( 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
179nncon( p ) NODE *p; {
180 /* is p a constant without a name */
181 return( p->in.op == ICON && p->tn.rval == NONAME );
182 }