Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20160402201623

Diff

Diff from 1.63 to:

Annotations

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

Annotated File View

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