Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20120422210740

Diff

Diff from 1.4 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/cc/cxxcom/optim.c

Annotated File View

plunky
1.4
1 /*      $Id: optim.c,v 1.4 2012/04/22 21:07:41 plunky Exp $     */
ragge
1.1
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 */
47 static NODE *
48 zapleft(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  */
61 static NODE *
62 fortarg(NODE *p)
63 {
64         ifp->n_op == CM ){
65                 p->n_left = fortargp->n_left );
66                 p->n_right = fortargp->n_right );
67                 return(p);
68         }
69
70         whileISPTR(p->n_type) ){
71                 p = buildtreeUMULpNIL );
72         }
73         returnoptim(p) );
74 }
75
76         /* mapping relationals when the sides are reversed */
77 short revrel[] ={ EQNEGEGTLELTUGEUGTULEULT };
78
79 /*
80  * local optimizations, most of which are probably
81  * machine independent
82  */
83 NODE *
84 optim(NODE *p)
85 {
86         int oty;
87         NODE *sp, *q;
plunky
1.2
88         OFFSZ sz;
89         int i;
ragge
1.1
90
plunky
1.3
91         if (odebugreturn(p);
ragge
1.1
92
93         ty = coptype(p->n_op);
94         ifty == LTYPE ) return(p);
95
96         ifty == BITYPE ) p->n_right = optim(p->n_right);
97         p->n_left = optim(p->n_left);
98
99         /* collect constants */
100 again:  o = p->n_op;
101         switch(o){
102
103         case SCONV:
104                 if (concast(p->n_leftp->n_type)) {
105                         q = p->n_left;
106                         nfree(p);
107                         p = q;
108                         break;
109                 }
110                 /* FALLTHROUGH */
111         case PCONV:
112                 if (p->n_type != VOID)
113                         p = clocal(p);
114                 break;
115
116         case FORTCALL:
117                 p->n_right = fortargp->n_right );
118                 break;
119
120         case ADDROF:
121                 if (LO(p) == TEMP)
122                         break;
123                 ifLO(p) != NAME ) cerror"& error" );
124
125                 if( !andable(p->n_left) && !statinit)
126                         break;
127
128                 LO(p) = ICON;
129
130                 setuleft:
131                 /* paint over the type of the left hand side with the type of the top */
132                 p->n_left->n_type = p->n_type;
133                 p->n_left->n_df = p->n_df;
134                 p->n_left->n_ap = p->n_ap;
135                 q = p->n_left;
136                 nfree(p);
137                 p = q;
138                 break;
139
140         case NOT:
141         case UMINUS:
142         case COMPL:
143                 if (LCON(p) && conval(p->n_leftop->n_left))
144                         p = nfree(p);
145                 break;
146
147         case UMUL:
148                 /* Do not discard ADDROF TEMP's */
149                 if (LO(p) == ADDROF && LO(p->n_left) != TEMP) {
150                         q = p->n_left->n_left;
151                         nfree(p->n_left);
152                         nfree(p);
153                         p = q;
154                         break;
155                 }
156                 ifLO(p) != ICON ) break;
157                 LO(p) = NAME;
158                 goto setuleft;
159
160         case RS:
161                 if (LCON(p) && RCON(p) && conval(p->n_leftop->n_right))
162                         goto zapright;
163
164                 sz = tsize(p->n_typep->n_dfp->n_ap);
165
166                 if (LO(p) == RS && RCON(p->n_left) && RCON(p) &&
167                     (RV(p) + RV(p->n_left)) < sz) {
168                         /* two right-shift  by constants */
169                         RV(p) += RV(p->n_left);
170                         p->n_left = zapleft(p->n_left);
171                 }
172 #if 0
173                   else if (LO(p) == LS && RCON(p->n_left) && RCON(p)) {
174                         RV(p) -= RV(p->n_left);
175                         if (RV(p) < 0)
176                                 o = p->n_op = LSRV(p) = -RV(p);
177                         p->n_left = zapleft(p->n_left);
178                 }
179 #endif
180                 if (RO(p) == ICON) {
181                         if (RV(p) < 0) {
182                                 RV(p) = -RV(p);
183                                 p->n_op = LS;
184                                 goto again;
185                         }
186 #ifdef notyet /* must check for side effects, --a >> 32; */
187                         if (RV(p) >= tsize(p->n_typep->n_dfp->n_sue) &&
188                             ISUNSIGNED(p->n_type)) { /* ignore signed shifts */
189                                 /* too many shifts */
190                                 tfree(p->n_left);
191                                 nfree(p->n_right);
192                                 p->n_op = ICONp->n_lval = 0p->n_sp = NULL;
193                         } else
194 #endif
195                         /* avoid larger shifts than type size */
196                         if (RV(p) >= sz) {
197                                 RV(p) = RV(p) % sz;
198                                 werror("shift larger than type");
199                         }
200                         if (RV(p) == 0)
201                                 p = zapleft(p);
202                 }
203                 break;
204
205         case LS:
206                 if (LCON(p) && RCON(p) && conval(p->n_leftop->n_right))
207                         goto zapright;
208
209                 sz = tsize(p->n_typep->n_dfp->n_ap);
210
211                 if (LO(p) == LS && RCON(p->n_left) && RCON(p)) {
212                         /* two left-shift  by constants */
213                         RV(p) += RV(p->n_left);
214                         p->n_left = zapleft(p->n_left);
215                 }
216 #if 0
217                   else if (LO(p) == RS && RCON(p->n_left) && RCON(p)) {
218                         RV(p) -= RV(p->n_left);
219                         p->n_left = zapleft(p->n_left);
220                 }
221 #endif
222                 if (RO(p) == ICON) {
223                         if (RV(p) < 0) {
224                                 RV(p) = -RV(p);
225                                 p->n_op = RS;
226                                 goto again;
227                         }
228 #ifdef notyet /* must check for side effects */
229                         if (RV(p) >= tsize(p->n_typep->n_dfp->n_sue)) {
230                                 /* too many shifts */
231                                 tfree(p->n_left);
232                                 nfree(p->n_right);
233                                 p->n_op = ICONp->n_lval = 0p->n_sp = NULL;
234                         } else
235 #endif
236                         /* avoid larger shifts than type size */
237                         if (RV(p) >= sz) {
238                                 RV(p) = RV(p) % sz;
239                                 werror("shift larger than type");
240                         }
241                         if (RV(p) == 0)  
242                                 p = zapleft(p);
243                 }
244                 break;
245
246         case MINUS:
247                 if (LCON(p) && RCON(p) && p->n_left->n_sp == p->n_right->n_sp) {
248                         /* link-time constants, but both are the same */
249                         /* solve it now by forgetting the symbols */
250                         p->n_left->n_sp = p->n_right->n_sp = NULL;
251                 }
252                 if( !nncon(p->n_right) ) break;
253                 RV(p) = -RV(p);
254                 o = p->n_op = PLUS;
255
256         case MUL:
257                 /*
258                  * Check for u=(x-y)+z; where all vars are pointers to
259                  * the same struct. This has two advantages:
260                  * 1: avoid a mul+div
261                  * 2: even if not allowed, people may get surprised if this
262                  *    calculation do not give correct result if using
263                  *    unaligned structs.
264                  */
265                 if (p->n_type == INTPTR && RCON(p) &&
266                     LO(p) == DIV && RCON(p->n_left) &&
267                     RV(p) == RV(p->n_left) &&
268                     LO(p->n_left) == MINUS) {
269                         q = p->n_left->n_left;
270                         if (q->n_left->n_type == PTR+STRTY &&
271                             q->n_right->n_type == PTR+STRTY &&
272                             strmemb(q->n_left->n_ap) ==
273                             strmemb(q->n_right->n_ap)) {
274                                 p = zapleft(p);
275                                 p = zapleft(p);
276                         }
277                 }
278                 /* FALLTHROUGH */
279         case PLUS:
280         case AND:
281         case OR:
282         case ER:
283                 /* commutative ops; for now, just collect constants */
284                 /* someday, do it right */
285                 ifnncon(p->n_left) || ( LCON(p) && !RCON(p) ) )
286                         SWAPp->n_leftp->n_right );
287                 /* make ops tower to the left, not the right */
288                 ifRO(p) == o ){
289                         NODE *t1, *t2, *t3;
290                         t1 = p->n_left;
291                         sp = p->n_right;
292                         t2 = sp->n_left;
293                         t3 = sp->n_right;
294                         /* now, put together again */
295                         p->n_left = sp;
296                         sp->n_left = t1;
297                         sp->n_right = t2;
298                         sp->n_type = p->n_type;
299                         p->n_right = t3;
300                         }
301                 if(o == PLUS && LO(p) == MINUS && RCON(p) && RCON(p->n_left) &&
302                    conval(p->n_rightMINUSp->n_left->n_right)){
303                         zapleft:
304
305                         q = p->n_left->n_left;
306                         nfree(p->n_left->n_right);
307                         nfree(p->n_left);
308                         p->n_left = q;
309                 }
310                 ifRCON(p) && LO(p)==o && RCON(p->n_left) &&
311                     convalp->n_rightop->n_left->n_right ) ){
312                         goto zapleft;
313                         }
314                 else ifLCON(p) && RCON(p) && convalp->n_leftop->n_right ) ){
315                         zapright:
316                         nfree(p->n_right);
317                         q = makety(p->n_leftp->n_typep->n_qual,
318                             p->n_dfp->n_ap);
319                         nfree(p);
320                         p = clocal(q);
321                         break;
322                         }
323
324                 /* change muls to shifts */
325
326                 ifo == MUL && nncon(p->n_right) && (i=ispow2(RV(p)))>=0){
327                         ifi == 0 ) { /* multiplication by 1 */
328                                 goto zapright;
329                                 }
330                         o = p->n_op = LS;
331                         p->n_right->n_type = INT;
332                         p->n_right->n_df = NULL;
333                         RV(p) = i;
334                         }
335
336                 /* change +'s of negative consts back to - */
337                 ifo==PLUS && nncon(p->n_right) && RV(p)<0 ){
338                         RV(p) = -RV(p);
339                         o = p->n_op = MINUS;
340                         }
341
342                 /* remove ops with RHS 0 */
343                 if ((o == PLUS || o == MINUS || o == OR || o == ER) &&
344                     nncon(p->n_right) && RV(p) == 0) {
345                         goto zapright;
346                 }
347                 break;
348
349         case DIV:
350                 ifnnconp->n_right ) && p->n_right->n_lval == 1 )
351                         goto zapright;
352                 if (LCON(p) && RCON(p) && conval(p->n_leftDIVp->n_right))
353                         goto zapright;
354                 if (RCON(p) && ISUNSIGNED(p->n_type) && (i=ispow2(RV(p))) > 0) {
355                         p->n_op = RS;
356                         RV(p) = i;
357                         q = p->n_right;
358                         if(tsize(q->n_typeq->n_dfq->n_ap) > SZINT)
359                                 p->n_right = makety(qINT000);
360
361                         break;
362                 }
363                 break;
364
365         case MOD:
366                 if (RCON(p) && ISUNSIGNED(p->n_type) && ispow2(RV(p)) > 0) {
367                         p->n_op = AND;
368                         RV(p) = RV(p) -1;
369                         break;
370                 }
371                 break;
372
373         case EQ:
374         case NE:
375         case LT:
376         case LE:
377         case GT:
378         case GE:
379         case ULT:
380         case ULE:
381         case UGT:
382         case UGE:
383                 if( !LCON(p) ) break;
384
385                 /* exchange operands */
386
387                 sp = p->n_left;
388                 p->n_left = p->n_right;
389                 p->n_right = sp;
390                 p->n_op = revrel[p->n_op - EQ ];
391                 break;
392
393 #ifdef notyet
394         case ASSIGN:
395                 /* Simple test to avoid two branches */
396                 if (RO(p) != NE)
397                         break;
398                 q = p->n_right;
399                 if (RCON(q) && RV(q) == 0 && LO(q) == AND &&
400                     RCON(q->n_left) && (i = ispow2(RV(q->n_left))) &&
401                     q->n_left->n_type == INT) {
402                         q->n_op = RS;
403                         RV(q) = i;
404                 }
405                 break;
406 #endif
407         }
408
409         return(p);
410         }
411
412 int
413 ispow2(CONSZ c)
414 {
415         int i;
416         ifc <= 0 || (c&(c-1)) ) return(-1);
417         fori=0c>1; ++ic >>= 1;
418         return(i);
419 }
420
421 int
plunky
1.4
422 nncon(NODE *p)
423 {
ragge
1.1
424         /* is p a constant without a name */
425         returnp->n_op == ICON && p->n_sp == NULL );
plunky
1.4
426 }
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-11-01 12:58 +0100