summaryrefslogtreecommitdiff
path: root/chapter25/src/test/java/com
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-09-20 17:46:47 -0700
committerCliff Click <cliffc@acm.org>2026-09-20 17:46:47 -0700
commit1e527b16b28f31b08cbb36b7b1bf2d689487a989 (patch)
treeeca664e141e3dd6e7091573befc1eb16d4a09bc8 /chapter25/src/test/java/com
parent6a5d13d459e40d242bea43f87a4717ad4fcf9e48 (diff)
downloadSimple-1e527b16b28f31b08cbb36b7b1bf2d689487a989.tar.gz
Simple-1e527b16b28f31b08cbb36b7b1bf2d689487a989.zip
Split self-conflict phis once at a loop head
if this works, saves a copy-per-loop. If it fails, next round split as normal
Diffstat (limited to 'chapter25/src/test/java/com')
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/BrainFuckTest.java2
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter24Test.java2
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/codegen/RegAllocTestSupport.java28
3 files changed, 31 insertions, 1 deletions
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/BrainFuckTest.java b/chapter25/src/test/java/com/seaofnodes/simple/BrainFuckTest.java
index a42ebc24..f3da1592 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/BrainFuckTest.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/BrainFuckTest.java
@@ -77,7 +77,7 @@ val brain_fuck = { ->
assertEquals(brain_fuck.length(),A5.ld4s(ptr_arm));
for( int i=0; i<brain_fuck.length(); i++ )
- assertEquals(brain_fuck.charAt(i), A5.ld1z(ptr+4+i));
+ assertEquals(brain_fuck.charAt(i), A5.ld1z(ptr_arm+4+i));
}
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter24Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter24Test.java
index 0abdfb3e..a94f36f2 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter24Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter24Test.java
@@ -12,6 +12,8 @@ import org.junit.Test;
import static org.junit.Assert.*;
public class Chapter24Test {
+ @Test public void testColdLoopSelfConflict() { com.seaofnodes.simple.codegen.RegAllocTestSupport.coldLoopSelfConflict(); }
+
@Test public void testPrintingDeadFunction() throws Exception {
var code = new CodeGen("return 0;").parse();
var tfp = TypeFunPtr.TEST;
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/codegen/RegAllocTestSupport.java b/chapter25/src/test/java/com/seaofnodes/simple/codegen/RegAllocTestSupport.java
index a92859d4..038d6882 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/codegen/RegAllocTestSupport.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/codegen/RegAllocTestSupport.java
@@ -209,6 +209,34 @@ public class RegAllocTestSupport {
assertFalse("A fixed definition clobbers even before coloring",uncolored.sameBlockNoClobber(copy));
}
+ public static void coldLoopSelfConflict() {
+ for( boolean phiConflict : new boolean[]{false,true} ) {
+ CodeGen code = graph();
+ RegAlloc alloc = new RegAlloc(code);
+ Op init = new Op(A,null,null,false,code._start);
+ LoopNode loop = new LoopNode(null,null,code._start);
+ PhiNode phi = new PhiNode("loop",loop,init,null);
+ phi._type = TypeInteger.BOT;
+ Op back = new Op(A,A,null,false,loop,phi);
+ phi.setDef(2,back);
+ Op use = new Op(null,A,null,false,loop,phi);
+ loop.setDef(2,loop);
+ LRG lrg = alloc.newLRG(phi,null);
+ lrg._mask = A;
+ alloc.union(lrg,init); alloc.union(lrg,back);
+ lrg.selfConflict(back);
+ if( phiConflict ) lrg.selfConflict(phi);
+ assertTrue(alloc.splitSelfConflict((byte)0,lrg));
+ assertSame(phi,use.in(1)); // First try leaves the hot definition alone.
+ assertSame(back,phi.in(2));
+ if( phiConflict ) assertTrue(phi.in(1) instanceof SplitNode);
+ // Even if the first attempt made no graph change, retry must split.
+ assertTrue(alloc.splitSelfConflict((byte)1,lrg));
+ assertTrue(phi.in(2) instanceof SplitNode);
+ if( phiConflict ) assertTrue(use.in(1) instanceof SplitNode);
+ }
+ }
+
public static void coalescing() {
// Merge, incompatible masks, interference, capacity, and adjacency remapping.
for( int kind=0; kind<5; kind++ ) {