summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--lisc/rega.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/lisc/rega.c b/lisc/rega.c
index 5173ecc..d368977 100644
--- a/lisc/rega.c
+++ b/lisc/rega.c
@@ -360,9 +360,9 @@ doblk(Blk *b, RMap *cur)
 void
 rega(Fn *fn)
 {
-	int n, t, r, x;
+	int j, n, t, r, r1, x;
 	Blk *b, *b1, *s, ***ps, *blist;
-	RMap *end, *beg, cur;
+	RMap *end, *beg, cur, old;
 	Ins *i;
 	Phi *p;
 	uint u;
@@ -401,14 +401,36 @@ rega(Fn *fn)
 			}
 		end[n] = cur;
 		doblk(b, &cur);
-		beg[n] = cur;
 		b->in = cur.b;
 		for (p=b->phi; p; p=p->link)
-			if (rtype(p->to) == RTmp) {
-				t = p->to.val;
-				BCLR(b->in, t);
-				/* rfree(&cur, t); */
+			if (rtype(p->to) == RTmp)
+				BCLR(b->in, p->to.val);
+		if (b->npred > 1) {
+			/* attempt to satisfy hints
+			 * when it's simple and we have
+			 * multiple predecessors
+			 */
+			old = cur;
+			curi = insb;
+			for (j=0; j<old.n; j++) {
+				t = old.t[j];
+				r = *hint(t);
+				r1 = rfind(&cur, t);
+				if (r != -1 && r != r1)
+				if (!BGET(cur.b, r)) {
+					rfree(&cur, t);
+					radd(&cur, t, r);
+					*curi++ = (Ins){OCopy, tmp[t].wide, TMP(r1), {TMP(r)}};
+				}
+			}
+			if ((j = curi - insb)) {
+				b->nins += j;
+				i = alloc(b->nins * sizeof(Ins));
+				icpy(icpy(i, insb, j), b->ins, b->nins-j);
+				b->ins = i;
 			}
+		}
+		beg[n] = cur;
 	}
 	if (debug['R'])  {
 		fprintf(stderr, "\n> Register mappings:\n");