diff options
author | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2015-10-30 11:43:39 -0400 |
---|---|---|
committer | Quentin Carbonneaux <quentin.carbonneaux@yale.edu> | 2015-10-30 13:20:42 -0400 |
commit | 62ff1f2f50c70573e2613cf616d53dd89c5461f2 (patch) | |
tree | a4214f840cb54161a542bbcf6856f962086ae588 /lisc | |
parent | e68aac2cef83469656bfb5703290a9e850cadbff (diff) | |
download | roux-62ff1f2f50c70573e2613cf616d53dd89c5461f2.tar.gz |
fix two bugs in spiller
1. In limit(), there can be machine registers that are live, thus we need to iterate from 0 (not Tmp0) to ntmp in the for loop building the array. 2. When an instruction can have a memory argument, we must not reload arguments that got spilled and were not live. Instead, the must be replaced by SLOT() arguments.
Diffstat (limited to 'lisc')
-rw-r--r-- | lisc/spill.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/lisc/spill.c b/lisc/spill.c index 15d4448..662df3f 100644 --- a/lisc/spill.c +++ b/lisc/spill.c @@ -192,7 +192,7 @@ limit(Bits *b, int k, Bits *fst) maxt = nt; } i = 0; - for (t=Tmp0; t<ntmp; t++) + for (t=0; t<ntmp; t++) if (BGET(*b, t)) { BCLR(*b, t); tarr[i++] = t; @@ -270,7 +270,7 @@ void spill(Fn *fn) { Blk *b, *s1, *s2, *hd; - int n, m, z, l, t; + int n, m, z, l, t, lvarg[2]; Bits u, v, w; Ins *i; int j, s; @@ -355,8 +355,11 @@ spill(Fn *fn) t = i->to.val; if (BGET(v, t)) BCLR(v, t); - else + else { + u = v; limit(&v, NReg-1, 0); + reloads(&u, &v); + } s = tmp[t].slot; } w = (Bits){{0}}; @@ -377,6 +380,7 @@ spill(Fn *fn) } break; case RTmp: + lvarg[m] = BGET(v, t); BSET(v, t); if (j-- <= 0) BSET(w, t); @@ -384,6 +388,18 @@ spill(Fn *fn) } u = v; limit(&v, NReg, &w); + for (m=0; m<2; m++) + if (rtype(i->arg[m]) == RTmp) { + t = i->arg[m].val; + if (!BGET(v, t)) { + /* do not reload if the + * the temporary was dead + */ + if (!lvarg[m]) + BCLR(u, t); + i->arg[m] = slot(t); + } + } reloads(&u, &v); if (s != -1) store(i->to, s); |