shithub: mc

Download patch

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)