commit 5e5d0a1e999a4d41614c9cf3db2b68ce031026f1
parent fdbff25a61d47cc7ed9aed3ada0e0e414e1b559b
Author: Quentin Carbonneaux <quentin.carbonneaux@yale.edu>
Date: Tue, 29 Sep 2015 17:23:55 -0400
wip on a simpler slot handling
Diffstat:
3 files changed, 52 insertions(+), 71 deletions(-)
diff --git a/lisc/isel.c b/lisc/isel.c
@@ -341,60 +341,6 @@ seljmp(Blk *b, Fn *fn)
b->jmp.type = JXJc + Cne;
}
-int
-slota(int sz, int al /* log2 */, int *sa)
-{
- int j, k, s, l, a, ret;
-
- a = 1 << al;
- l = sz;
-
- if (l > a) {
- /* for large slots, we just
- * tack them on the next max
- * alignment slot available
- * todo, could sophisticate
- */
- l = (l + a-1) & ~(a-1);
- s = sa[NAlign-1] + l;
- ret = s;
- for (j=0, k=1; j<NAlign; j++, k*=2) {
- l = (l + k-1) & ~(k-1);
- sa[j] = sa[NAlign-1] + l;
- }
- } else {
- j = al;
- s = sa[j] + a;
- ret = s;
- Shift:
- if (j < NAlign-1 && s < sa[j+1])
- /* ........-----------...
- * ^ ^ ^
- * sa[j] sa[j]+a sa[j+1]
- *
- * we have to skip to the
- * next large whole
- */
- s = sa[j+1];
-
- for (k=0; k<=j; k++)
- /* move all smaller holes
- * that we contain with us
- */
- if (sa[k] == sa[j])
- sa[k] = s;
-
- if (j < NAlign-1 && s > sa[j+1]) {
- /* we were in a bigger hole,
- * it needs to shift further
- */
- s = sa[++j] + (a *= 2);
- goto Shift;
- }
- }
- return ret;
-}
-
typedef struct AClass AClass;
struct AClass {
@@ -693,8 +639,8 @@ isel(Fn *fn)
int64_t sz;
for (n=Tmp0; n<fn->ntmp; n++)
- fn->tmp[n].spill = 0;
- memset(fn->svec, 0, sizeof fn->svec);
+ fn->tmp[n].spill = -1;
+ fn->stk0 = 0;
/* lower arguments */
for (b=fn->start, i=b->ins; i-b->ins < b->nins; i++)
@@ -735,20 +681,22 @@ isel(Fn *fn)
}
/* assign slots to fast allocs */
- for (b=fn->start, i=b->ins; i-b->ins < b->nins; i++)
- if (OAlloc <= i->op && i->op <= OAlloc1) {
- if (rtype(i->arg[0]) != RCon)
- break;
- sz = fn->con[i->arg[0].val].val;
- if (sz < 0 || sz >= INT_MAX-3)
- diag("isel: invalid alloc size");
- n = 16 / (1 << (NAlign-1));
- sz = (sz + n-1) / n;
- al = i->op - OAlloc;
- s = slota(sz, al, fn->svec);
- fn->tmp[i->to.val].spill = s;
- i->to = R;
- }
+ b = fn->start;
+ assert(NAlign == 3 && "change n=4 and sz /= 4 below");
+ for (al=OAlloc, n=4; al<=OAlloc1; al++, n*=2)
+ for (i=b->ins; i-b->ins < b->nins; i++)
+ if (i->op == al) {
+ if (rtype(i->arg[0]) != RCon)
+ break;
+ sz = fn->con[i->arg[0].val].val;
+ if (sz < 0 || sz >= INT_MAX-3)
+ diag("isel: invalid alloc size");
+ sz = (sz + n-1) & -n;
+ sz /= 4;
+ fn->tmp[i->to.val].spill = fn->stk0;
+ fn->stk0 -= sz;
+ i->to = R;
+ }
for (b=fn->start; b; b=b->link) {
for (sb=(Blk*[3]){b->s1, b->s2, 0}; *sb; sb++)
diff --git a/lisc/lisc.h b/lisc/lisc.h
@@ -249,7 +249,7 @@ struct Fn {
int retty;
Blk **rpo;
ulong reg;
- int svec[NAlign];
+ int stk0, stk1;
char name[NString];
};
diff --git a/lisc/slot.txt b/lisc/slot.txt
@@ -0,0 +1,33 @@
+Plan for new slot computations:
+
+- reverse the allocation of all stack slots
+ so that isel slots go below spill locations
+- the fast allocs must be allocated by decreasing
+ alignment constraints
+- instead of the svec vector, we simply need two
+ numbers that contain the size of both the locals
+ and spills (stk0, stk1)
+- maybe it's time to include small alignments
+- use Tmp.spill == -1 to mark unallocated slots
+
+Layout:
+
+ ---------- rbp = 0 [16]
+ | << padding 1 >>
+ | .. spills ..
+ | <- enforce align 16
+ | .. align 16 ..
+ | .. align 8 ..
+ | .. align 4 ..
+ | << padding 0 >>
+ ---------- rsp = 0 [16]
+
+ padding 0: inserted at last minute by the code
+ emitter to respect the ABI
+ padding 1: inserted at the beginning of spill
+ it can be 4 or 0
+
+Examples:
+
+ if the first local is aligned 4 of size 4, its slot
+ number will be set 0, to emit the proper offset to