Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20040515121433

Diff

Diff from 1.3 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/mip/optim2.c

Annotated File View

ragge
1.3
1 /*      $Id: optim2.c,v 1.3 2004/05/15 12:14:43 ragge Exp $     */
ragge
1.1
2 /*
3  * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "pass2.h"
30 #include "external.h"
31
ragge
1.3
32 #include <string.h>
33
ragge
1.1
34 extern int saving;
35
36 void saveip(struct interpass *ip);
37 void deljumps(void);
38 void deltemp(NODE *p);
39 void optdump(struct interpass *ip);
40
41 static SIMPLEQ_HEAD(, interpassipole = SIMPLEQ_HEAD_INITIALIZER(ipole);
42
43 static struct rsv {
44         struct rsv *next;
45         int fpoff;
46         TWORD type;
47         int use;
48 } *rsv;
49
50 static void
51 addcand(TWORD typeint offint avoid)
52 {
53         struct rsv *w = rsv;
54
55         while (w != NULL) {
56                 if (w->type == type && w->fpoff == off) {
57                         if (avoid)
58                                 w->use = -1;
59                         else if (w->use > 0)
60                                 w->use++;
61                         return;
62                 }
63                 w = w->next;
64         }
65         w = tmpalloc(sizeof(*w));
66         w->type = type;
67         w->fpoff = off;
68         w->use = avoid ? -1 : 1;
69         w->next = rsv;
70         rsv = w;
71 }
72
73 /*
74  * walk through the tree and count the number of (possible)
75  * temporary nodes.
76  */
77 static void
78 cntuse(NODE *p)
79 {
80         NODE *l = p->n_left;
81         NODE *r = p->n_right;
82
83         if (p->n_op == UMUL && l->n_op == REG && l->n_rval == FPREG) {
84                 /* found a candidate for register */
85                 addcand(p->n_type0ISVOL(p->n_qual << TSHIFT));
86         } else if (p->n_op == UMUL && l->n_op == PLUS &&
87             l->n_right->n_op == ICON && 
88              (l->n_left->n_op == REG && l->n_left->n_rval == FPREG)) {
89                 /* The same as above */
90                 addcand(p->n_typel->n_right->n_lval,
91                     ISVOL(p->n_qual << TSHIFT));
92         } else if (p->n_op == PLUS && l->n_op == REG && l->n_rval == FPREG &&
93             p->n_right->n_op == ICON) {
94                 /* Address taken of temporary, avoid register */
95                 addcand(DECREF(p->n_type), r->n_lval1);
96         } else {
97                 if (optype(p->n_op) == BITYPE)
98                         cntuse(r);
99                 if (optype(p->n_op) != LTYPE)
100                         cntuse(l);
101         }
102 }
103
104 /*
ragge
1.2
105  * Insert a node into the register stack.
106  */
107 static void
108 insert(struct rsv *wstruct rsv **savedint maxregs)
109 {
110         int ijsize;
111
112         size = szty(w->type);
113
114         /* Find reg move position */
115         for (i = 0i < maxregsi++) {
116                 if (saved[i] == NULL)
117                         continue;
118                 if (saved[i]->use > w->use)
119                         break;
120         }
121         /* Move down other regs */
122         for (j = sizej < ij++)
123                 saved[j-size] = saved[j];
124
125         /* Insert new reg pointer */
126         if (i-size >= 0) {
127                 saved[i-size] = w;
128                 for (j = i-size+1j < ij++)
129                         saved[j] = NULL;
130         }
131 }
132
133 /* Help routine to rconvert() */
134 static int
135 matches(TWORD typeint offstruct rsv **rsvint maxregs)
136 {
137         int i;
138
139         for (i = 0i < maxregsi++)
140                 if (rsv[i] && rsv[i]->type == type && rsv[i]->fpoff == off)
141                         return i;
142         return -1;
143 }
144
145 /* Help routine to rconvert() */
146 static void
147 modify(NODE *pint reg)
148 {
149         tfree(p->n_left);
150         p->n_op = REG;
151         p->n_rval = p->n_rall = reg + MINRVAR;
152         p->n_lval = 0;
153 }
154
155 /*
156  * walk through the tree and convert nodes to registers
157  */
158 static void
159 rconvert(NODE *pstruct rsv **rsvint maxregs)
160 {
161         NODE *l = p->n_left;
162         NODE *r = p->n_right;
163         int i;
164
165         if (p->n_op == UMUL && l->n_op == REG && l->n_rval == FPREG) {
166                 /* found a candidate for register */
167                 if ((i = matches(p->n_type0rsvmaxregs)) >= 0)
168                         modify(pi);
169         } else if (p->n_op == UMUL && l->n_op == PLUS &&
170             l->n_right->n_op == ICON && 
171              (l->n_left->n_op == REG && l->n_left->n_rval == FPREG)) {
172                 /* The same as above */
173                 if ((i = matches(p->n_type,
174                     l->n_right->n_lvalrsvmaxregs)) >= 0)
175                         modify(pi);
176 #if 0
177         } else if (p->n_op == PLUS && l->n_op == REG && l->n_rval == FPREG &&
178             p->n_right->n_op == ICON) {
179                 /* Address taken of temporary, avoid register */
180                 addcand(DECREF(p->n_type), r->n_lval1);
181 #endif
182         } else {
183                 if (optype(p->n_op) == BITYPE)
184                         rconvert(rrsvmaxregs);
185                 if (optype(p->n_op) != LTYPE)
186                         rconvert(lrsvmaxregs);
187         }
188 }
189
190 /*
ragge
1.1
191  * Assign non-temporary registers to variables.
192  * Cannot do it if:
193  * - address is taken of the temporary
194  * - variable is declared "volatile".
195  */
ragge
1.2
196 static int
ragge
1.1
197 asgregs(void)
198 {
199         struct interpass *ip;
ragge
1.2
200         struct rsv *w, **saved;
201         int imaxregs = MAXRVAR - MINRVAR + 1;
ragge
1.1
202
ragge
1.2
203         if (maxregs == 0)
204                 return MAXRVAR/* No register usage */
ragge
1.1
205         rsv = NULL;
206
207         /* Loop over the function to do a usage count */
208         SIMPLEQ_FOREACH(ip, &ipolesqelem) {
209                 if (ip->type != IP_NODE)
210                         continue;
211                 cntuse(ip->ip_node);
212         }
213         /* Check which nodes that shall be converted to registers */
ragge
1.2
214         saved = tmpalloc(sizeof(struct rsv *) * maxregs);
215         memset(saved0sizeof(struct rsv *) * maxregs);
ragge
1.1
216         w = rsv;
217         for (w = rsvww = w->next) {
218                 if (w->use < 0)
ragge
1.2
219                         continue/* Not allowed to be in register */
220
221                 /* XXX check here if type is allowed to be in register */
222
223                 insert(wsavedmaxregs);
ragge
1.1
224         }
225
226         /* Convert found nodes to registers */
ragge
1.2
227         SIMPLEQ_FOREACH(ip, &ipolesqelem) {
228                 if (ip->type != IP_NODE)
229                         continue;
230                 rconvert(ip->ip_nodesavedmaxregs);
231         }
232         for (i = 0i < maxregsi++)
233                 if (saved[i] != NULL)
234                         break;
235         return MINRVAR+i-1;
ragge
1.1
236 }
237
238 void
239 saveip(struct interpass *ip)
240 {
241         struct interpass *prol;
ragge
1.2
242         int regs;
ragge
1.1
243
244         SIMPLEQ_INSERT_TAIL(&ipoleipsqelem);
245
246         if (ip->type != IP_EPILOG)
247                 return;
248         saving = -1;
249
250         deljumps();     /* Delete redundant jumps and dead code */
ragge
1.2
251         regs = asgregs();       /* Assign non-temporary registers */
252
253 #ifdef PCC_DEBUG
254         if (ip->ip_regs != MAXRVAR)
255                 comperr("register error");
256 #endif
ragge
1.1
257
258         prol = SIMPLEQ_FIRST(&ipole);
259         prol->ip_auto = ip->ip_auto;
ragge
1.2
260         prol->ip_regs = ip->ip_regs = regs;
ragge
1.1
261
262 #ifdef MYOPTIM
263         myoptim(prol);
264 #endif
265
266         while ((ip = SIMPLEQ_FIRST(&ipole))) {
267                 SIMPLEQ_REMOVE_HEAD(&ipolesqelem);
268                 pass2_compile(ip);
269         }
270 }
271
272 void
273 deljumps()
274 {
275         struct interpass *ip, *n;
276         int gotone;
277
278 again:  gotone = 0;
279
280         SIMPLEQ_FOREACH(ip, &ipolesqelem) {
281                 if (ip->type == IP_EPILOG)
282                         return;
283                 if (ip->type != IP_NODE)
284                         continue;
285                 n = ip->sqelem.sqe_next;
286                 /* Check for nodes without side effects */
287                 if (ip->ip_node->n_op != GOTO)
288                         continue;
289                 switch (n->type) {
290                 case IP_NODE:
291                         tfree(n->ip_node);
292                         ip->sqelem.sqe_next = n->sqelem.sqe_next;
293                         break;
294                 case IP_DEFLAB:
295                         if (ip->ip_node->n_left->n_lval != n->ip_lbl)
296                                 continue;
297                         tfree(ip->ip_node);
298                         *ip = *n;
299                         break;
300                 default:
301                         continue;
302                 }
303                 gotone = 1;
304         }
305         if (gotone)
306                 goto again;
307 }
308
309 void
310 optdump(struct interpass *ip)
311 {
312         static char *nm[] = { "node""prolog""newblk""epilog""locctr",
313                 "deflab""defnam""asm" };
314         printf("type %s\n"nm[ip->type-1]);
315         switch (ip->type) {
316         case IP_NODE:
317                 fwalk(ip->ip_nodee2print0);
318                 break;
319         case IP_DEFLAB:
320                 printf("label " LABFMT "\n"ip->ip_lbl);
321                 break;
322         case IP_ASM:
323                 printf(": %s\n"ip->ip_asm);
324                 break;
325         }
326 }
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-09-03 06:48 +0200