summary refs log tree commit diff
path: root/lisc/spill.c
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2015-09-14 23:36:26 -0400
committerQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2015-09-15 23:01:33 -0400
commitf7bfa2e435c78917bd6df0c80e7e488751dac58c (patch)
treeff55a42ecc560ccde7af547b59c71b94afe6844b /lisc/spill.c
parentbad74e6dce897df9f21cea5bf0a32df298856351 (diff)
downloadroux-f7bfa2e435c78917bd6df0c80e7e488751dac58c.tar.gz
heavy modification of call handling
The IR generated by calls was very bulky because two
instructions were used for marking the live range of
a clobber.

This patch attempts to store the information of what
registers are use/def/clobber in the call instruction
itself, this leads to more compact code (even more
when we'll have SSE registers).  However, I find that
the amount of extra code needed is not really
easonable.  Fortunately it is not too invasive, thus
if the complexity creeps in, it should be easy to
revert.
Diffstat (limited to 'lisc/spill.c')
-rw-r--r--lisc/spill.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/lisc/spill.c b/lisc/spill.c
index 2625ceb..7b2476e 100644
--- a/lisc/spill.c
+++ b/lisc/spill.c
@@ -277,6 +277,7 @@ inregs(Blk *b, Blk *s) /* todo, move to live.c */
 static Ins *
 dopm(Blk *b, Ins *i, Bits *v)
 {
+	int j;
 	Ins *i1;
 
 	/* consecutive moves from
@@ -293,7 +294,14 @@ dopm(Blk *b, Ins *i, Bits *v)
 		|| !isreg((i-1)->arg[0]))
 			break;
 	}
-	limit(v, NReg, 0);
+	if (i > b->ins && (i-1)->op == OCall) {
+		calldef(*--i, &j);
+		limit(v, NReg - NRSave + j, 0);
+		v->t[0] &= ~calldef(*i, 0);
+		v->t[0] |= calluse(*i, 0);
+		setloc(&i->arg[0], v, &(Bits){{0}});
+	} else
+		limit(v, NReg, 0);
 	do
 		emit(*--i1);
 	while (i1 != i);
@@ -388,21 +396,21 @@ spill(Fn *fn)
 		for (i=&b->ins[b->nins]; i!=b->ins;) {
 			assert(bcnt(&v) <= NReg);
 			i--;
-			s = 0;
 			if (i->op == OCopy && isreg(i->arg[0])) {
 				i = dopm(b, i, &v);
 				continue;
 			}
+			s = 0;
+			w = (Bits){{0}};
 			if (!req(i->to, R)) {
 				assert(rtype(i->to) == RTmp);
 				t = i->to.val;
 				if (BGET(v, t))
 					BCLR(v, t);
 				else
-					limit(&v, NReg-1, &w);
+					limit(&v, NReg-1, 0);
 				s = tmp[t].spill;
 			}
-			w = (Bits){{0}};
 			j = opdesc[i->op].nmem;
 			if (!j && rtype(i->arg[0]) == RTmp)
 				BSET(w, i->arg[0].val);