break phi-classes following interferences
This commit is contained in:
parent
614130e431
commit
d43ebe8f58
1 changed files with 36 additions and 11 deletions
47
lisc/live.c
47
lisc/live.c
|
@ -19,15 +19,31 @@ liveon(Blk *b, Blk *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
bset(Ref r, Blk *b, int *nlv)
|
bset(Ref r, Blk *b, int *nlv, short *phi, Tmp *tmp)
|
||||||
{
|
{
|
||||||
|
int t, t1, t2;
|
||||||
|
|
||||||
if (rtype(r) != RTmp)
|
if (rtype(r) != RTmp)
|
||||||
return;
|
return;
|
||||||
BSET(b->gen, r.val);
|
t1 = r.val;
|
||||||
if (!BGET(b->in, r.val)) {
|
BSET(b->gen, t1);
|
||||||
|
if (!BGET(b->in, t1)) {
|
||||||
++*nlv;
|
++*nlv;
|
||||||
BSET(b->in, r.val);
|
BSET(b->in, t1);
|
||||||
}
|
}
|
||||||
|
/* detect temporaries in the same
|
||||||
|
* phi-class that interfere and
|
||||||
|
* separate them
|
||||||
|
*/
|
||||||
|
t = phirepr(tmp, t1);
|
||||||
|
t2 = phi[t];
|
||||||
|
if (t2 && t2 != t1) {
|
||||||
|
if (tmp[t1].phi != t1)
|
||||||
|
tmp[t1].phi = t1;
|
||||||
|
else
|
||||||
|
tmp[t2].phi = t2;
|
||||||
|
}
|
||||||
|
phi[t] = t1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* liveness analysis
|
/* liveness analysis
|
||||||
|
@ -38,11 +54,13 @@ filllive(Fn *f)
|
||||||
{
|
{
|
||||||
Blk *b;
|
Blk *b;
|
||||||
Ins *i;
|
Ins *i;
|
||||||
int z, m, n, chg, nlv;
|
int t, z, m, n, chg, nlv;
|
||||||
|
short *phi;
|
||||||
Bits u, v;
|
Bits u, v;
|
||||||
Mem *ma;
|
Mem *ma;
|
||||||
|
|
||||||
assert(f->ntmp <= NBit*BITS);
|
assert(f->ntmp <= NBit*BITS);
|
||||||
|
phi = emalloc(f->ntmp * sizeof phi[0]);
|
||||||
for (b=f->start; b; b=b->link) {
|
for (b=f->start; b; b=b->link) {
|
||||||
b->in = (Bits){{0}};
|
b->in = (Bits){{0}};
|
||||||
b->out = (Bits){{0}};
|
b->out = (Bits){{0}};
|
||||||
|
@ -66,9 +84,13 @@ Again:
|
||||||
}
|
}
|
||||||
chg |= memcmp(&b->out, &u, sizeof(Bits));
|
chg |= memcmp(&b->out, &u, sizeof(Bits));
|
||||||
|
|
||||||
b->in = b->out;
|
memset(phi, 0, f->ntmp * sizeof phi[0]);
|
||||||
nlv = bcnt(&b->in);
|
b->in = (Bits){{0}};
|
||||||
bset(b->jmp.arg, b, &nlv);
|
nlv = 0;
|
||||||
|
for (t=0; t<f->ntmp; t++)
|
||||||
|
if (BGET(b->out, t))
|
||||||
|
bset(TMP(t), b, &nlv, phi, f->tmp);
|
||||||
|
bset(b->jmp.arg, b, &nlv, phi, f->tmp);
|
||||||
b->nlive = nlv;
|
b->nlive = nlv;
|
||||||
for (i=&b->ins[b->nins]; i!=b->ins;) {
|
for (i=&b->ins[b->nins]; i!=b->ins;) {
|
||||||
if ((--i)->op == OCall) {
|
if ((--i)->op == OCall) {
|
||||||
|
@ -83,16 +105,18 @@ Again:
|
||||||
assert(rtype(i->to) == RTmp);
|
assert(rtype(i->to) == RTmp);
|
||||||
nlv -= BGET(b->in, i->to.val);
|
nlv -= BGET(b->in, i->to.val);
|
||||||
BCLR(b->in, i->to.val);
|
BCLR(b->in, i->to.val);
|
||||||
|
t = phirepr(f->tmp, i->to.val);
|
||||||
|
phi[t] = 0;
|
||||||
}
|
}
|
||||||
for (m=0; m<2; m++)
|
for (m=0; m<2; m++)
|
||||||
switch (rtype(i->arg[m])) {
|
switch (rtype(i->arg[m])) {
|
||||||
case RAMem:
|
case RAMem:
|
||||||
ma = &f->mem[i->arg[m].val & AMask];
|
ma = &f->mem[i->arg[m].val & AMask];
|
||||||
bset(ma->base, b, &nlv);
|
bset(ma->base, b, &nlv, phi, f->tmp);
|
||||||
bset(ma->index, b, &nlv);
|
bset(ma->index, b, &nlv, phi, f->tmp);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
bset(i->arg[m], b, &nlv);
|
bset(i->arg[m], b, &nlv, phi, f->tmp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (nlv > b->nlive)
|
if (nlv > b->nlive)
|
||||||
|
@ -103,6 +127,7 @@ Again:
|
||||||
chg = 0;
|
chg = 0;
|
||||||
goto Again;
|
goto Again;
|
||||||
}
|
}
|
||||||
|
free(phi);
|
||||||
|
|
||||||
if (debug['L']) {
|
if (debug['L']) {
|
||||||
fprintf(stderr, "\n> Liveness analysis:\n");
|
fprintf(stderr, "\n> Liveness analysis:\n");
|
||||||
|
|
Loading…
Add table
Reference in a new issue