Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20040510213558

Diff

Diff from 1.1 to:

Annotations

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

Annotated File View

ragge
1.1
1 /*      $Id: optim2.c,v 1.1 2004/05/10 21:35:58 ragge Exp $     */
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
32 extern int saving;
33
34 void saveip(struct interpass *ip);
35 void deljumps(void);
36 void deltemp(NODE *p);
37 void optdump(struct interpass *ip);
38
39 static SIMPLEQ_HEAD(, interpassipole = SIMPLEQ_HEAD_INITIALIZER(ipole);
40
41 static struct rsv {
42         struct rsv *next;
43         int fpoff;
44         TWORD type;
45         int use;
46 } *rsv;
47
48 static void
49 addcand(TWORD typeint offint avoid)
50 {
51         struct rsv *w = rsv;
52
53         while (w != NULL) {
54                 if (w->type == type && w->fpoff == off) {
55                         if (avoid)
56                                 w->use = -1;
57                         else if (w->use > 0)
58                                 w->use++;
59                         return;
60                 }
61                 w = w->next;
62         }
63         w = tmpalloc(sizeof(*w));
64         w->type = type;
65         w->fpoff = off;
66         w->use = avoid ? -1 : 1;
67         w->next = rsv;
68         rsv = w;
69 }
70
71 /*
72  * walk through the tree and count the number of (possible)
73  * temporary nodes.
74  */
75 static void
76 cntuse(NODE *p)
77 {
78         NODE *l = p->n_left;
79         NODE *r = p->n_right;
80
81         if (p->n_op == UMUL && l->n_op == REG && l->n_rval == FPREG) {
82                 /* found a candidate for register */
83                 addcand(p->n_type0ISVOL(p->n_qual << TSHIFT));
84         } else if (p->n_op == UMUL && l->n_op == PLUS &&
85             l->n_right->n_op == ICON && 
86              (l->n_left->n_op == REG && l->n_left->n_rval == FPREG)) {
87                 /* The same as above */
88                 addcand(p->n_typel->n_right->n_lval,
89                     ISVOL(p->n_qual << TSHIFT));
90         } else if (p->n_op == PLUS && l->n_op == REG && l->n_rval == FPREG &&
91             p->n_right->n_op == ICON) {
92                 /* Address taken of temporary, avoid register */
93                 addcand(DECREF(p->n_type), r->n_lval1);
94         } else {
95                 if (optype(p->n_op) == BITYPE)
96                         cntuse(r);
97                 if (optype(p->n_op) != LTYPE)
98                         cntuse(l);
99         }
100 }
101
102 /*
103  * Assign non-temporary registers to variables.
104  * Cannot do it if:
105  * - address is taken of the temporary
106  * - variable is declared "volatile".
107  */
108 static void
109 asgregs(void)
110 {
111         struct interpass *ip;
112         struct rsv *w;
113         
114
115         rsv = NULL;
116
117         /* Loop over the function to do a usage count */
118         SIMPLEQ_FOREACH(ip, &ipolesqelem) {
119                 if (ip->type != IP_NODE)
120                         continue;
121                 cntuse(ip->ip_node);
122         }
123
124         /* Check which nodes that shall be converted to registers */
125         w = rsv;
126         for (w = rsvww = w->next) {
127                 if (w->use < 0)
128                         continue;
129                 printf("type %x off %d use %d\n"w->typew->fpoffw->use);
130         }
131
132         /* Convert found nodes to registers */
133 }
134
135 void
136 saveip(struct interpass *ip)
137 {
138         struct interpass *prol;
139
140         SIMPLEQ_INSERT_TAIL(&ipoleipsqelem);
141
142         if (ip->type != IP_EPILOG)
143                 return;
144         saving = -1;
145
146         deljumps();     /* Delete redundant jumps and dead code */
147         asgregs();      /* Assign non-temporary registers */
148
149         prol = SIMPLEQ_FIRST(&ipole);
150         prol->ip_auto = ip->ip_auto;
151         prol->ip_regs = ip->ip_regs;
152
153 #ifdef MYOPTIM
154         myoptim(prol);
155 #endif
156
157         while ((ip = SIMPLEQ_FIRST(&ipole))) {
158                 SIMPLEQ_REMOVE_HEAD(&ipolesqelem);
159                 pass2_compile(ip);
160         }
161 }
162
163 void
164 deljumps()
165 {
166         struct interpass *ip, *n;
167         int gotone;
168
169 again:  gotone = 0;
170
171         SIMPLEQ_FOREACH(ip, &ipolesqelem) {
172                 if (ip->type == IP_EPILOG)
173                         return;
174                 if (ip->type != IP_NODE)
175                         continue;
176                 n = ip->sqelem.sqe_next;
177                 /* Check for nodes without side effects */
178                 if (ip->ip_node->n_op != GOTO)
179                         continue;
180                 switch (n->type) {
181                 case IP_NODE:
182                         tfree(n->ip_node);
183                         ip->sqelem.sqe_next = n->sqelem.sqe_next;
184                         break;
185                 case IP_DEFLAB:
186                         if (ip->ip_node->n_left->n_lval != n->ip_lbl)
187                                 continue;
188                         tfree(ip->ip_node);
189                         *ip = *n;
190                         break;
191                 default:
192                         continue;
193                 }
194                 gotone = 1;
195         }
196         if (gotone)
197                 goto again;
198 }
199
200 void
201 optdump(struct interpass *ip)
202 {
203         static char *nm[] = { "node""prolog""newblk""epilog""locctr",
204                 "deflab""defnam""asm" };
205         printf("type %s\n"nm[ip->type-1]);
206         switch (ip->type) {
207         case IP_NODE:
208                 fwalk(ip->ip_nodee2print0);
209                 break;
210         case IP_DEFLAB:
211                 printf("label " LABFMT "\n"ip->ip_lbl);
212                 break;
213         case IP_ASM:
214                 printf(": %s\n"ip->ip_asm);
215                 break;
216         }
217 }
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-21 05:05 +0100