]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/vl/noop.c
exec(2): fix prototypes
[plan9front.git] / sys / src / cmd / vl / noop.c
1 #include        "l.h"
2
3 void
4 noops(void)
5 {
6         Prog *p, *p1, *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                         if(p->to.type == D_FCREG ||
55                            p->to.type == D_MREG) {
56                                 p->mark |= LABEL|SYNC;
57                                 break;
58                         }
59                         if(p->from.type == D_FCREG ||
60                            p->from.type == D_MREG) {
61                                 p->mark |= LABEL|SYNC;
62                                 addnop(p);
63                                 addnop(p);
64                                 nop.mfrom.count += 2;
65                                 nop.mfrom.outof += 2;
66                                 break;
67                         }
68                         break;
69
70                 /* too hard, just leave alone */
71                 case ACASE:
72                 case ASYSCALL:
73                 case AWORD:
74                 case ATLBWR:
75                 case ATLBWI:
76                 case ATLBP:
77                 case ATLBR:
78                         p->mark |= LABEL|SYNC;
79                         break;
80
81                 case ANOR:
82                         if(p->to.type == D_REG && p->to.reg == REGZERO)
83                                 p->mark |= LABEL|SYNC;
84                         break;
85
86                 case ARET:
87                         /* special form of RET is BECOME */
88                         if(p->from.type == D_CONST)
89                                 if(p->from.offset > curbecome)
90                                         curbecome = p->from.offset;
91
92                         if(p->link != P)
93                                 p->link->mark |= LABEL;
94                         break;
95
96                 case ANOP:
97                         q1 = p->link;
98                         q->link = q1;           /* q is non-nop */
99                         q1->mark |= p->mark;
100                         continue;
101
102                 case ABCASE:
103                         p->mark |= LABEL|SYNC;
104                         goto dstlab;
105
106                 case ABGEZAL:
107                 case ABLTZAL:
108                 case AJAL:
109                         if(curtext != P)
110                                 curtext->mark &= ~LEAF;
111
112                 case AJMP:
113                 case ABEQ:
114                 case ABGEZ:
115                 case ABGTZ:
116                 case ABLEZ:
117                 case ABLTZ:
118                 case ABNE:
119                 case ABFPT:
120                 case ABFPF:
121                         p->mark |= BRANCH;
122
123                 dstlab:
124                         q1 = p->cond;
125                         if(q1 != P) {
126                                 while(q1->as == ANOP) {
127                                         q1 = q1->link;
128                                         p->cond = q1;
129                                 }
130                                 if(!(q1->mark & LEAF))
131                                         q1->mark |= LABEL;
132                         } else
133                                 p->mark |= LABEL;
134                         q1 = p->link;
135                         if(q1 != P)
136                                 q1->mark |= LABEL;
137                         break;
138                 }
139                 q = p;
140         }
141
142         if(curtext && curtext->from.sym) {
143                 curtext->from.sym->frame = curframe;
144                 curtext->from.sym->become = curbecome;
145                 if(curbecome > maxbecome)
146                         maxbecome = curbecome;
147         }
148
149         if(debug['b'])
150                 print("max become = %d\n", maxbecome);
151         xdefine("ALEFbecome", STEXT, maxbecome);
152
153         curtext = 0;
154         for(p = firstp; p != P; p = p->link) {
155                 switch(p->as) {
156                 case ATEXT:
157                         curtext = p;
158                         break;
159                 case AJAL:
160                         if(curtext != P && curtext->from.sym != S && curtext->to.offset >= 0) {
161                                 o = maxbecome - curtext->from.sym->frame;
162                                 if(o <= 0)
163                                         break;
164                                 /* calling a become or calling a variable */
165                                 if(p->to.sym == S || p->to.sym->become) {
166                                         curtext->to.offset += o;
167                                         if(debug['b']) {
168                                                 curp = p;
169                                                 print("%D calling %D increase %d\n",
170                                                         &curtext->from, &p->to, o);
171                                         }
172                                 }
173                         }
174                         break;
175                 }
176         }
177
178         for(p = firstp; p != P; p = p->link) {
179                 o = p->as;
180                 switch(o) {
181                 case ATEXT:
182                         curtext = p;
183                         autosize = p->to.offset + 4;
184                         if(autosize <= 4)
185                         if(curtext->mark & LEAF) {
186                                 p->to.offset = -4;
187                                 autosize = 0;
188                         }
189
190                         q = p;
191                         if(autosize) {
192                                 q = prg();
193                                 q->as = AADD;
194                                 q->line = p->line;
195                                 q->from.type = D_CONST;
196                                 q->from.offset = -autosize;
197                                 q->to.type = D_REG;
198                                 q->to.reg = REGSP;
199
200                                 q->link = p->link;
201                                 p->link = q;
202                         } else
203                         if(!(curtext->mark & LEAF)) {
204                                 if(debug['v'])
205                                         Bprint(&bso, "save suppressed in: %s\n",
206                                                 curtext->from.sym->name);
207                                 Bflush(&bso);
208                                 curtext->mark |= LEAF;
209                         }
210
211                         if(curtext->mark & LEAF) {
212                                 if(curtext->from.sym)
213                                         curtext->from.sym->type = SLEAF;
214                                 break;
215                         }
216
217                         q1 = prg();
218                         q1->as = AMOVW;
219                         q1->line = p->line;
220                         q1->from.type = D_REG;
221                         q1->from.reg = REGLINK;
222                         q1->to.type = D_OREG;
223                         q1->from.offset = 0;
224                         q1->to.reg = REGSP;
225
226                         q1->link = q->link;
227                         q->link = q1;
228                         break;
229
230                 case ARET:
231                         nocache(p);
232                         if(p->from.type == D_CONST)
233                                 goto become;
234                         if(curtext->mark & LEAF) {
235                                 if(!autosize) {
236                                         p->as = AJMP;
237                                         p->from = zprg.from;
238                                         p->to.type = D_OREG;
239                                         p->to.offset = 0;
240                                         p->to.reg = REGLINK;
241                                         p->mark |= BRANCH;
242                                         break;
243                                 }
244
245                                 p->as = AADD;
246                                 p->from.type = D_CONST;
247                                 p->from.offset = autosize;
248                                 p->to.type = D_REG;
249                                 p->to.reg = REGSP;
250
251                                 q = prg();
252                                 q->as = AJMP;
253                                 q->line = p->line;
254                                 q->to.type = D_OREG;
255                                 q->to.offset = 0;
256                                 q->to.reg = REGLINK;
257                                 q->mark |= BRANCH;
258
259                                 q->link = p->link;
260                                 p->link = q;
261                                 break;
262                         }
263                         p->as = AMOVW;
264                         p->from.type = D_OREG;
265                         p->from.offset = 0;
266                         p->from.reg = REGSP;
267                         p->to.type = D_REG;
268                         p->to.reg = 2;
269
270                         q = p;
271                         if(autosize) {
272                                 q = prg();
273                                 q->as = AADD;
274                                 q->line = p->line;
275                                 q->from.type = D_CONST;
276                                 q->from.offset = autosize;
277                                 q->to.type = D_REG;
278                                 q->to.reg = REGSP;
279
280                                 q->link = p->link;
281                                 p->link = q;
282                         }
283
284                         q1 = prg();
285                         q1->as = AJMP;
286                         q1->line = p->line;
287                         q1->to.type = D_OREG;
288                         q1->to.offset = 0;
289                         q1->to.reg = 2;
290                         q1->mark |= BRANCH;
291
292                         q1->link = q->link;
293                         q->link = q1;
294                         break;
295
296                 become:
297                         if(curtext->mark & LEAF) {
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                                 p->as = AADD;
310                                 p->from = zprg.from;
311                                 p->from.type = D_CONST;
312                                 p->from.offset = autosize;
313                                 p->to = zprg.to;
314                                 p->to.type = D_REG;
315                                 p->to.reg = REGSP;
316
317                                 break;
318                         }
319                         q = prg();
320                         q->line = p->line;
321                         q->as = AJMP;
322                         q->from = zprg.from;
323                         q->to = p->to;
324                         q->cond = p->cond;
325                         q->link = p->link;
326                         q->mark |= BRANCH;
327                         p->link = q;
328
329                         q = prg();
330                         q->line = p->line;
331                         q->as = AADD;
332                         q->from.type = D_CONST;
333                         q->from.offset = autosize;
334                         q->to.type = D_REG;
335                         q->to.reg = REGSP;
336                         q->link = p->link;
337                         p->link = q;
338
339                         p->as = AMOVW;
340                         p->from = zprg.from;
341                         p->from.type = D_OREG;
342                         p->from.offset = 0;
343                         p->from.reg = REGSP;
344                         p->to = zprg.to;
345                         p->to.type = D_REG;
346                         p->to.reg = REGLINK;
347
348                         break;
349                 }
350         }
351
352         curtext = P;
353         q = P;          /* p - 1 */
354         q1 = firstp;    /* top of block */
355         o = 0;          /* count of instructions */
356         for(p = firstp; p != P; p = p1) {
357                 p1 = p->link;
358                 o++;
359                 if(p->mark & NOSCHED){
360                         if(q1 != p){
361                                 sched(q1, q);
362                         }
363                         for(; p != P; p = p->link){
364                                 if(!(p->mark & NOSCHED))
365                                         break;
366                                 q = p;
367                         }
368                         p1 = p;
369                         q1 = p;
370                         o = 0;
371                         continue;
372                 }
373                 if(p->mark & (LABEL|SYNC)) {
374                         if(q1 != p)
375                                 sched(q1, q);
376                         q1 = p;
377                         o = 1;
378                 }
379                 if(p->mark & (BRANCH|SYNC)) {
380                         sched(q1, p);
381                         q1 = p1;
382                         o = 0;
383                 }
384                 if(o >= NSCHED) {
385                         sched(q1, p);
386                         q1 = p1;
387                         o = 0;
388                 }
389                 q = p;
390         }
391 }
392
393 void
394 addnop(Prog *p)
395 {
396         Prog *q;
397
398         q = prg();
399         q->as = ANOR;
400         q->line = p->line;
401         q->from.type = D_REG;
402         q->from.reg = REGZERO;
403         q->to.type = D_REG;
404         q->to.reg = REGZERO;
405
406         q->link = p->link;
407         p->link = q;
408 }
409
410 void
411 nocache(Prog *p)
412 {
413         p->optab = 0;
414         p->from.class = 0;
415         p->to.class = 0;
416 }