summary refs log tree commit diff
path: root/lisc/rega.c
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2015-09-15 01:09:55 -0400
committerQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2015-09-15 23:01:33 -0400
commita60cff4d39926461eaa9ec777f793083b44cc690 (patch)
treeb6eefa5faf423c894d03cf2647dfd27f49769fdd /lisc/rega.c
parent8f43615a2140bcdd120e214dbea531f6d22cae09 (diff)
downloadroux-a60cff4d39926461eaa9ec777f793083b44cc690.tar.gz
fix call bug in rega
When rdx is used to return a value and is used as argument,
it is in the call defs and hence made dead by the loop
modified here.  This is obviously erroneous behavior.
We instead rephrase the loop to make it clear that among
the caller-save registers, only the ones used by the call
must be live before the call.
Diffstat (limited to 'lisc/rega.c')
-rw-r--r--lisc/rega.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/lisc/rega.c b/lisc/rega.c
index 1263c6a..e792d55 100644
--- a/lisc/rega.c
+++ b/lisc/rega.c
@@ -320,10 +320,10 @@ rega(Fn *fn)
 		for (i=&b->ins[b->nins]; i!=b->ins;) {
 			switch ((--i)->op) {
 			case OCall:
-				rs = calldef(*i, 0) | callclb(*i, 0);
-				for (r=0; r<NReg; r++)
-					if ((1ll << r) & rs)
-						rfree(&cur, r);
+				rs = calluse(*i, 0);
+				for (r=0; r<NRSave; r++)
+					if (!((1ll << rsave[r]) & rs))
+						rfree(&cur, rsave[r]);
 				continue;
 			case OCopy:
 				if (!isreg(i->arg[0]))