1 #include "l.h"
2
3 void
noops(void)4 noops(void)
5 {
6 Prog *p, *q, *q1;
7 int o, curframe, curbecome, maxbecome;
8
9 /*
10 * find leaf subroutines
11 * become sizes
12 * frame sizes
13 * strip NOPs
14 * expand RET
15 * expand BECOME pseudo
16 */
17
18 if(debug['v'])
19 Bprint(&bso, "%5.2f noops\n", cputime());
20 Bflush(&bso);
21
22 curframe = 0;
23 curbecome = 0;
24 maxbecome = 0;
25 curtext = 0;
26
27 q = P;
28 for(p = firstp; p != P; p = p->link) {
29
30 /* find out how much arg space is used in this TEXT */
31 if(p->to.type == D_OREG && p->to.reg == REGSP)
32 if(p->to.offset > curframe)
33 curframe = p->to.offset;
34
35 switch(p->as) {
36 case ATEXT:
37 if(curtext && curtext->from.sym) {
38 curtext->from.sym->frame = curframe;
39 curtext->from.sym->become = curbecome;
40 if(curbecome > maxbecome)
41 maxbecome = curbecome;
42 }
43 curframe = 0;
44 curbecome = 0;
45
46 p->mark |= LABEL|LEAF|SYNC;
47 if(p->link)
48 p->link->mark |= LABEL;
49 curtext = p;
50 break;
51
52 /* too hard, just leave alone */
53 case AMOVW:
54 case AMOV:
55 if(p->to.type == D_CTLREG) {
56 p->mark |= LABEL|SYNC;
57 break;
58 }
59 if(p->from.type == D_CTLREG) {
60 p->mark |= LABEL|SYNC;
61 break;
62 }
63 break;
64
65 /* too hard, just leave alone */
66 case ASYS:
67 case AWORD:
68 p->mark |= LABEL|SYNC;
69 break;
70
71 case ARET:
72 /* special form of RET is BECOME */
73 if(p->from.type == D_CONST)
74 if(p->from.offset > curbecome)
75 curbecome = p->from.offset;
76
77 if(p->link != P)
78 p->link->mark |= LABEL;
79 break;
80
81 case ANOP:
82 q1 = p->link;
83 q->link = q1; /* q is non-nop */
84 q1->mark |= p->mark;
85 continue;
86
87 case AJAL:
88 if(curtext != P)
89 curtext->mark &= ~LEAF;
90
91 case AJMP:
92 case ABEQ:
93 case ABGE:
94 case ABGEU:
95 case ABLT:
96 case ABLTU:
97 case ABNE:
98 p->mark |= BRANCH;
99
100 q1 = p->cond;
101 if(q1 != P) {
102 while(q1->as == ANOP) {
103 q1 = q1->link;
104 p->cond = q1;
105 }
106 if(!(q1->mark & LEAF))
107 q1->mark |= LABEL;
108 } else
109 p->mark |= LABEL;
110 q1 = p->link;
111 if(q1 != P)
112 q1->mark |= LABEL;
113 break;
114 }
115 q = p;
116 }
117
118 if(curtext && curtext->from.sym) {
119 curtext->from.sym->frame = curframe;
120 curtext->from.sym->become = curbecome;
121 if(curbecome > maxbecome)
122 maxbecome = curbecome;
123 }
124
125 if(debug['b'])
126 print("max become = %d\n", maxbecome);
127 xdefine("ALEFbecome", STEXT, maxbecome);
128
129 curtext = 0;
130 for(p = firstp; p != P; p = p->link) {
131 switch(p->as) {
132 case ATEXT:
133 curtext = p;
134 break;
135 case AJAL:
136 if(curtext != P && curtext->from.sym != S && curtext->to.offset >= 0) {
137 o = maxbecome - curtext->from.sym->frame;
138 if(o <= 0)
139 break;
140 /* calling a become or calling a variable */
141 if(p->to.sym == S || p->to.sym->become) {
142 curtext->to.offset += o;
143 if(debug['b']) {
144 curp = p;
145 print("%D calling %D increase %d\n",
146 &curtext->from, &p->to, o);
147 }
148 }
149 }
150 break;
151 }
152 }
153
154 for(p = firstp; p != P; p = p->link) {
155 o = p->as;
156 switch(o) {
157 case ATEXT:
158 curtext = p;
159 autosize = p->to.offset + ptrsize;
160 if(autosize <= ptrsize) {
161 if(curtext->mark & LEAF || autosize <= 0) {
162 p->to.offset = -ptrsize;
163 autosize = 0;
164 } else if(ptrsize == 4) {
165 p->to.offset = 4;
166 autosize = 8;
167 }
168 }
169
170 q = p;
171 if(autosize) {
172 q = prg();
173 q->as = AADD;
174 q->line = p->line;
175 q->from.type = D_CONST;
176 q->from.offset = -autosize;
177 q->to.type = D_REG;
178 q->to.reg = REGSP;
179
180 q->link = p->link;
181 p->link = q;
182 } else
183 if(!(curtext->mark & LEAF)) {
184 if(debug['v'])
185 Bprint(&bso, "save suppressed in: %s\n",
186 curtext->from.sym->name);
187 Bflush(&bso);
188 curtext->mark |= LEAF;
189 }
190
191 if(curtext->mark & LEAF) {
192 if(curtext->from.sym)
193 curtext->from.sym->type = SLEAF;
194 break;
195 }
196
197 q1 = prg();
198 q1->as = thechar == 'j' ? AMOV : AMOVW;
199 q1->line = p->line;
200 q1->from.type = D_REG;
201 q1->from.reg = REGLINK;
202 q1->to.type = D_OREG;
203 q1->from.offset = 0;
204 q1->to.reg = REGSP;
205
206 q1->link = q->link;
207 q->link = q1;
208 break;
209
210 case ARET:
211 nocache(p);
212 if(p->from.type == D_CONST)
213 goto become;
214 if(curtext->mark & LEAF) {
215 if(!autosize) {
216 p->as = AJMP;
217 p->from = zprg.from;
218 p->to.type = D_OREG;
219 p->to.offset = 0;
220 p->to.reg = REGLINK;
221 p->mark |= BRANCH;
222 break;
223 }
224
225 p->as = AADD;
226 p->from.type = D_CONST;
227 p->from.offset = autosize;
228 p->to.type = D_REG;
229 p->to.reg = REGSP;
230
231 q = prg();
232 q->as = AJMP;
233 q->line = p->line;
234 q->to.type = D_OREG;
235 q->to.offset = 0;
236 q->to.reg = REGLINK;
237 q->mark |= BRANCH;
238
239 q->link = p->link;
240 p->link = q;
241 break;
242 }
243 p->as = thechar == 'j' ? AMOV : AMOVW;
244 p->from.type = D_OREG;
245 p->from.offset = 0;
246 p->from.reg = REGSP;
247 p->to.type = D_REG;
248 p->to.reg = REGLINK;
249
250 q = p;
251 if(autosize) {
252 q = prg();
253 q->as = AADD;
254 q->line = p->line;
255 q->from.type = D_CONST;
256 q->from.offset = autosize;
257 q->to.type = D_REG;
258 q->to.reg = REGSP;
259
260 q->link = p->link;
261 p->link = q;
262 }
263
264 q1 = prg();
265 q1->as = AJMP;
266 q1->line = p->line;
267 q1->to.type = D_OREG;
268 q1->to.offset = 0;
269 q1->to.reg = REGLINK;
270 q1->mark |= BRANCH;
271
272 q1->link = q->link;
273 q->link = q1;
274 break;
275
276 become:
277 if(curtext->mark & LEAF) {
278
279 q = prg();
280 q->line = p->line;
281 q->as = AJMP;
282 q->from = zprg.from;
283 q->to = p->to;
284 q->cond = p->cond;
285 q->link = p->link;
286 q->mark |= BRANCH;
287 p->link = q;
288
289 p->as = AADD;
290 p->from = zprg.from;
291 p->from.type = D_CONST;
292 p->from.offset = autosize;
293 p->to = zprg.to;
294 p->to.type = D_REG;
295 p->to.reg = REGSP;
296
297 break;
298 }
299 q = prg();
300 q->line = p->line;
301 q->as = AJMP;
302 q->from = zprg.from;
303 q->to = p->to;
304 q->cond = p->cond;
305 q->link = p->link;
306 q->mark |= BRANCH;
307 p->link = q;
308
309 q = prg();
310 q->line = p->line;
311 q->as = AADD;
312 q->from.type = D_CONST;
313 q->from.offset = autosize;
314 q->to.type = D_REG;
315 q->to.reg = REGSP;
316 q->link = p->link;
317 p->link = q;
318
319 p->as = thechar == 'j' ? AMOV : AMOVW;
320 p->from = zprg.from;
321 p->from.type = D_OREG;
322 p->from.offset = 0;
323 p->from.reg = REGSP;
324 p->to = zprg.to;
325 p->to.type = D_REG;
326 p->to.reg = REGLINK;
327
328 break;
329 }
330 }
331
332 curtext = P;
333 }
334
335 void
nocache(Prog * p)336 nocache(Prog *p)
337 {
338 p->optab = 0;
339 p->from.class = 0;
340 p->to.class = 0;
341 }
342