ref: 67bd2a9810f0891b26ed05830a565fa452aa04da
parent: 7c7208dac215e12376b9d72c7fd52ec4bb44ee69
author: Ori Bernstein <[email protected]>
date: Fri Jun 15 01:27:42 EDT 2012
Implement spill selection.
--- a/8/ra.c
+++ b/8/ra.c
@@ -518,13 +518,62 @@
return 1;
}
+int wlhas(Loc **wl, size_t nwl, regid v, size_t *idx)
+{
+ size_t i;
+
+ for (i = 0; i < nwl; i++) {
+ if (wl[i]->reg.id == v) {
+ *idx = i;
+ return 1;
+ }
+ }
+ return 0;
+}
+
void combine(Isel *s, regid u, regid v)
{
+ Bitset *adj;
+ regid t;
+ size_t idx;
+ size_t i, j;
+ int has;
+
printf("Want to combine ");
locprint(stdout, locmap[u]);
printf(" with ");
locprint(stdout, locmap[v]);
printf("\n");
+ if (wlhas(s->wlfreeze, s->nwlfreeze, v, &idx))
+ ldel(&s->wlfreeze, &s->nwlfreeze, idx);
+ else if (wlhas(s->wlspill, s->nwlspill, v, &idx))
+ ldel(&s->wlspill, &s->nwlspill, idx);
+ bsput(s->coalesced, v);
+ s->aliasmap[v] = locmap[u];
+
+ /* nodemoves[u] = nodemoves[u] U nodemoves[v] */
+ for (i = 0; i < s->nrmoves[v]; i++) {
+ has = 0;
+ for (j = 0; j < s->nrmoves[u]; j++) {
+ if (s->rmoves[v][i] == s->rmoves[u][j]) {
+ has = 1;
+ break;
+ }
+ }
+ if (!has)
+ lappend(&s->rmoves[u], &s->nrmoves[u], s->rmoves[v][i]);
+ }
+
+ adj = adjacent(s, v);
+ for (t = 0; bsiter(adj, &t); t++) {
+ gbputedge(s, t, u);
+ decdegree(s, t);
+ }
+ if (s->degree[u] >= K && wlhas(s->wlfreeze, s->nwlfreeze, u, &idx)) {
+ ldel(&s->wlfreeze, &s->nwlfreeze, idx);
+ lappend(&s->wlspill, &s->nwlspill, locmap[u]);
+ }
+
}
void coalesce(Isel *s)
@@ -560,11 +609,51 @@
}
}
-void freezemoves(Isel *s, regid u)
+int mldel(Insn ***ml, size_t *nml, Insn *m)
{
- die("Implement freeze moves\n");
+ size_t i;
+ for (i = 0; i < *nml; i++) {
+ if (m == (*ml)[i]) {
+ ldel(ml, nml, i);
+ return 1;
+ }
+ }
+ return 0;
}
+void freezemoves(Isel *s, Loc *u)
+{
+ size_t i;
+ Insn **ml;
+ Insn *m;
+ size_t nml;
+ size_t idx;
+ Loc *v;
+
+ nml = nodemoves(s, u->reg.id, &ml);
+ for (i = 0; i < nml; i++) {
+ m = ml[i];
+ if (m->args[0] == u)
+ v = m->args[1];
+ else if (m->args[1] == u)
+ v = m->args[0];
+ else
+ continue;
+
+ if (!mldel(&s->mactive, &s->nmactive, m))
+ mldel(&s->wlmove, &s->nwlmove, m);
+ lappend(&s->mfrozen, &s->nmfrozen, m);
+ if (!nodemoves(s, v->reg.id, NULL) && s->degree[v->reg.id] < K) {
+ if (!wlhas(s->wlfreeze, s->nwlfreeze, v->reg.id, &idx))
+ die("Reg %zd not in freeze wl\n", v->reg.id);
+ ldel(&s->wlfreeze, &s->nwlfreeze, idx);
+ lappend(&s->wlsimp, &s->nwlsimp, v);
+ }
+
+ }
+ lfree(&ml, &nml);
+}
+
void freeze(Isel *s)
{
Loc *l;
@@ -571,12 +660,25 @@
l = lpop(&s->wlfreeze, &s->nwlfreeze);
lappend(&s->wlsimp, &s->nwlsimp, l);
- freezemoves(s, l->reg.id);
+ freezemoves(s, l);
}
-void spill(Isel *s)
+void selspill(Isel *s)
{
- die("Implement spilling\n");
+ size_t i;
+ Loc *m;
+
+ /* FIXME: pick a better heuristic for spilling */
+ for (i = 0; i < s->nwlspill; i++) {
+ if (!bshas(s->spilled, s->wlspill[i]->reg.id)) {
+ m = s->wlspill[i];
+ ldel(&s->wlspill, &s->nwlspill, i);
+ break;
+ }
+ }
+ assert(m != NULL);
+ lappend(&s->wlsimp, &s->nwlsimp, m);
+ freezemoves(s, m);
}
int paint(Isel *s)
@@ -605,7 +707,11 @@
found = 0;
for (i = 0; i < K; i++) {
if (!taken[i]) {
+ locprint(stdout, n);
+ printf(" ==> ");
n->reg.colour = regmap[i][n->mode];
+ locprint(stdout, n);
+ printf("\n");
found = 1;
break;
}
@@ -651,7 +757,7 @@
else if (s->nwlfreeze)
freeze(s);
else if (s->nwlspill)
- spill(s);
+ selspill(s);
} while (s->nwlsimp || s->nwlmove || s->nwlfreeze || s->nwlspill);
spilled = paint(s);
if (spilled)
--- a/8/reduce.c
+++ b/8/reduce.c
@@ -330,7 +330,7 @@
}
/* safe: all types we allow here have a sub[0] that we want to grab */
sz = tysize(n->expr.type->sub[0]);
- v = mkexpr(-1, Omul, u, mkexpr(-1, Olit, mkint(-1, sz), NULL), NULL);
+ v = mkexpr(-1, Omul, off, mkexpr(-1, Olit, mkint(-1, sz), NULL), NULL);
return mkexpr(-1, Oadd, u, v, NULL);
}