wip on a simpler slot handling

This commit is contained in:
Quentin Carbonneaux 2015-09-29 17:23:55 -04:00
parent fdbff25a61
commit 5e5d0a1e99
3 changed files with 52 additions and 71 deletions

View file

@ -341,60 +341,6 @@ seljmp(Blk *b, Fn *fn)
b->jmp.type = JXJc + Cne; 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; typedef struct AClass AClass;
struct AClass { struct AClass {
@ -693,8 +639,8 @@ isel(Fn *fn)
int64_t sz; int64_t sz;
for (n=Tmp0; n<fn->ntmp; n++) for (n=Tmp0; n<fn->ntmp; n++)
fn->tmp[n].spill = 0; fn->tmp[n].spill = -1;
memset(fn->svec, 0, sizeof fn->svec); fn->stk0 = 0;
/* lower arguments */ /* lower arguments */
for (b=fn->start, i=b->ins; i-b->ins < b->nins; i++) 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 */ /* assign slots to fast allocs */
for (b=fn->start, i=b->ins; i-b->ins < b->nins; i++) b = fn->start;
if (OAlloc <= i->op && i->op <= OAlloc1) { assert(NAlign == 3 && "change n=4 and sz /= 4 below");
if (rtype(i->arg[0]) != RCon) for (al=OAlloc, n=4; al<=OAlloc1; al++, n*=2)
break; for (i=b->ins; i-b->ins < b->nins; i++)
sz = fn->con[i->arg[0].val].val; if (i->op == al) {
if (sz < 0 || sz >= INT_MAX-3) if (rtype(i->arg[0]) != RCon)
diag("isel: invalid alloc size"); break;
n = 16 / (1 << (NAlign-1)); sz = fn->con[i->arg[0].val].val;
sz = (sz + n-1) / n; if (sz < 0 || sz >= INT_MAX-3)
al = i->op - OAlloc; diag("isel: invalid alloc size");
s = slota(sz, al, fn->svec); sz = (sz + n-1) & -n;
fn->tmp[i->to.val].spill = s; sz /= 4;
i->to = R; fn->tmp[i->to.val].spill = fn->stk0;
} fn->stk0 -= sz;
i->to = R;
}
for (b=fn->start; b; b=b->link) { for (b=fn->start; b; b=b->link) {
for (sb=(Blk*[3]){b->s1, b->s2, 0}; *sb; sb++) for (sb=(Blk*[3]){b->s1, b->s2, 0}; *sb; sb++)

View file

@ -249,7 +249,7 @@ struct Fn {
int retty; int retty;
Blk **rpo; Blk **rpo;
ulong reg; ulong reg;
int svec[NAlign]; int stk0, stk1;
char name[NString]; char name[NString];
}; };

33
lisc/slot.txt Normal file
View file

@ -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