Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20020325225236

Diff

Diff from 1.2 to:

Annotations

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

Annotated File View

ragge
1.2
1 #if 0
ragge
1.1
2 static char *sccsid ="@(#)optim.c       4.7 (Berkeley) 1/8/86";
ragge
1.2
3 #endif
ragge
1.1
4
5 # include "pass1.h"
6
7 # define SWAP(p,q) {sp=p; p=q; q=sp;}
8 # define RCON(p) (p->in.right->in.op==ICON)
9 # define RO(p) p->in.right->in.op
10 # define RV(p) p->in.right->tn.lval
11 # define LCON(p) (p->in.left->in.op==ICON)
12 # define LO(p) p->in.left->in.op
13 # define LV(p) p->in.left->tn.lval
14
15         /* is p a constant without a name */
16 # define nncon(p)       ((p)->in.op == ICON && (p)->tn.rval == NONAME)
17
18 int oflag = 0;
19
ragge
1.2
20 /*
21  * fortran function arguments
22  */
ragge
1.1
23 NODE *
ragge
1.2
24 fortarg(NODE *p)
25 {
ragge
1.1
26         ifp->in.op == CM ){
27                 p->in.left = fortargp->in.left );
28                 p->in.right = fortargp->in.right );
29                 return(p);
ragge
1.2
30         }
ragge
1.1
31
32         whileISPTR(p->in.type) ){
33                 p = buildtreeUNARY MULpNIL );
ragge
1.2
34         }
ragge
1.1
35         returnoptim(p) );
ragge
1.2
36 }
ragge
1.1
37
38         /* mapping relationals when the sides are reversed */
39 short revrel[] ={ EQNEGEGTLELTUGEUGTULEULT };
ragge
1.2
40
41 /*
42  * local optimizations, most of which are probably
43  * machine independent
44  */
ragge
1.1
45 NODE *
ragge
1.2
46 optim(NODE *p)
47 {
48         int oty;
ragge
1.1
49         NODE *sp;
50         int i;
51         TWORD t;
52
53         if( (t=BTYPE(p->in.type))==ENUMTY || t==MOETY ) econvert(p);
54         ifoflag ) return(p);
55         ty = optypeo=p->in.op);
56         ifty == LTYPE ) return(p);
57
58         ifty == BITYPE ) p->in.right = optim(p->in.right);
59         p->in.left = optim(p->in.left);
60
61         /* collect constants */
62
63         switch(o){
64
65         case SCONV:
66         case PCONV:
67                 returnclocal(p) );
68
69         case FORTCALL:
70                 p->in.right = fortargp->in.right );
71                 break;
72
73         case UNARY AND:
74                 ifLO(p) != NAME || !andable(p->in.left) ) return(p);
75
76                 LO(p) = ICON;
77
78                 setuleft:
79                 /* paint over the type of the left hand side with the type of the top */
80                 p->in.left->in.type = p->in.type;
81                 p->in.left->fn.cdim = p->fn.cdim;
82                 p->in.left->fn.csiz = p->fn.csiz;
83                 p->in.op = FREE;
84                 returnp->in.left );
85
86         case UNARY MUL:
87                 ifLO(p) != ICON ) break;
88                 LO(p) = NAME;
89                 goto setuleft;
90
91         case MINUS:
92                 if( !nncon(p->in.right) ) break;
93                 RV(p) = -RV(p);
94                 o = p->in.op = PLUS;
95
96         case MUL:
97         case PLUS:
98         case AND:
99         case OR:
100         case ER:
101                 /* commutative ops; for now, just collect constants */
102                 /* someday, do it right */
103                 ifnncon(p->in.left) || ( LCON(p) && !RCON(p) ) ) SWAPp->in.leftp->in.right );
104                 /* make ops tower to the left, not the right */
105                 ifRO(p) == o ){
106                         NODE *t1, *t2, *t3;
107                         t1 = p->in.left;
108                         sp = p->in.right;
109                         t2 = sp->in.left;
110                         t3 = sp->in.right;
111                         /* now, put together again */
112                         p->in.left = sp;
113                         sp->in.left = t1;
114                         sp->in.right = t2;
115                         p->in.right = t3;
116                         }
117                 if(o == PLUS && LO(p) == MINUS && RCON(p) && RCON(p->in.left) &&
118                    conval(p->in.rightMINUSp->in.left->in.right)){
119                         zapleft:
120                         RO(p->in.left) = FREE;
121                         LO(p) = FREE;
122                         p->in.left = p->in.left->in.left;
123                 }
124                 ifRCON(p) && LO(p)==o && RCON(p->in.left) &&
125                     convalp->in.rightop->in.left->in.right ) ){
126                         goto zapleft;
127                         }
128                 else ifLCON(p) && RCON(p) &&
129                          convalp->in.leftop->in.right ) ){
130                         zapright:
131                         RO(p) = FREE;
132                         p->in.left = maketyp->in.leftp->in.typep->fn.cdimp->fn.csiz );
133                         p->in.op = FREE;
134                         returnclocalp->in.left ) );
135                         }
136                 /* FALL THROUGH */
137
138         case ASG MUL:
139                 /* change muls to adds or shifts */
140
141                 if( (o == MUL || o == ASG MUL) &&
142                     nncon(p->in.right) && (i=ispow2(RV(p)))>=0){
143                         ifi == 0 ) /* multiplication by 1 */
144                                 goto zapright;
145                         /* c2 will turn 'i << 1' into 'i + i' for us */
146                         else {
147                                 p->in.op = (asgop(o) ? ASG LS : LS);
148                                 o = p->in.op;
149                                 p->in.right->in.type = p->in.right->fn.csiz = INT;
150                                 RV(p) = i;
151                                 }
152                         }
153
154                 /* change +'s of negative consts back to - */
155                 ifo==PLUS && nncon(p->in.right) && RV(p)<0 ){
156                         RV(p) = -RV(p);
157                         o = p->in.op = MINUS;
158                         }
159                 /* FALL THROUGH */
160         case ASG AND:
161         case ASG PLUS:
162         case ASG MINUS:
163         case RS:
164         case LS:
165                 /* Operations with zero */
166                 ifnncon(p->in.right) && RV(p) == 0 ) {
167                         ifo == MUL || o == ASG MUL ||
168                             o == AND || o == ASG AND ) {
169                                 ifasgop(o) )
170                                         p->in.op = ASSIGN;
171                                 else ifoptype(LO(p)) == LTYPE ) {
172                                         p->in.op = FREE;
173                                         LO(p) = FREE;
174                                         p = p->in.right;
175                                         }
176                                 else
177                                         p->in.op = COMOP/* side effects */
178                                 }
179                         else ifo == PLUS || o == MINUS ||
180                                  o == ASG PLUS || o == ASG MINUS ||
181                                  o == OR || o == ER ||
182                                  o == LS || o == RS )
183                                 goto zapright;
184                         }
185                 ifo != LS && o != RS )
186                         break;
187                 /* FALL THROUGH */
188
189         case ASG RS:
190         case ASG LS:
191                 if( !ISUNSIGNED(p->in.left->in.type) )
192                         break;
193                 ifp->in.right->in.op == ICON &&
194                     p->in.right->tn.lval < 0 ) {
195                         /*
196                          * Technically negative shifts are illegal
197                          * but we can support them, at least with
198                          * constants; you take potluck with variables.
199                          */
200                         p->in.right->tn.lval = -p->in.right->tn.lval;
201                         switcho ){
202                         case LS:        p->in.op = RSbreak;
203                         case ASG LS:    p->in.op = ASG RSbreak;
204                         case RS:        p->in.op = LSbreak;
205                         case ASG RS:    p->in.op = ASG LSbreak;
206                                 }
207                         }
208                 break;
209
210         case ASG DIV:
211         case DIV:
212                 ifnnconp->in.right ) ){
213                         ifRV(p) == 0 ) uerror("division by zero");
214                         else ifRV(p) == 1 ) goto zapright;
215                         /* Unsigned division by a power of two */
216                         else if( (i=ispow2(RV(p)))>=0 &&
217                                  (ISUNSIGNED(p->in.left->in.type) ||
218                                   ISUNSIGNED(p->in.right->in.type)) ){
219                                 p->in.op = (asgop(o) ? ASG RS : RS);
220                                 p->in.right->in.type = p->in.right->fn.csiz = INT;
221                                 RV(p) = i;
222                                 }
223                         }
224                 break;
225
226         case ASG MOD:
227         case MOD:
228                 ifnncon(p->in.right) ){
229                         ifRV(p) == 0 ) uerror("modulus of zero");
230                         else ifRV(p) == 1 ){ /* mod by one gives zero */
231                                 RV(p) = 0;
232                                 ifasgop(o) )
233                                         p->in.op = ASSIGN;
234                                 else ifoptype(LO(p)) == LTYPE ) {
235                                         p->in.op = FREE;
236                                         LO(p) = FREE;
237                                         p = p->in.right;
238                                         }
239                                 else
240                                         p->in.op = COMOP/* side effects */
241                                 }
242                         else if ((i=ispow2(RV(p)))>=0 &&
243                                  (ISUNSIGNED(p->in.left->in.type) ||
244                                   ISUNSIGNED(p->in.right->in.type)) ){
245                                 /* Unsigned mod by a power of two */
246                                 p->in.op = (asgop(o) ? ASG AND : AND);
247                                 RV(p)--;
248                                 }
249                         }
250                 break;
251
252         case EQ:
253         case NE:
254         case LT:
255         case LE:
256         case GT:
257         case GE:
258         case ULT:
259         case ULE:
260         case UGT:
261         case UGE:
262                 if( !LCON(p) ) break;
263
264                 /* exchange operands */
265
266                 sp = p->in.left;
267                 p->in.left = p->in.right;
268                 p->in.right = sp;
269                 p->in.op = revrel[p->in.op - EQ ];
270                 break;
271
272                 }
273
274         return(p);
275         }
276
ragge
1.2
277 int
278 ispow2(CONSZ c)
279 {
280         int i;
ragge
1.1
281         ifc <= 0 || (c&(c-1)) ) return(-1);
282         fori=0c>1; ++ic >>= 1;
283         return(i);
ragge
1.2
284 }
FishEye: Open Source License registered to PCC.
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-12-22 06:40 +0100