summary refs log tree commit diff
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin@c9x.me>2022-11-21 14:08:08 +0100
committerQuentin Carbonneaux <quentin@c9x.me>2022-11-21 14:16:19 +0100
commit87dc3ea290a4ba75f153c5bb8b9fb87ec548e64f (patch)
tree9e63c0a05a9ce1f79720eda3b15cd801726844ab
parent0db06dad63e02b619671bfb3dd25fc92c0856319 (diff)
downloadroux-87dc3ea290a4ba75f153c5bb8b9fb87ec548e64f.tar.gz
fix allocation ordering bug in rega
When we process one block, we
start by allocating registers
for all the temporaries live
at the exit of the block.

Before this patch we processed
temps first, then in doblk() we
would mark globally live registers
allocated. This meant that temps
could get wrongly assigned a live
register.

The fix is simple: we now process
registers first at block exits,
then allocate temps.
-rw-r--r--rega.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/rega.c b/rega.c
index dd77a75..c97d1e1 100644
--- a/rega.c
+++ b/rega.c
@@ -359,8 +359,6 @@ doblk(Blk *b, RMap *cur)
 	Mem *m;
 	Ref *ra[4];
 
-	for (r=0; bsiter(b->out, &r) && r<Tmp0; r++)
-		radd(cur, r, r);
 	if (rtype(b->jmp.arg) == RTmp)
 		b->jmp.arg = ralloc(cur, b->jmp.arg.val);
 	curi = &insb[NIns];
@@ -534,6 +532,8 @@ rega(Fn *fn)
 				rl[j] = t;
 			}
 		}
+		for (r=0; bsiter(b->out, &r) && r<Tmp0; r++)
+			radd(&cur, r, r);
 		for (j=0; j<x; j++)
 			ralloctry(&cur, rl[j], 1);
 		for (j=0; j<x; j++)