summary refs log tree commit diff
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin@c9x.me>2019-02-06 09:09:03 +0100
committerQuentin Carbonneaux <quentin@c9x.me>2019-02-06 09:09:03 +0100
commitd9b0d77cf20cb8340bc4a77b66aa8cb56c75b496 (patch)
tree111306a07b0010a4ef022df6f96e3c20cae1747d
parentce0ab53ed73fb24f9537cab762467efad56f2664 (diff)
downloadroux-d9b0d77cf20cb8340bc4a77b66aa8cb56c75b496.tar.gz
soften heuristic of 316b57
Instead of systematically spilling any
temp live in an exit branch but not in
the part of the loop already processed,
only spill when it is already known to
have been spilled.
-rw-r--r--spill.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/spill.c b/spill.c
index 2f7ebb2..04afaca 100644
--- a/spill.c
+++ b/spill.c
@@ -280,6 +280,19 @@ dopm(Blk *b, Ins *i, BSet *v)
 	return i;
 }
 
+static void
+merge(BSet *u, Blk *bu, BSet *v, Blk *bv)
+{
+	int t;
+
+	if (bu->loop <= bv->loop)
+		bsunion(u, v);
+	else
+		for (t=0; bsiter(v, &t); t++)
+			if (tmp[t].slot == -1)
+				bsset(u, t);
+}
+
 /* spill code insertion
  * requires spill costs, rpo, liveness
  *
@@ -364,12 +377,10 @@ spill(Fn *fn)
 			 * in the middle of loops */
 			bszero(v);
 			liveon(w, b, s1);
-			if (s1->loop >= b->loop)
-				bsunion(v, w);
+			merge(v, b, w, s1);
 			if (s2) {
 				liveon(u, b, s2);
-				if (s2->loop >= b->loop)
-					bsunion(v, u);
+				merge(v, b, u, s2);
 				bsinter(w, u);
 			}
 			limit2(v, 0, 0, w);