5 #define assert(x) assert_test(#x, x) 53 memcpy(ma, mb,
sizeof *ma);
62 for (i=0; i<m->
n; i++)
76 assert(s != -1 &&
"should have spilled");
83 radd(
RMap *m,
int t,
int r)
85 assert((t >=
Tmp0 || t == r) &&
"invalid temporary");
88 &&
"invalid register");
89 assert(!bshas(m->
b, t) &&
"temporary has mapping");
90 assert(!bshas(m->
b, r) &&
"register already allocated");
91 assert(m->
n <=
T.
ngpr+
T.
nfpr &&
"too many mappings");
101 ralloctry(
RMap *m,
int t,
int try)
107 assert(bshas(m->
b, t));
110 if (bshas(m->
b, t)) {
116 if (r == -1 || bshas(m->
b, r))
118 if (r == -1 || bshas(m->
b, r)) {
130 for (r=r0; r<r1; r++)
131 if (!(regs &
BIT(r)))
133 for (r=r0; r<r1; r++)
143 if (h != -1 && h != r)
149 ralloc(
RMap *m,
int t)
151 return ralloctry(m, t, 0);
155 rfree(
RMap *m,
int t)
162 for (i=0; m->
t[i] != t; i++)
168 memmove(&m->
t[i], &m->
t[i+1], (m->
n-i) *
sizeof m->
t[0]);
169 memmove(&m->
r[i], &m->
r[i+1], (m->
n-i) *
sizeof m->
r[0]);
170 assert(t >=
Tmp0 || t == r);
179 for (i=0; i<m->
n; i++)
181 fprintf(stderr,
" (%s, R%d)",
184 fprintf(stderr,
"\n");
191 die(
"cannot have more moves than registers");
201 pmrec(
enum PMStat *status,
int i,
int *k)
208 if (req(pm[i].
src, pm[i].
dst)) {
215 for (j=0; j<npm; j++)
216 if (req(pm[j].
dst, pm[i].
src))
218 switch (j == npm ?
Moved : status[j]) {
225 c = pmrec(status, j, k);
250 status =
alloc(npm *
sizeof status[0]);
251 assert(!npm || status[npm-1] ==
ToMove);
252 for (i=0; i<npm; i++)
254 pmrec(status, i, (
int[]){pm[i].cls});
262 r1 = req(to,
R) ? -1 : rfree(m, to.
val);
263 if (bshas(m->
b, r)) {
266 for (n=0; m->
r[n] != r; n++)
274 t = req(to,
R) ? r : to.
val;
298 }
while (i != b->
ins && regcpy(i-1));
299 assert(m0.
n <= m->
n);
302 for (r=0;
T.
rsave[r]>=0; r++)
306 for (npm=0, n=0; n<m->
n; n++) {
316 for (ip=i; ip<i1; ip++) {
318 rfree(m, ip->
to.
val);
320 if (rfind(m, r) == -1)
335 return *hint(r1.
val) != -1;
339 insert(
Ref *r,
Ref **rs,
int p)
344 while (i-- > 0 && prio1(*r, *rs[i])) {
353 int t, x, r, rf, rt, nr;
371 for (r=0;
T.
rsave[r]>=0; r++)
378 i1 = dopm(b, i1, cur);
387 if (!req(i->
to,
R)) {
388 assert(rtype(i->
to) ==
RTmp);
402 for (x=0, nr=0; x<2; x++)
403 switch (rtype(i->
arg[x])) {
407 insert(&m->
base, ra, nr++);
409 insert(&m->
index, ra, nr++);
412 insert(&i->
arg[x], ra, nr++);
416 *ra[r] = ralloc(cur, ra[r]->val);
421 if (rf != -1 && (t = cur->
w[rf]) != 0)
422 if (!bshas(cur->
b, rf) && *hint(t) == rf
423 && (rt = rfree(cur, t)) != -1) {
426 assert(bshas(cur->
b, rf));
431 if (req(*ra[r],
TMP(rt)))
445 carve(
const void *a,
const void *b)
454 return ba->
id > bb->
id ? -1 : ba->
id < bb->
id;
455 return ba->
loop > bb->
loop ? -1 : +1;
461 prio2(
int t1,
int t2)
463 if ((tmp[t1].visit ^ tmp[t2].visit) < 0)
464 return tmp[t1].
visit != -1 ? +1 : -1;
465 if ((*hint(t1) ^ *hint(t2)) < 0)
466 return *hint(t1) != -1 ? +1 : -1;
476 int j, t, r, x, rl[
Tmp0];
477 Blk *b, *b1, *s, ***ps, *blist, **blk, **bp;
478 RMap *end, *beg, cur, old, *m;
493 for (n=0; n<fn->
nblk; n++) {
501 for (t=0; t<fn->
ntmp; t++) {
503 tmp[t].
hint.
w = loop;
508 qsort(blk, fn->
nblk,
sizeof blk[0], carve);
513 assert(rtype(i->
to) ==
RTmp);
518 for (bp=blk; bp<&blk[fn->
nblk]; bp++) {
524 memset(cur.
w, 0,
sizeof cur.
w);
528 while (j-- > 0 && prio2(t, rl[j]) > 0) {
534 ralloctry(&cur, rl[j], 1);
537 rcopy(&end[n], &cur);
543 rcopy(&beg[n], &cur);
556 memset(rl, 0,
sizeof rl);
562 r = rfind(m, p->
to.
val);
565 for (u=0; u<p->
narg; u++) {
572 rl[r] = (!rl[r] || rl[r] == x) ? x : -1;
579 for (j=0; j<m->
n; j++) {
582 if (rl[r] || t <
Tmp0 )
584 for (bp=s->
pred; bp<&s->pred[s->
npred]; bp++) {
585 x = rfind(&end[(*bp)->id], t);
587 rl[r] = (!rl[r] || rl[r] == x) ? x : -1;
592 for (j=0; j<m->
n; j++) {
596 assert(x != 0 || t <
Tmp0 );
615 fprintf(stderr,
"\n> Register mappings:\n");
616 for (n=0; n<fn->
nblk; n++) {
618 fprintf(stderr,
"\t%-10s beg", b->
name);
620 fprintf(stderr,
"\t end");
623 fprintf(stderr,
"\n");
629 ps = (
Blk**[3]){&b->
s1, &b->
s2, (
Blk*[1]){0}};
630 for (; (s=**ps); ps++) {
641 for (u=0; p->
blk[u]!=b; u++)
642 assert(u+1 < p->
narg);
649 src = rref(&end[b->
id], t);
650 dst = rref(&beg[s->
id], t);
681 fprintf(stderr,
"\n> Register allocation statistics:\n");
682 fprintf(stderr,
"\tnew moves: %d\n", stmov);
683 fprintf(stderr,
"\tnew blocks: %d\n", stblk);
684 fprintf(stderr,
"\n> After register allocation:\n");
Blk * start
Указатель на блок функции, являющийся её входной точкой
void emit(int, int, Ref, Ref, Ref)
Структура, хранящая информацию об инструкциях.
void bsinit(BSet *, uint)
void bscopy(BSet *, BSet *)
Структура, хранящая описание переменных (более подробное описание переменной ищите в Tmp)...
Содержит информацию о переменной
Tmp * tmp
Массив используемых функцией переменных
int ntmp
Размер массива tmp.
Непосредственно информация о базовом блоке.
int bsiter(BSet *, int *)
void idup(Ins **, Ins *, ulong)
void printfn(Fn *, FILE *)
bits m
avoid these registers
uint nblk
Количество блоков в функции
bits(* retregs)(Ref, int[2])
Blk ** rpo
Ссылка на массив блоков, пронумерованных в порядке Reverse-Post Order, заполняется функцией fillrpo...
bits(* argregs)(Ref, int[2])
Номер (в массиве Fn->tmp) первой не регистровой переменной
Ins * icpy(Ins *, Ins *, ulong)
Структура, хранящая в себе информацию о функции