diff options
author | Quentin Carbonneaux <quentin@c9x.me> | 2019-03-12 21:15:21 +0100 |
---|---|---|
committer | Quentin Carbonneaux <quentin@c9x.me> | 2019-03-13 22:02:29 +0100 |
commit | b777cd6c4becf0d834f8fa549315fa11918a53be (patch) | |
tree | 10e19572ac0f336c5248565323d6a9c71dceeed1 | |
parent | fd65f4275be6dc6603be9610e88c55b8bfc1dc62 (diff) | |
download | roux-b777cd6c4becf0d834f8fa549315fa11918a53be.tar.gz |
simple heuristic to reuse stack slots
On test/spill1.ssa, the stack frame of the function f() goes from 56 bytes to 40 bytes. That's a reduction of close to 30%. This patch also opens the door to folding operations on spill slots. For example movl $15, %r15d addl -X(%rbp), %r15d movl %r15d, -X(%rbp) should become add $15, -X(%rbp) when %r15d is not used afterwards.
-rw-r--r-- | spill.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/spill.c b/spill.c index 42f0c05..f0b593a 100644 --- a/spill.c +++ b/spill.c @@ -309,7 +309,7 @@ void spill(Fn *fn) { Blk *b, *s1, *s2, *hd, **bp; - int j, l, t, k, lvarg[2]; + int j, l, t, k, s, lvarg[2]; uint n; BSet u[1], v[1], w[1]; Ins *i; @@ -407,6 +407,7 @@ spill(Fn *fn) if (!req(i->to, R)) { assert(rtype(i->to) == RTmp); t = i->to.val; + s = tmp[t].slot; if (bshas(v, t)) bsclr(v, t); else { @@ -440,6 +441,13 @@ spill(Fn *fn) bsset(v, t); if (j-- <= 0) bsset(w, t); + else if (!lvarg[n]) { + /* recycle the slot of + * i->to when possible + */ + if (tmp[t].slot == -1) + tmp[t].slot = s; + } break; } bscopy(u, v); @@ -447,9 +455,12 @@ spill(Fn *fn) for (n=0; n<2; n++) if (rtype(i->arg[n]) == RTmp) { t = i->arg[n].val; - if (!bshas(v, t)) { + if (bshas(v, t)) { + if (tmp[t].slot == s) + tmp[t].slot = -1; + } else { /* do not reload if the - * the temporary was dead + * argument is dead */ if (!lvarg[n]) bsclr(u, t); |