summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2020-06-10 21:47:45 -0700
committerOri Bernstein <ori@eigenstate.org>2020-06-10 21:47:45 -0700
commitde1eabd91024f360845dfe7382581e0acbc368e1 (patch)
tree1bd5d2ae9bd992147364f450bf3c1b36e7b418f9
parent552823815f7c52c16111045b638ba8bab322e7ac (diff)
downloadmc-de1eabd91024f360845dfe7382581e0acbc368e1.tar.gz
Fix check for dumb moves (thanks sgilles)
We need to check if we have reg->reg moves.
-rw-r--r--6/asm.h2
-rw-r--r--6/gengas.c29
-rw-r--r--6/genp9.c26
-rw-r--r--6/ra.c25
4 files changed, 43 insertions, 39 deletions
diff --git a/6/asm.h b/6/asm.h
index fe33b3f..f4c0bad 100644
--- a/6/asm.h
+++ b/6/asm.h
@@ -295,6 +295,8 @@ char *tydescid(char *buf, size_t bufsz, Type *ty);
Loc *coreg(Reg r, Mode m);
int isfloatmode(Mode m);
int isintmode(Mode m);
+int issubreg(Loc *, Loc *);
+int dumbmov(Loc *, Loc *);
/* emitting instructions */
Insn *mkinsn(int op, ...);
diff --git a/6/gengas.c b/6/gengas.c
index 991e30b..b1ef7cb 100644
--- a/6/gengas.c
+++ b/6/gengas.c
@@ -107,12 +107,6 @@ locprint(FILE *fd, Loc *l, char spec)
}
}
-static int
-issubreg(Loc *a, Loc *b)
-{
- return rclass(a) == rclass(b) && a->mode != b->mode;
-}
-
void
iprintf(FILE *fd, Insn *insn)
{
@@ -132,29 +126,22 @@ iprintf(FILE *fd, Insn *insn)
insn->args[1] = coreg(insn->args[1]->reg.colour, ModeL);
}
}
- /* moving a reg to itself is dumb. */
- if (insn->args[0]->reg.colour == insn->args[1]->reg.colour)
- return;
+ if(dumbmov(insn->args[0], insn->args[1]))
+ return;
break;
case Imovs:
- if (insn->args[0]->reg.colour == Rnone || insn->args[1]->reg.colour == Rnone)
- break;
- /* moving a reg to itself is dumb. */
- if (insn->args[0]->reg.colour == insn->args[1]->reg.colour)
+ if(dumbmov(insn->args[0], insn->args[1]))
return;
break;
case Imov:
assert(!isfloatmode(insn->args[0]->mode));
- if (insn->args[0]->type != Locreg || insn->args[1]->type != Locreg)
- break;
- if (insn->args[0]->reg.colour == Rnone || insn->args[1]->reg.colour == Rnone)
- break;
- /* if one reg is a subreg of another, we can just use the right
- * mode to move between them. */
+ /*
+ * if one reg is a subreg of another, we can just use the right
+ * mode to move between them, without any cost.
+ */
if (issubreg(insn->args[0], insn->args[1]))
insn->args[0] = coreg(insn->args[0]->reg.colour, insn->args[1]->mode);
- /* moving a reg to itself is dumb. */
- if (insn->args[0]->reg.colour == insn->args[1]->reg.colour)
+ if(dumbmov(insn->args[0], insn->args[1]))
return;
break;
default:
diff --git a/6/genp9.c b/6/genp9.c
index 32af6de..f366c26 100644
--- a/6/genp9.c
+++ b/6/genp9.c
@@ -105,12 +105,6 @@ locprint(FILE *fd, Loc *l, char spec)
}
}
-static int
-issubreg(Loc *a, Loc *b)
-{
- return rclass(a) == rclass(b) && a->mode != b->mode;
-}
-
static void
iprintf(FILE *fd, Insn *insn)
{
@@ -130,26 +124,22 @@ iprintf(FILE *fd, Insn *insn)
insn->args[1] = coreg(insn->args[1]->reg.colour, ModeL);
}
}
+ if(dumbmov(insn->args[0], insn->args[1]))
+ return;
break;
case Imovs:
- if (insn->args[0]->reg.colour == Rnone || insn->args[1]->reg.colour == Rnone)
- break;
- /* moving a reg to itself is dumb. */
- if (insn->args[0]->reg.colour == insn->args[1]->reg.colour)
+ if(dumbmov(insn->args[0], insn->args[1]))
return;
break;
case Imov:
assert(!isfloatmode(insn->args[0]->mode));
- if (insn->args[0]->type != Locreg || insn->args[1]->type != Locreg)
- break;
- if (insn->args[0]->reg.colour == Rnone || insn->args[1]->reg.colour == Rnone)
- break;
- /* if one reg is a subreg of another, we can just use the right
- * mode to move between them. */
+ /*
+ * if one reg is a subreg of another, we can just use the right
+ * mode to move between them, without any cost.
+ */
if (issubreg(insn->args[0], insn->args[1]))
insn->args[0] = coreg(insn->args[0]->reg.colour, insn->args[1]->mode);
- /* moving a reg to itself is dumb. */
- if (insn->args[0]->reg.colour == insn->args[1]->reg.colour)
+ if(dumbmov(insn->args[0], insn->args[1]))
return;
break;
default:
diff --git a/6/ra.c b/6/ra.c
index da3deca..3ec5cb1 100644
--- a/6/ra.c
+++ b/6/ra.c
@@ -156,6 +156,31 @@ rclass(Loc *l)
return Classbad;
}
+int
+issubreg(Loc *a, Loc *b)
+{
+ if(a->type != Locreg || b->type != Locreg)
+ return 0;
+ if(a->reg.colour == Rnone || b->reg.colour == Rnone)
+ return 0;
+ return rclass(a) == rclass(b) && a->mode != b->mode;
+}
+
+int
+dumbmov(Loc *a, Loc *b)
+{
+ /*
+ * moving a reg to itself is dumb,
+ * but we generate a lot of these as part
+ * of register coalescing.
+ */
+ if (a->type != Locreg || b->type != Locreg)
+ return 0;
+ if (a->reg.colour == Rnone || b->reg.colour == Rnone)
+ return 0;
+ return a->reg.colour == b->reg.colour;
+}
+
/* %esp, %ebp are not in the allocatable pool */
static int
isfixreg(Loc *l)