summaryrefslogtreecommitdiff
path: root/6
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2016-08-24 21:41:21 -0700
committerOri Bernstein <ori@eigenstate.org>2016-08-24 21:42:22 -0700
commit094e3fb0ee4dd4b8aaaca40da90bf770ae42674f (patch)
tree50b644d80293a88e93bb30658cd9f36809383e64 /6
parent37c3a754daff7f53930a7d47987403e6e2357bc7 (diff)
downloadmc-094e3fb0ee4dd4b8aaaca40da90bf770ae42674f.tar.gz
Don't eliminate all record of prepainted liveness.
If we have a prepainted register that we coalesced, we can't eliminate the move, because that means we could clobber it.
Diffstat (limited to '6')
-rw-r--r--6/ra.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/6/ra.c b/6/ra.c
index 6b417de..24c9d47 100644
--- a/6/ra.c
+++ b/6/ra.c
@@ -1129,13 +1129,14 @@ static int remap(Isel *s, Htab *map, Insn *insn, regid *use, size_t nuse, regid
return remapped;
}
-static int nopmov(Insn *insn)
+static int nopmov(Isel *s, Insn *insn)
{
- if (insn->op != Imov && insn->op != Imovs)
+ if (insn->op != Imov)
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;
+ /* Prepainted register moves need to be kept live to avoid coalescing over them */
+ return insn->args[0]->reg.id == insn->args[1]->reg.id && !bshas(s->prepainted, insn->args[0]->reg.id);
}
void replacealias(Isel *s, Loc **map, size_t nreg, Insn *insn)
@@ -1198,7 +1199,7 @@ static void rewritebb(Isel *s, Asmbb *bb, Loc **aliasmap)
for (j = bb->ni; j > 0; j--) {
insn = bb->il[j - 1];
replacealias(s, aliasmap, s->nreg, insn);
- if (nopmov(insn))
+ if (nopmov(s, insn))
continue;
nuse = uses(insn, use);
ndef = defs(insn, def);