ref: 48996257e5e74a72258db974a03ba8e40ce9287f
parent: ad438bbebc8bc26ec441150577792dde4e729558
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Aug 23 13:31:40 EDT 2015
Clean up remapping code.
--- a/6/ra.c
+++ b/6/ra.c
@@ -999,19 +999,12 @@
return spilled;
}
-typedef struct Remapping Remapping;
-struct Remapping {
- regid oldreg;
- Loc *newreg;
-};
-
-static Loc *mapfind(Isel *s, Loc *old, Remapping *r, size_t nr)
+static Loc *mapfind(Isel *s, Htab *map, Loc *old)
{
Loc *new;
Loc *base;
Loc *idx;
regid id;
- size_t i;
if (!old)
return NULL;
@@ -1019,20 +1012,16 @@
new = NULL;
if (old->type == Locreg) {
id = getalias(s, old->reg.id);
- for (i = 0; i < nr; i++) {
- if (id == r[i].oldreg) {
- return r[i].newreg;
- }
- }
+ new = htget(map, locmap[id]);
} else if (old->type == Locmem || old->type == Locmeml) {
- base = NULL;
- idx = NULL;
- if (old->mem.base)
- base = locmap[getalias(s, old->mem.base->reg.id)];
- if (old->mem.idx)
- idx = locmap[getalias(s, old->mem.idx->reg.id)];
- base = mapfind(s, base, r, nr);
- idx = mapfind(s, idx, r, nr);
+ base = old->mem.base;
+ idx = old->mem.idx;
+ if (base)
+ base = locmap[getalias(s, base->reg.id)];
+ if (idx)
+ idx = locmap[getalias(s, idx->reg.id)];
+ base = mapfind(s, map, base);
+ idx = mapfind(s, map, idx);
if (base != old->mem.base || idx != old->mem.idx) {
if (old->type == Locmem)
new = locmems(old->mem.constdisp, base, idx, old->mem.scale, old->mode);
@@ -1039,9 +1028,9 @@
else
new = locmemls(old->mem.lbldisp, base, idx, old->mem.scale, old->mode);
}
- if (new)
- return new;
}
+ if (new)
+ return new;
return old;
}
@@ -1053,13 +1042,13 @@
return locmem(-stkoff, locphysreg(Rrbp), NULL, locmap[reg]->mode);
}
-static void updatelocs(Isel *s, Insn *insn, Remapping *use, size_t nuse, Remapping *def, size_t ndef)
+static void updatelocs(Isel *s, Htab *map, Insn *insn)
{
size_t i;
for (i = 0; i < insn->nargs; i++) {
- insn->args[i] = mapfind(s, insn->args[i], use, nuse);
- insn->args[i] = mapfind(s, insn->args[i], def, ndef);
+ insn->args[i] = mapfind(s, map, insn->args[i]);
+ insn->args[i] = mapfind(s, map, insn->args[i]);
}
}
@@ -1068,58 +1057,37 @@
* and fills them, storign the number of uses or defs. Returns
* whether there are any remappings at all.
*/
-static int remap(Isel *s, Insn *insn, Remapping *use, size_t *nuse, Remapping *def, size_t *ndef)
+static int remap(Isel *s, Htab *map, Insn *insn, regid *use, size_t nuse, regid *def, size_t ndef)
{
- regid u[Nreg], d[Nreg];
regid ruse, rdef;
- size_t nu, nd;
- size_t useidx, defidx;
- size_t i, j, k;
- int found;
+ int remapped;
+ Loc *tmp;
+ size_t i;
- useidx = 0;
- nu = uses(insn, u);
- nd = defs(insn, d);
- for (i = 0; i < nu; i++) {
- ruse = getalias(s, u[i]);
+ remapped = 0;
+ for (i = 0; i < nuse; i++) {
+ ruse = getalias(s, use[i]);
if (!bshas(s->spilled, ruse))
continue;
- use[useidx].oldreg = ruse;
- use[useidx].newreg = locreg(locmap[ruse]->mode);
- bsput(s->neverspill, use[useidx].newreg->reg.id);
- useidx++;
+ tmp = locreg(locmap[ruse]->mode);
+ htput(map, locmap[ruse], tmp);
+ bsput(s->neverspill, tmp->reg.id);
+ remapped = 1;
}
- defidx = 0;
- for (i = 0; i < nd; i++) {
- rdef = getalias(s, d[i]);
+ for (i = 0; i < ndef; i++) {
+ rdef = getalias(s, def[i]);
if (!bshas(s->spilled, rdef))
continue;
- def[defidx].oldreg = rdef;
-
- /* if we already have remapped a use for this register, we want to
- * store the same register from the def. */
- found = 0;
- for (j = 0; j <= defidx; j++) {
- for (k = 0; k < useidx; k++) {
- if (use[k].oldreg == getalias(s, d[j])) {
- def[defidx].newreg = use[j].newreg;
- bsput(s->neverspill, def[defidx].newreg->reg.id);
- found = 1;
- }
- }
- }
- if (!found) {
- def[defidx].newreg = locreg(locmap[rdef]->mode);
- bsput(s->neverspill, def[defidx].newreg->reg.id);
- }
-
- defidx++;
+ if (hthas(map, locmap[rdef]))
+ continue;
+ tmp = locreg(locmap[rdef]->mode);
+ htput(map, locmap[rdef], tmp);
+ bsput(s->neverspill, tmp->reg.id);
+ remapped = 1;
}
- *nuse = useidx;
- *ndef = defidx;
- return useidx > 0 || defidx > 0;
+ return remapped;
}
static int nopmov(Insn *insn)
@@ -1151,60 +1119,92 @@
}
}
+static ulong reglochash(void *p)
+{
+ Loc *l;
+
+ l = p;
+ return inthash(l->reg.id);
+}
+
+
+static int regloceq(void *pa, void *pb)
+{
+ Loc *a, *b;
+
+ a = pa;
+ b = pb;
+ return a->reg.id == b->reg.id;
+}
/*
* Rewrite instructions using spilled registers, inserting
* appropriate loads and stores into the BB
*/
-static void rewritebb(Isel *s, Asmbb *bb, Loc **map)
+static void rewritebb(Isel *s, Asmbb *bb, Loc **aliasmap)
{
- Remapping use[Nreg], def[Nreg];
- Insn *insn, *mov;
+ regid use[Nreg], def[Nreg];
size_t nuse, ndef;
+ Insn *insn, *mov;
size_t i, j;
Insn **new;
size_t nnew;
+ Htab *map;
+ Loc *tmp;
new = NULL;
nnew = 0;
if (!bb)
return;
+ map = mkht(reglochash, regloceq);
for (j = 0; j < bb->ni; j++) {
insn = bb->il[j];
- replacealias(s, map, s->nreg, insn);
+ replacealias(s, aliasmap, s->nreg, insn);
if (nopmov(insn))
continue;
+ nuse = uses(insn, use);
+ ndef = defs(insn, def);
/* if there is a remapping, insert the loads and stores as needed */
- if (remap(s, insn, use, &nuse, def, &ndef)) {
+ if (remap(s, map, insn, use, nuse, def, ndef)) {
for (i = 0; i < nuse; i++) {
- if (isfloatmode(use[i].newreg->mode))
- mov = mkinsn(Imovs, spillslot(s, use[i].oldreg), use[i].newreg, NULL);
+ tmp = htget(map, locmap[use[i]]);
+ if (!tmp)
+ continue;
+ if (isfloatmode(tmp->mode))
+ mov = mkinsn(Imovs, spillslot(s, use[i]), tmp, NULL);
else
- mov = mkinsn(Imov, spillslot(s, use[i].oldreg), use[i].newreg, NULL);
+ mov = mkinsn(Imov, spillslot(s, use[i]), tmp, NULL);
lappend(&new, &nnew, mov);
if (debugopt['r']) {
printf("loading ");
- dbglocprint(stdout, locmap[use[i].oldreg], 'x');
+ dbglocprint(stdout, locmap[use[i]], 'x');
printf(" -> ");
- dbglocprint(stdout, use[i].newreg, 'x');
+ dbglocprint(stdout, tmp, 'x');
printf("\n");
}
}
- updatelocs(s, insn, use, nuse, def, ndef);
+ updatelocs(s, map, insn);
lappend(&new, &nnew, insn);
for (i = 0; i < ndef; i++) {
- if (isfloatmode(def[i].newreg->mode))
- mov = mkinsn(Imovs, def[i].newreg, spillslot(s, def[i].oldreg), NULL);
+ tmp = htget(map, locmap[def[i]]);
+ if (!tmp)
+ continue;
+ if (isfloatmode(tmp->mode))
+ mov = mkinsn(Imovs, tmp, spillslot(s, def[i]), NULL);
else
- mov = mkinsn(Imov, def[i].newreg, spillslot(s, def[i].oldreg), NULL);
+ mov = mkinsn(Imov, tmp, spillslot(s, def[i]), NULL);
lappend(&new, &nnew, mov);
if (debugopt['r']) {
printf("storing ");
- dbglocprint(stdout, locmap[def[i].oldreg], 'x');
+ dbglocprint(stdout, locmap[def[i]], 'x');
printf(" -> ");
- dbglocprint(stdout, def[i].newreg, 'x');
+ dbglocprint(stdout, tmp, 'x');
printf("\n");
}
}
+ for (i = 0; i < nuse; i++)
+ htdel(map, locmap[use[i]]);
+ for (i = 0; i < ndef; i++)
+ htdel(map, locmap[def[i]]);
} else {
lappend(&new, &nnew, insn);
}