Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20120322180441

Diff

Diff from 1.48 to:

Annotations

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

Annotated File View

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