source: mainline/uspace/app/pcc/cc/ccom/optim.c@ 8a23fef

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 8a23fef was a7de7182, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 14 years ago

Added pcc source tree (contents of pcc-1.0.0.tgz)

  • Property mode set to 100644
File size: 9.1 KB
Line 
1/* $Id: optim.c,v 1.36.2.1 2011/03/01 17:40:21 ragge Exp $ */
2/*
3 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * Redistributions of source code and documentation must retain the above
10 * copyright notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditionsand the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed or owned by Caldera
17 * International, Inc.
18 * Neither the name of Caldera International, Inc. nor the names of other
19 * contributors may be used to endorse or promote products derived from
20 * this software without specific prior written permission.
21 *
22 * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
23 * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
27 * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
31 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
32 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 */
35
36# include "pass1.h"
37
38# define SWAP(p,q) {sp=p; p=q; q=sp;}
39# define RCON(p) (p->n_right->n_op==ICON)
40# define RO(p) p->n_right->n_op
41# define RV(p) p->n_right->n_lval
42# define LCON(p) (p->n_left->n_op==ICON)
43# define LO(p) p->n_left->n_op
44# define LV(p) p->n_left->n_lval
45
46/* remove left node */
47static NODE *
48zapleft(NODE *p)
49{
50 NODE *q;
51
52 q = p->n_left;
53 nfree(p->n_right);
54 nfree(p);
55 return q;
56}
57
58/*
59 * fortran function arguments
60 */
61static NODE *
62fortarg(NODE *p)
63{
64 if( p->n_op == CM ){
65 p->n_left = fortarg( p->n_left );
66 p->n_right = fortarg( p->n_right );
67 return(p);
68 }
69
70 while( ISPTR(p->n_type) ){
71 p = buildtree( UMUL, p, NIL );
72 }
73 return( optim(p) );
74}
75
76 /* mapping relationals when the sides are reversed */
77short revrel[] ={ EQ, NE, GE, GT, LE, LT, UGE, UGT, ULE, ULT };
78
79/*
80 * local optimizations, most of which are probably
81 * machine independent
82 */
83NODE *
84optim(NODE *p)
85{
86 struct attr *ap;
87 int o, ty;
88 NODE *sp, *q;
89 int i;
90 TWORD t;
91
92 t = BTYPE(p->n_type);
93 if( oflag ) return(p);
94
95 ty = coptype(p->n_op);
96 if( ty == LTYPE ) return(p);
97
98 if( ty == BITYPE ) p->n_right = optim(p->n_right);
99 p->n_left = optim(p->n_left);
100
101 /* collect constants */
102again: o = p->n_op;
103 switch(o){
104
105 case SCONV:
106 case PCONV:
107 return( clocal(p) );
108
109 case FORTCALL:
110 p->n_right = fortarg( p->n_right );
111 break;
112
113 case ADDROF:
114 if (LO(p) == TEMP)
115 return p;
116 if( LO(p) != NAME ) cerror( "& error" );
117
118 if( !andable(p->n_left) ) return(p);
119
120 LO(p) = ICON;
121
122 setuleft:
123 /* paint over the type of the left hand side with the type of the top */
124 p->n_left->n_type = p->n_type;
125 p->n_left->n_df = p->n_df;
126 p->n_left->n_ap = p->n_ap;
127 q = p->n_left;
128 nfree(p);
129 return q;
130
131 case UMUL:
132 if (LO(p) == ADDROF) {
133 q = p->n_left->n_left;
134 nfree(p->n_left);
135 nfree(p);
136 return q;
137 }
138 if( LO(p) != ICON ) break;
139 LO(p) = NAME;
140 goto setuleft;
141
142 case RS:
143 if (LCON(p) && RCON(p) && conval(p->n_left, o, p->n_right))
144 goto zapright;
145
146 ap = attr_find(p->n_ap, ATTR_BASETYP);
147
148 if (LO(p) == RS && RCON(p->n_left) && RCON(p) &&
149 (RV(p) + RV(p->n_left)) < ap->atypsz) {
150 /* two right-shift by constants */
151 RV(p) += RV(p->n_left);
152 p->n_left = zapleft(p->n_left);
153 }
154#if 0
155 else if (LO(p) == LS && RCON(p->n_left) && RCON(p)) {
156 RV(p) -= RV(p->n_left);
157 if (RV(p) < 0)
158 o = p->n_op = LS, RV(p) = -RV(p);
159 p->n_left = zapleft(p->n_left);
160 }
161#endif
162 if (RO(p) == ICON) {
163 if (RV(p) < 0) {
164 RV(p) = -RV(p);
165 p->n_op = LS;
166 goto again;
167 }
168#ifdef notyet /* must check for side effects, --a >> 32; */
169 if (RV(p) >= tsize(p->n_type, p->n_df, p->n_sue) &&
170 ISUNSIGNED(p->n_type)) { /* ignore signed shifts */
171 /* too many shifts */
172 tfree(p->n_left);
173 nfree(p->n_right);
174 p->n_op = ICON; p->n_lval = 0; p->n_sp = NULL;
175 } else
176#endif
177 /* avoid larger shifts than type size */
178 if (RV(p) >= ap->atypsz) {
179 RV(p) = RV(p) %
180 attr_find(p->n_ap, ATTR_BASETYP)->atypsz;
181 werror("shift larger than type");
182 }
183 if (RV(p) == 0)
184 p = zapleft(p);
185 }
186 break;
187
188 case LS:
189 if (LCON(p) && RCON(p) && conval(p->n_left, o, p->n_right))
190 goto zapright;
191
192 ap = attr_find(p->n_ap, ATTR_BASETYP);
193
194 if (LO(p) == LS && RCON(p->n_left) && RCON(p)) {
195 /* two left-shift by constants */
196 RV(p) += RV(p->n_left);
197 p->n_left = zapleft(p->n_left);
198 }
199#if 0
200 else if (LO(p) == RS && RCON(p->n_left) && RCON(p)) {
201 RV(p) -= RV(p->n_left);
202 p->n_left = zapleft(p->n_left);
203 }
204#endif
205 if (RO(p) == ICON) {
206 if (RV(p) < 0) {
207 RV(p) = -RV(p);
208 p->n_op = RS;
209 goto again;
210 }
211#ifdef notyet /* must check for side effects */
212 if (RV(p) >= tsize(p->n_type, p->n_df, p->n_sue)) {
213 /* too many shifts */
214 tfree(p->n_left);
215 nfree(p->n_right);
216 p->n_op = ICON; p->n_lval = 0; p->n_sp = NULL;
217 } else
218#endif
219 /* avoid larger shifts than type size */
220 if (RV(p) >= ap->atypsz) {
221 RV(p) = RV(p) %
222 attr_find(p->n_ap, ATTR_BASETYP)->atypsz;
223 werror("shift larger than type");
224 }
225 if (RV(p) == 0)
226 p = zapleft(p);
227 }
228 break;
229
230 case MINUS:
231 if (LCON(p) && RCON(p) && p->n_left->n_sp == p->n_right->n_sp) {
232 /* link-time constants, but both are the same */
233 /* solve it now by forgetting the symbols */
234 p->n_left->n_sp = p->n_right->n_sp = NULL;
235 }
236 if( !nncon(p->n_right) ) break;
237 RV(p) = -RV(p);
238 o = p->n_op = PLUS;
239
240 case MUL:
241 case PLUS:
242 case AND:
243 case OR:
244 case ER:
245 /* commutative ops; for now, just collect constants */
246 /* someday, do it right */
247 if( nncon(p->n_left) || ( LCON(p) && !RCON(p) ) )
248 SWAP( p->n_left, p->n_right );
249 /* make ops tower to the left, not the right */
250 if( RO(p) == o ){
251 NODE *t1, *t2, *t3;
252 t1 = p->n_left;
253 sp = p->n_right;
254 t2 = sp->n_left;
255 t3 = sp->n_right;
256 /* now, put together again */
257 p->n_left = sp;
258 sp->n_left = t1;
259 sp->n_right = t2;
260 p->n_right = t3;
261 }
262 if(o == PLUS && LO(p) == MINUS && RCON(p) && RCON(p->n_left) &&
263 conval(p->n_right, MINUS, p->n_left->n_right)){
264 zapleft:
265
266 q = p->n_left->n_left;
267 nfree(p->n_left->n_right);
268 nfree(p->n_left);
269 p->n_left = q;
270 }
271 if( RCON(p) && LO(p)==o && RCON(p->n_left) &&
272 conval( p->n_right, o, p->n_left->n_right ) ){
273 goto zapleft;
274 }
275 else if( LCON(p) && RCON(p) && conval( p->n_left, o, p->n_right ) ){
276 zapright:
277 nfree(p->n_right);
278 q = makety(p->n_left, p->n_type, p->n_qual,
279 p->n_df, p->n_ap);
280 nfree(p);
281 return clocal(q);
282 }
283
284 /* change muls to shifts */
285
286 if( o == MUL && nncon(p->n_right) && (i=ispow2(RV(p)))>=0){
287 if( i == 0 ) { /* multiplication by 1 */
288 goto zapright;
289 }
290 o = p->n_op = LS;
291 p->n_right->n_type = INT;
292 p->n_right->n_df = NULL;
293 RV(p) = i;
294 }
295
296 /* change +'s of negative consts back to - */
297 if( o==PLUS && nncon(p->n_right) && RV(p)<0 ){
298 RV(p) = -RV(p);
299 o = p->n_op = MINUS;
300 }
301
302 /* remove ops with RHS 0 */
303 if ((o == PLUS || o == MINUS || o == OR || o == ER) &&
304 nncon(p->n_right) && RV(p) == 0) {
305 goto zapright;
306 }
307 break;
308
309 case DIV:
310 if( nncon( p->n_right ) && p->n_right->n_lval == 1 )
311 goto zapright;
312 if (LCON(p) && RCON(p) && conval(p->n_left, DIV, p->n_right))
313 goto zapright;
314 if (RCON(p) && ISUNSIGNED(p->n_type) && (i=ispow2(RV(p))) > 0) {
315 p->n_op = RS;
316 RV(p) = i;
317 q = p->n_right;
318 if(tsize(q->n_type, q->n_df, q->n_ap) > SZINT)
319 p->n_right = makety(q, INT, 0, 0, MKAP(INT));
320
321 break;
322 }
323 break;
324
325 case MOD:
326 if (RCON(p) && ISUNSIGNED(p->n_type) && ispow2(RV(p)) > 0) {
327 p->n_op = AND;
328 RV(p) = RV(p) -1;
329 break;
330 }
331 break;
332
333 case EQ:
334 case NE:
335 case LT:
336 case LE:
337 case GT:
338 case GE:
339 case ULT:
340 case ULE:
341 case UGT:
342 case UGE:
343 if( !LCON(p) ) break;
344
345 /* exchange operands */
346
347 sp = p->n_left;
348 p->n_left = p->n_right;
349 p->n_right = sp;
350 p->n_op = revrel[p->n_op - EQ ];
351 break;
352
353#ifdef notyet
354 case ASSIGN:
355 /* Simple test to avoid two branches */
356 if (RO(p) != NE)
357 break;
358 q = p->n_right;
359 if (RCON(q) && RV(q) == 0 && LO(q) == AND &&
360 RCON(q->n_left) && (i = ispow2(RV(q->n_left))) &&
361 q->n_left->n_type == INT) {
362 q->n_op = RS;
363 RV(q) = i;
364 }
365 break;
366#endif
367 }
368
369 return(p);
370 }
371
372int
373ispow2(CONSZ c)
374{
375 int i;
376 if( c <= 0 || (c&(c-1)) ) return(-1);
377 for( i=0; c>1; ++i) c >>= 1;
378 return(i);
379}
380
381int
382nncon( p ) NODE *p; {
383 /* is p a constant without a name */
384 return( p->n_op == ICON && p->n_sp == NULL );
385 }
Note: See TracBrowser for help on using the repository browser.