Bell 32V development
[unix-history] / usr / src / cmd / mip / optim.c
CommitLineData
57230eac
TL
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
11int oflag = 0;
12
13NODE *
14fortarg( 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 */
30short revrel[] ={ EQ, NE, GE, GT, LE, LT, UGE, UGT, ULE, ULT };
31NODE *
32optim(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
171ispow2( 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
178nncon( p ) NODE *p; {
179 /* is p a constant without a name */
180 return( p->op == ICON && p->rval == NONAME );
181 }