1#include "all.h"
2
3/* require use, maintains use counts */
4void
5memopt(Fn *fn)
6{
7 Blk *b;
8 Ins *i, *l;
9 Tmp *t;
10 Use *u, *ue;
11 int s, k;
12
13 /* promote uniform stack slots to temporaries */
14 b = fn->start;
15 for (i=b->ins; i<&b->ins[b->nins]; i++) {
16 if (Oalloc > i->op || i->op > Oalloc1)
17 continue;
18 /* specific to NAlign == 3 */
19 assert(rtype(i->to) == RTmp);
20 t = &fn->tmp[i->to.val];
21 if (t->ndef != 1)
22 goto Skip;
23 k = -1;
24 s = -1;
25 for (u=t->use; u != &t->use[t->nuse]; u++) {
26 if (u->type != UIns)
27 goto Skip;
28 l = u->u.ins;
29 if (isload(l->op))
30 if (s == -1 || s == loadsz(l)) {
31 s = loadsz(l);
32 continue;
33 }
34 if (isstore(l->op))
35 if (req(i->to, l->arg[1]) && !req(i->to, l->arg[0]))
36 if (s == -1 || s == storesz(l))
37 if (k == -1 || k == optab[l->op].argcls[0][0]) {
38 s = storesz(l);
39 k = optab[l->op].argcls[0][0];
40 continue;
41 }
42 goto Skip;
43 }
44 /* get rid of the alloc and replace uses */
45 *i = (Ins){.op = Onop};
46 t->ndef--;
47 ue = &t->use[t->nuse];
48 for (u=t->use; u!=ue; u++) {
49 l = u->u.ins;
50 if (isstore(l->op)) {
51 l->cls = k;
52 l->op = Ocopy;
53 l->to = l->arg[1];
54 l->arg[1] = R;
55 t->nuse--;
56 t->ndef++;
57 } else {
58 if (k == -1)
59 err("slot %%%s is read but never stored to",
60 fn->tmp[l->arg[0].val].name);
61 /* try to turn loads into copies so we
62 * can eliminate them later */
63 switch(l->op) {
64 case Oloadsw:
65 case Oloaduw:
66 if (k == Kl)
67 goto Extend;
68 /* fall through */
69 case Oload:
70 if (KBASE(k) != KBASE(l->cls))
71 l->op = Ocast;
72 else
73 l->op = Ocopy;
74 break;
75 default:
76 Extend:
77 l->op = Oextsb + (l->op - Oloadsb);
78 break;
79 }
80 }
81 }
82 Skip:;
83 }
84 if (debug['M']) {
85 fprintf(stderr, "\n> After memory optimization:\n");
86 printfn(fn, stderr);
87 }
88}
89