ref: a340b8b9e6b3645eccb5ee3e00cb92c974029c68
parent: 6007029a7fcb1184f5f3d698ed55f96fa4812ac1
author: Ori Bernstein <[email protected]>
date: Tue Jun 3 20:09:37 EDT 2014
Optimize the register allocator. We don't need to iterate through lists to figure out which node a list is on. Store it in the node.
--- a/6/asm.h
+++ b/6/asm.h
@@ -59,6 +59,7 @@
struct Loc {
Loctype type; /* the type of loc */
Mode mode; /* the mode of this location */
+ void *list;
union {
char *lbl; /* for Loclbl, Loclitl */
struct { /* for Locreg */
@@ -113,7 +114,6 @@
Bitset *liveout; /* variables live on exit from BB */
};
-
/* instruction selection state */
struct Isel {
Cfg *cfg; /* cfg built with nodes */
@@ -133,8 +133,6 @@
Loc *calleesave[Nsaved];
/* register allocator state */
- Bitset *prepainted; /* locations that need to be a specific colour */
- Bitset *initial; /* initial set of locations used by this fn */
size_t *gbits; /* igraph matrix repr */
regid **gadj; /* igraph adj set repr */
@@ -142,11 +140,6 @@
int *degree; /* degree of nodes */
Loc **aliasmap; /* mapping of aliases */
- Loc **selstk;
- size_t nselstk;
-
- Bitset *coalesced;
- Bitset *spilled;
Bitset *shouldspill; /* the first registers we should try to spill */
Bitset *neverspill; /* registers we should never spill */
@@ -179,6 +172,14 @@
Loc **wlsimp;
size_t nwlsimp;
+
+ Loc **selstk;
+ size_t nselstk;
+
+ Bitset *coalesced;
+ Bitset *spilled;
+ Bitset *prepainted; /* locations that need to be a specific colour */
+ Bitset *initial; /* initial set of locations used by this fn */
};
/* entry points */
--- a/6/ra.c
+++ b/6/ra.c
@@ -306,7 +306,7 @@
assert(gbhasedge(s, u, v) && gbhasedge(s, v, u));
}
-static int wlhas(Loc **wl, size_t nwl, regid v, size_t *idx)
+static int wlfind(Loc **wl, size_t nwl, regid v, size_t *idx)
{
size_t i;
@@ -356,6 +356,19 @@
s->gadj[u][s->ngadj[u] - 1] = v;
}
+static void wlput(Loc ***wl, size_t *nwl, Loc *l)
+{
+ lappend(wl, nwl, l);
+ l->list = wl;
+}
+
+static void wlputset(Bitset *bs, regid r)
+{
+ bsput(bs, r);
+ locmap[r]->list = bs;
+}
+
+
static void addedge(Isel *s, regid u, regid v)
{
if (u == v || gbhasedge(s, u, v))
@@ -435,10 +448,14 @@
nd = defs(insn, d);
/* add these to the initial set */
- for (k = 0; k < nu; k++)
- bsput(s->initial, u[k]);
- for (k = 0; k < nd; k++)
- bsput(s->initial, d[k]);
+ for (k = 0; k < nu; k++) {
+ if (!bshas(s->prepainted, u[k]))
+ wlputset(s->initial, u[k]);
+ }
+ for (k = 0; k < nd; k++) {
+ if (!bshas(s->prepainted, d[k]))
+ wlputset(s->initial, d[k]);
+ }
/* moves get special treatment, since we don't want spurious
* edges between the src and dest */
@@ -479,13 +496,10 @@
static int adjavail(Isel *s, regid r)
{
- size_t i;
-
if (bshas(s->coalesced, r))
return 0;
- for (i = 0; i < s->nselstk; i++)
- if (r == s->selstk[i]->reg.id)
- return 0;
+ if (locmap[r]->list == &s->selstk)
+ return 0;
return 1;
}
@@ -532,11 +546,11 @@
if (bshas(s->prepainted, i))
continue;
else if (!istrivial(s, i))
- lappend(&s->wlspill, &s->nwlspill, locmap[i]);
+ wlput(&s->wlspill, &s->nwlspill, locmap[i]);
else if (moverelated(s, i))
- lappend(&s->wlfreeze, &s->nwlfreeze, locmap[i]);
+ wlput(&s->wlfreeze, &s->nwlfreeze, locmap[i]);
else
- lappend(&s->wlsimp, &s->nwlsimp, locmap[i]);
+ wlput(&s->wlsimp, &s->nwlsimp, locmap[i]);
locmap[i]->reg.colour = 0;
}
}
@@ -589,19 +603,19 @@
* that the node is already on the list that we'd be
* moving it to.
*/
- found = wlhas(s->wlspill, s->nwlspill, m, &idx);
+ found = wlfind(s->wlspill, s->nwlspill, m, &idx);
if (found)
ldel(&s->wlspill, &s->nwlspill, idx);
if (moverelated(s, m)) {
if (!found)
- assert(wlhas(s->wlfreeze, s->nwlfreeze, m, &idx));
+ assert(wlfind(s->wlfreeze, s->nwlfreeze, m, &idx));
else
- lappend(&s->wlfreeze, &s->nwlfreeze, locmap[m]);
+ wlput(&s->wlfreeze, &s->nwlfreeze, locmap[m]);
} else {
if (!found)
- assert(wlhas(s->wlsimp, s->nwlsimp, m, &idx));
+ assert(wlfind(s->wlsimp, s->nwlsimp, m, &idx));
else
- lappend(&s->wlsimp, &s->nwlsimp, locmap[m]);
+ wlput(&s->wlsimp, &s->nwlsimp, locmap[m]);
}
}
}
@@ -613,7 +627,7 @@
size_t i;
l = lpop(&s->wlsimp, &s->nwlsimp);
- lappend(&s->selstk, &s->nselstk, l);
+ wlput(&s->selstk, &s->nselstk, l);
for (i = 0; i < s->ngadj[l->reg.id]; i++) {
m = s->gadj[l->reg.id][i];
if (adjavail(s, m))
@@ -642,9 +656,9 @@
if (!istrivial(s, u))
return;
- assert(wlhas(s->wlfreeze, s->nwlfreeze, u, &i));
+ assert(wlfind(s->wlfreeze, s->nwlfreeze, u, &i));
ldel(&s->wlfreeze, &s->nwlfreeze, i);
- lappend(&s->wlsimp, &s->nwlsimp, locmap[u]);
+ wlput(&s->wlsimp, &s->nwlsimp, locmap[u]);
}
static int conservative(Isel *s, regid u, regid v)
@@ -705,12 +719,12 @@
if (debugopt['r'] > 2)
printedge(stdout, "combining:", u, v);
- if (wlhas(s->wlfreeze, s->nwlfreeze, v, &idx))
+ if (wlfind(s->wlfreeze, s->nwlfreeze, v, &idx))
ldel(&s->wlfreeze, &s->nwlfreeze, idx);
- else if (wlhas(s->wlspill, s->nwlspill, v, &idx)) {
+ else if (wlfind(s->wlspill, s->nwlspill, v, &idx)) {
ldel(&s->wlspill, &s->nwlspill, idx);
}
- bsput(s->coalesced, v);
+ wlputset(s->coalesced, v);
s->aliasmap[v] = locmap[u];
/* nodemoves[u] = nodemoves[u] U nodemoves[v] */
@@ -735,9 +749,9 @@
addedge(s, t, u);
decdegree(s, t);
}
- if (!istrivial(s, u) && wlhas(s->wlfreeze, s->nwlfreeze, u, &idx)) {
+ if (!istrivial(s, u) && wlfind(s->wlfreeze, s->nwlfreeze, u, &idx)) {
ldel(&s->wlfreeze, &s->nwlfreeze, idx);
- lappend(&s->wlspill, &s->nwlspill, locmap[u]);
+ wlput(&s->wlspill, &s->nwlspill, locmap[u]);
}
}
@@ -806,10 +820,10 @@
mldel(&s->wlmove, &s->nwlmove, m);
lappend(&s->mfrozen, &s->nmfrozen, m);
if (!nodemoves(s, v->reg.id, NULL) && istrivial(s, v->reg.id)) {
- if (!wlhas(s->wlfreeze, s->nwlfreeze, v->reg.id, &idx))
+ if (!wlfind(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);
+ wlput(&s->wlsimp, &s->nwlsimp, v);
}
}
@@ -821,7 +835,7 @@
Loc *l;
l = lpop(&s->wlfreeze, &s->nwlfreeze);
- lappend(&s->wlsimp, &s->nwlsimp, l);
+ wlput(&s->wlsimp, &s->nwlsimp, l);
freezemoves(s, l);
}
@@ -852,7 +866,7 @@
}
}
assert(m != NULL);
- lappend(&s->wlsimp, &s->nwlsimp, m);
+ wlput(&s->wlsimp, &s->nwlsimp, m);
freezemoves(s, m);
}
@@ -898,7 +912,7 @@
}
if (!found) {
spilled = 1;
- bsput(s->spilled, n->reg.id);
+ wlputset(s->spilled, n->reg.id);
}
}
for (l = 0; bsiter(s->coalesced, &l); l++) {