ref: de1eabd91024f360845dfe7382581e0acbc368e1
parent: 552823815f7c52c16111045b638ba8bab322e7ac
author: Ori Bernstein <ori@eigenstate.org>
date: Wed Jun 10 17:47:45 EDT 2020
Fix check for dumb moves (thanks sgilles) We need to check if we have reg->reg moves.
--- a/6/asm.h
+++ b/6/asm.h
@@ -295,6 +295,8 @@
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, ...);
--- a/6/gengas.c
+++ b/6/gengas.c
@@ -107,12 +107,6 @@
}
}
-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 @@
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:
--- a/6/genp9.c
+++ b/6/genp9.c
@@ -105,12 +105,6 @@
}
}
-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 @@
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:
--- a/6/ra.c
+++ b/6/ra.c
@@ -156,6 +156,31 @@
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)