ref: cdda2a180d180c48e9ba197c4a0cecc7e075b782
parent: 14aeadb41737f1765b6f3489f3b8da330aeccf39
author: Ori Bernstein <ori@eigenstate.org>
date: Fri Aug 21 23:37:33 EDT 2015
Do slightly better code gen. Remove some spurious spills.
--- a/6/ra.c
+++ b/6/ra.c
@@ -609,6 +609,8 @@
ni = nodemoves(s, n, &il);
for (i = 0; i < ni; i++) {
+ if (!bshas(s->mactiveset, il[i]->uid))
+ continue;
for (j = 0; j < s->nmactive; j++) {
if (il[i] == s->mactive[j]) {
ldel(&s->mactive, &s->nmactive, j);
@@ -1137,6 +1139,15 @@
return useidx > 0 || defidx > 0;
}
+static int nopmov(Insn *insn)
+{
+ if (insn->op != Imov && insn->op != Imovs)
+ return 0;
+ if (insn->args[0]->type != Locreg || insn->args[1]->type != Locreg)
+ return 0;
+ return insn->args[0]->reg.id == insn->args[1]->reg.id;
+}
+
/*
* Rewrite instructions using spilled registers, inserting
* appropriate loads and stores into the BB
@@ -1155,6 +1166,8 @@
if (!bb)
return;
for (j = 0; j < bb->ni; j++) {
+ if (nopmov(bb->il[j]))
+ continue;
/* if there is a remapping, insert the loads and stores as needed */
if (remap(s, bb->il[j], use, &nuse, def, &ndef)) {
for (i = 0; i < nuse; i++) {
@@ -1208,6 +1221,34 @@
htput(s->spillslots, itop(l->reg.id), itop(s->stksz->lit));
}
+void replacealias(Isel *s, Asmbb *bb, Loc **map)
+{
+ size_t i, j;
+ Insn *insn;
+ Loc **alias;
+ Loc *l;
+
+ if (!map || !bb)
+ return;
+ alias = s->aliasmap;
+ s->aliasmap = alias;
+ for (i = 0; i < bb->ni; i++) {
+ insn = bb->il[i];
+ for (j = 0; j < insn->nargs; j++) {
+ l = insn->args[j];
+ if (l->type == Locreg) {
+ insn->args[j] = locmap[getalias(s, l->reg.id)];
+ } else if (l->type == Locmem || l->type == Locmeml) {
+ if (l->mem.base)
+ l->mem.base = locmap[getalias(s, l->mem.base->reg.id)];
+ if (l->mem.idx)
+ l->mem.idx = locmap[getalias(s, l->mem.idx->reg.id)];
+ }
+ }
+ }
+ s->aliasmap = alias;
+}
+
/*
* Rewrites the function code so that it no longer contains
* references to spilled registers. Every use of spilled regs
@@ -1220,7 +1261,7 @@
* insn %rZ,%rW
* mov %rW,234(%rsp)
*/
-static void rewrite(Isel *s)
+static void rewrite(Isel *s, Loc **aliasmap)
{
size_t i;
@@ -1231,6 +1272,8 @@
/* rewrite instructions using them */
for (i = 0; i < s->nbb; i++)
+ replacealias(s, s->bb[i], aliasmap);
+ for (i = 0; i < s->nbb; i++)
rewritebb(s, s->bb[i]);
htfree(s->spillslots);
bsclear(s->spilled);
@@ -1276,6 +1319,7 @@
{
int spilled;
size_t i;
+ Loc **aliasmap;
/* Initialize the list of prepainted registers */
s->prepainted = mkbs();
@@ -1289,6 +1333,7 @@
for (i = 0; i < s->nsaved; i++)
bsput(s->shouldspill, s->calleesave[i]->reg.id);
do {
+ aliasmap = NULL;
setup(s);
liveness(s);
build(s);
@@ -1302,12 +1347,15 @@
coalesce(s);
else if (s->nwlfreeze)
freeze(s);
- else if (s->nwlspill)
+ else if (s->nwlspill) {
+ if (!aliasmap)
+ aliasmap = memdup(s->aliasmap, s->nreg * sizeof(Loc*));
selspill(s);
+ }
} while (s->nwlsimp || s->nwlmove || s->nwlfreeze || s->nwlspill);
spilled = paint(s);
if (spilled)
- rewrite(s);
+ rewrite(s, aliasmap);
} while (spilled);
delnops(s);
bsfree(s->prepainted);
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -524,6 +524,7 @@
{
Type *t;
+ t = NULL;
if (!n->lit.type) {
switch (n->lit.littype) {
case Lchr: t = mktype(n->loc, Tychar); break;