wip on a simpler slot handling
This commit is contained in:
parent
fdbff25a61
commit
5e5d0a1e99
3 changed files with 52 additions and 71 deletions
74
lisc/isel.c
74
lisc/isel.c
|
@ -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,18 +681,20 @@ 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");
|
||||||
|
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)
|
if (rtype(i->arg[0]) != RCon)
|
||||||
break;
|
break;
|
||||||
sz = fn->con[i->arg[0].val].val;
|
sz = fn->con[i->arg[0].val].val;
|
||||||
if (sz < 0 || sz >= INT_MAX-3)
|
if (sz < 0 || sz >= INT_MAX-3)
|
||||||
diag("isel: invalid alloc size");
|
diag("isel: invalid alloc size");
|
||||||
n = 16 / (1 << (NAlign-1));
|
sz = (sz + n-1) & -n;
|
||||||
sz = (sz + n-1) / n;
|
sz /= 4;
|
||||||
al = i->op - OAlloc;
|
fn->tmp[i->to.val].spill = fn->stk0;
|
||||||
s = slota(sz, al, fn->svec);
|
fn->stk0 -= sz;
|
||||||
fn->tmp[i->to.val].spill = s;
|
|
||||||
i->to = R;
|
i->to = R;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
33
lisc/slot.txt
Normal 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
|
Loading…
Add table
Reference in a new issue