diff options
author | Ori Bernstein <ori@eigenstate.org> | 2015-08-22 03:37:33 -0700 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2015-08-22 03:59:02 -0700 |
commit | cdda2a180d180c48e9ba197c4a0cecc7e075b782 (patch) | |
tree | 7a242ccb800cad4f30ff1533960a1e8748cb0cab | |
parent | 14aeadb41737f1765b6f3489f3b8da330aeccf39 (diff) | |
download | mc-cdda2a180d180c48e9ba197c4a0cecc7e075b782.tar.gz |
Do slightly better code gen.
Remove some spurious spills.
-rw-r--r-- | 6/ra.c | 54 | ||||
-rw-r--r-- | parse/infer.c | 1 |
2 files changed, 52 insertions, 3 deletions
@@ -609,6 +609,8 @@ static void enablemove(Isel *s, regid n) 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 @@ static int remap(Isel *s, Insn *insn, Remapping *use, size_t *nuse, Remapping *d 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 @@ static void rewritebb(Isel *s, Asmbb *bb) 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 @@ static void addspill(Isel *s, Loc *l) 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 @@ static void addspill(Isel *s, Loc *l) * 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 @@ static void rewrite(Isel *s) /* 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 @@ void regalloc(Isel *s) { int spilled; size_t i; + Loc **aliasmap; /* Initialize the list of prepainted registers */ s->prepainted = mkbs(); @@ -1289,6 +1333,7 @@ void regalloc(Isel *s) 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 @@ void regalloc(Isel *s) 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); diff --git a/parse/infer.c b/parse/infer.c index 6d23c0a..7f6290a 100644 --- a/parse/infer.c +++ b/parse/infer.c @@ -524,6 +524,7 @@ static Type *littype(Node *n) { Type *t; + t = NULL; if (!n->lit.type) { switch (n->lit.littype) { case Lchr: t = mktype(n->loc, Tychar); break; |