summaryrefslogtreecommitdiff
path: root/chapter25/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'chapter25/src/test')
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/BulkMemPhiTest.java40
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter05Test.java16
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter06Test.java32
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter07Test.java22
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter08Test.java22
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter09Test.java40
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter10Test.java46
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter12Test.java32
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter13Test.java26
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter14FloatTest.java14
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter14Test.java30
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter15Test.java42
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter16Test.java16
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter17aTest.java16
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter17bTest.java94
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter18Test.java40
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter19Test.java2
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter20Test.java4
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter21Test.java2
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter22Test.java8
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter23Test.java18
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter24Test.java4
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter25Test.java39
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/ClassInitDependenciesTest.java82
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/CompoundAssignmentTest.java2
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Eval2.java18
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Main.java2
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/MemoryEncodingTest.java4
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/MutabilityTest.java4
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/PhaseTest.java64
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Simple.java2
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/StaticDataTest.java20
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/codegen/FlagSpillTestSupport.java141
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/codegen/RegAllocTestSupport.java16
34 files changed, 671 insertions, 289 deletions
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/BulkMemPhiTest.java b/chapter25/src/test/java/com/seaofnodes/simple/BulkMemPhiTest.java
new file mode 100644
index 00000000..31c0302b
--- /dev/null
+++ b/chapter25/src/test/java/com/seaofnodes/simple/BulkMemPhiTest.java
@@ -0,0 +1,40 @@
+package com.seaofnodes.simple;
+
+import com.seaofnodes.simple.codegen.CodeGen;
+import com.seaofnodes.simple.node.*;
+import com.seaofnodes.simple.type.TypeInteger;
+import com.seaofnodes.simple.type.TypeMem;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class BulkMemPhiTest {
+ // Reduced from Capitalize's Lower-phase failure. A precise MemMerge slot
+ // may still be supplied by bulk memory which covers the requested alias.
+ @Test public void testBulkInPreciseSlot() {
+ CodeGen code=new CodeGen("");
+ code._phase=CodeGen.Phase.Lower;
+ Node m0=code.con(TypeMem.START), m1=code.con(TypeMem.BOT);
+ Node ctrl=new CProjNode(code._start,0,"Ctrl").init();
+ Node iff=new IfNode(ctrl,code.con(TypeInteger.BOOL)).init();
+ RegionNode region=new RegionNode(null,null,
+ new CProjNode(iff,0,"True").init(),
+ new CProjNode(iff,1,"False").init()).init();
+ BulkMemPhiNode bulk=new BulkMemPhiNode("$mem",region,m0,m1).init();
+ // A later init check proves its call arm dead. Its precise Phi can
+ // collapse before the surrounding aggregate gets another peephole.
+ RegionNode done=new RegionNode(null,null,region,code.XCTRL).init();
+ MemPhiNode precise=new MemPhiNode("$4",4,done,bulk,m1).init();
+ MemMergeNode merge=new MemMergeNode(null,m0);
+ merge.alias(4,precise);
+ merge.init();
+ Node folded=precise.peepholeOpt();
+ assertSame(bulk,folded);
+ precise.subsume(folded);
+
+ assertFalse(bulk.isSplit(4));
+ assertSame(bulk,merge.alias(4));
+ // Splitting this still-covered alias must tolerate the direct bulk use.
+ Node mem = bulk.idealize();
+ bulk.subsume(mem);
+ }
+}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter05Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter05Test.java
index 5b57e701..afdb1071 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter05Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter05Test.java
@@ -20,7 +20,7 @@ else {
}
return a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,(arg+2),(arg-3));", code.print());
}
@@ -36,7 +36,7 @@ if (arg == 1) {
}
return c;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,4,3);", code.print());
}
@@ -64,7 +64,7 @@ if( arg==1 )
else
b=a+1;
return a+b;""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return ((arg<<1)+Phi(Region,2,3));", code.print());
}
@@ -79,7 +79,7 @@ if( arg==1 )
else
a=b+1;
return a+b;""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return ((Phi(Region,(arg<<1),arg)+arg)+Phi(Region,4,5));", code.print());
}
@@ -99,7 +99,7 @@ else
a=5;
return a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,3,5,2,4);", code.print());
}
@@ -115,7 +115,7 @@ if( arg==0 )
b=2;
return arg+a+b;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
String ir = code.print();
assertTrue(ir,
ir.equals("return ((arg+Phi(Region,1,0))+Phi(Region,2,0));") ||
@@ -133,7 +133,7 @@ if( arg==1 )
}
return a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return (arg==Phi(Region,3,2));", code.print());
}
@@ -148,7 +148,7 @@ else
a=3;
return a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 3;", code.print());
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter06Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter06Test.java
index c503b56c..d1af5d14 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter06Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter06Test.java
@@ -15,7 +15,7 @@ public class Chapter06Test {
if( true ) return 2;
return 1;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 2;", code.print());
assertTrue(code.ctrl() instanceof FunNode);
}
@@ -29,7 +29,7 @@ if (arg)
a = 2;
return (arg < a) < 3; // Because (arg < a) is a bool/uint1/[0-1], its always less than 3
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 1;", code.print());
}
@@ -44,7 +44,7 @@ else
a=3;
return a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 2;", code.print());
assertTrue(code.ctrl() instanceof FunNode);
}
@@ -65,7 +65,7 @@ else
b=5;
return b;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,42,5);", code.print());
}
@@ -84,7 +84,7 @@ if( arg==2 )
else
b=5;
return b;""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,2,5);", code.print());
}
@@ -104,7 +104,7 @@ else if( arg==3 )
else
a=5;
return a;
-""", TypeInteger.constant(2)).parse().iter().opto().iterPostOpto().finalizeIR();
+""", TypeInteger.constant(2)).driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 5;", code.print());
}
@@ -124,7 +124,7 @@ else if( arg==3 )
else
a=5;
return a;
-""", TypeInteger.constant(1)).parse().iter().opto().iterPostOpto().finalizeIR();
+""", TypeInteger.constant(1)).driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 3;", code.print());
}
@@ -144,7 +144,7 @@ else
a=5;
return a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,3,5,4);", code.print());
}
@@ -165,7 +165,7 @@ else
a=5;
return a;
""", TypeInteger.constant(1));
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 3;", code.print());
}
@@ -186,7 +186,7 @@ else
a=5;
return a;
""", TypeInteger.constant(3));
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 4;", code.print());
}
@@ -202,7 +202,7 @@ if( arg ) {
}
return a+b;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,4,1);", code.print());
}
@@ -221,7 +221,7 @@ if( arg ) {
}
return a+b;
""", TypeInteger.constant(1));
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 4;", code.print());
}
@@ -239,7 +239,7 @@ if( arg ) {
}
return a+b;
""", TypeInteger.constant(0));
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 1;", code.print());
}
@@ -257,7 +257,7 @@ if( arg ) {
}
return a+b+c;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,6,1,5);", code.print());
}
@@ -278,7 +278,7 @@ if( arg ) {
}
return a+b+c;
""", TypeInteger.constant(1));
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 6;", code.print());
}
@@ -298,7 +298,7 @@ if( arg ) {
}
return a+b+c;
""", TypeInteger.constant(2));
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 5;", code.print());
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter07Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter07Test.java
index 498038c1..7094c0d5 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter07Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter07Test.java
@@ -17,7 +17,7 @@ while(arg < 10) {
}
return arg;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,arg,(Phi_arg+1));", code.print());
assertTrue(code.ctrl() instanceof CProjNode);
}
@@ -34,7 +34,7 @@ if(arg){}else{
}
return a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,1,Phi(Loop,1,(Phi_a+1)));", code.print());
}
@@ -54,7 +54,7 @@ while(i < arg) {
}
return sum;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,0,Phi(Loop,Phi_sum,(Phi_sum+Phi(Loop,0,(Phi_j+1)))));", code.print());
}
@@ -89,7 +89,7 @@ while(a < 10) {
}
return b;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,2,(Phi(Region,Phi_b,4)+1));", code.print());
assertTrue(code.ctrl() instanceof CProjNode);
}
@@ -106,7 +106,7 @@ while(a < 10) {
}
return a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,1,(Phi_a+3));", code.print());
assertTrue(code.ctrl() instanceof CProjNode);
}
@@ -122,7 +122,7 @@ while(a < 10) {
}
return a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,1,(Phi_a+3));", code.print());
assertTrue(code.ctrl() instanceof CProjNode);
}
@@ -148,7 +148,7 @@ int a = 1;
while(arg) a = 2;
return a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,1,2);", code.print());
assertTrue(code.ctrl() instanceof CProjNode);
}
@@ -164,7 +164,7 @@ while(a < 10) {
}
return a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,1,(Phi_a+3));", code.print());
assertTrue(code.ctrl() instanceof CProjNode);
}
@@ -180,7 +180,7 @@ while(a < 10) {
}
return a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,1,(Phi_a+3));", code.print());
assertTrue(code.ctrl() instanceof CProjNode);
}
@@ -197,7 +197,7 @@ while(a < 10) {
}
return a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,1,(Phi_a+3));", code.print());
assertTrue(code.ctrl() instanceof CProjNode);
}
@@ -214,7 +214,7 @@ while(a < 10) {
}
return a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,1,(Phi_a+3));", code.print());
assertTrue(code.ctrl() instanceof CProjNode);
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter08Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter08Test.java
index 61815840..376e472b 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter08Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter08Test.java
@@ -22,7 +22,7 @@ while(arg < 10) {
}
return arg;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,(Phi(Loop,arg,Add)+1),Add,Phi_arg);", code.print());
assertTrue(code.ctrl() instanceof RegionNode);
Assert.assertEquals( "5", Eval2.eval(code, 1));
@@ -45,7 +45,7 @@ while(arg < 10) {
}
return a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,1,Phi(Region,Phi_a,(Phi_a+1),Phi_a));", code.print());
assertTrue(code.ctrl() instanceof CProjNode);
}
@@ -64,7 +64,7 @@ while(arg < 10) {
}
return arg;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,Phi(Loop,arg,(Phi_arg+1)),Add);", code.print());
assertTrue(code.ctrl() instanceof RegionNode);
}
@@ -80,7 +80,7 @@ while(arg < 10) {
}
return arg;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,Phi(Loop,arg,(Phi_arg+1)),Add);", code.print());
assertTrue(code.ctrl() instanceof RegionNode);
}
@@ -99,7 +99,7 @@ while(arg < 10) {
}
return arg;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,arg,(Phi_arg+1));", code.print());
assertTrue(code.ctrl() instanceof CProjNode);
}
@@ -116,7 +116,7 @@ while(arg < 10) {
}
return arg;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,arg,(Phi_arg+1));", code.print());
assertTrue(code.ctrl() instanceof CProjNode);
}
@@ -132,14 +132,14 @@ while( arg < 10 ) {
}
return arg;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return arg;", code.print());
}
@Test
public void testRegress2() {
CodeGen code = new CodeGen("if(1) return 0; else while(arg>- -arg) arg=arg+1; return 0;");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
}
@@ -167,7 +167,7 @@ while(arg < 10) {
}
return arg;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return arg;", code.print());
}
@@ -184,7 +184,7 @@ while(arg < 10) {
}
return a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,Phi(Loop,1,(Phi_a+1)),Add);", code.print());
assertTrue(code.ctrl() instanceof RegionNode);
}
@@ -200,7 +200,7 @@ while(1) {
}
return a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return (Phi(Loop,1,Add)+1);", code.print());
assertTrue(code.ctrl() instanceof CProjNode prj && prj._idx==1 );
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter09Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter09Test.java
index 839b834d..7025b98a 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter09Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter09Test.java
@@ -24,7 +24,7 @@ while(v0) {
}
return 0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
}
@Test
@@ -40,7 +40,7 @@ else {
}
return x;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,(arg<<1),(Shl+1));", code.print());
Assert.assertEquals( "2", Eval2.eval(code, 1));
Assert.assertEquals("23", Eval2.eval(code, 11));
@@ -49,7 +49,7 @@ return x;
@Test
public void testGVN2() {
CodeGen code = new CodeGen("return arg*arg-arg*arg;");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
Assert.assertEquals("0", Eval2.eval(code, 1, 1));
}
@@ -63,7 +63,7 @@ while (arg < 10) {
}
return arg;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,arg,(Phi_arg+2));", code.print());
Assert.assertEquals("11", Eval2.eval(code, 1));
}
@@ -80,7 +80,7 @@ while (arg < 10) {
}
return arg;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,arg,(Phi_arg+4));", code.print());
Assert.assertEquals("13", Eval2.eval(code, 1));
}
@@ -109,7 +109,7 @@ while (arg) {
}
return arg;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
}
@@ -128,14 +128,14 @@ while(v1+arg) {
}
return 0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
}
@Test
public void testWhile0() {
CodeGen code = new CodeGen("while(0) continue; if(0) arg=0; return arg;");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return arg;", code.print());
}
@@ -148,7 +148,7 @@ if(0) while(0) {
}
return 0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
}
@@ -156,14 +156,14 @@ return 0;
@Test
public void testPrecedence() {
CodeGen code = new CodeGen("return 3-1+2;");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 4;", code.print());
}
@Test
public void testSwap2() {
CodeGen code = new CodeGen("return 1+(1+1);");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 3;", code.print());
}
@@ -181,7 +181,7 @@ while(arg) {
}
return a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,0,(-(Phi_a+3)));", code.print());
}
@@ -195,7 +195,7 @@ arg=0;
int v0=0!=0<-0;
return -0+0+0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Top;", code.print());
}
@@ -203,14 +203,14 @@ return -0+0+0;
@Test
public void testFuzz2() {
CodeGen code = new CodeGen("return 0+-0;");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
}
@Test
public void testFuzz3() {
CodeGen code = new CodeGen("int v0=0; while(0==69) while(v0) return 0; return 1;");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 1;", code.print());
}
@@ -222,7 +222,7 @@ while(1) {
if(1<0) while(arg==-0) arg=arg-arg;
}
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Top;", code.print());
}
@@ -244,7 +244,7 @@ while(1) {
}
return 0!=0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Top;", code.print());
}
@@ -257,7 +257,7 @@ while(0==1) while(v0)
v0=1+v0;
return 0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
}
@@ -273,14 +273,14 @@ while(1)
v1=1;
return v1+v0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Top;", code.print());
}
@Test
public void testFuzz8() {
CodeGen code = new CodeGen("while(arg) arg = arg - 1; return arg;");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter10Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter10Test.java
index 1b542d63..924884ac 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter10Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter10Test.java
@@ -12,7 +12,7 @@ public class Chapter10Test {
"if(1) return new S; else return 0;"
} ) {
String src = "struct S { int x; }; " + body;
- var code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ var code = new CodeGen(src).driver(CodeGen.Phase.TypeCheck);
// This chapter also has constructor/class-init Returns in the CompUnit.
var entry = (com.seaofnodes.simple.node.FunNode)code._start.uctrl();
org.junit.Assert.assertTrue(body,
@@ -102,7 +102,7 @@ if( (arg/13)==0 ) {
int r = g+h;
return p-r;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
}
@@ -122,7 +122,7 @@ bar.a = 1;
bar.a = 2;
return bar.a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 2;", code.print());
}
@@ -138,7 +138,7 @@ else
v.y = 3;
return v;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("Stop[ return Test.Vector2D; return MEM[ 2:___ 3:.x=0; 4:.y=0;]; return Test.Vector2D; ]", code.print());
}
@@ -151,7 +151,7 @@ struct s0 {
s0? v1=null;
int v3=v1.zAicm;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Might be null accessing 'zAicm'",e.getMessage()); }
}
@@ -176,7 +176,7 @@ while (arg) {
}
return bar.a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("Stop[ return Phi(Loop,0,(Phi_a+2)); return MEM[ 2:___ 3:.a=0;]; return Test.Bar; ]", code.print());
}
@@ -189,7 +189,7 @@ if (arg) bar = null;
bar.a = 1;
return bar.a;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Type null is not of declared type *Test.Bar",e.getMessage()); }
}
@@ -202,7 +202,7 @@ if (arg) bar = new Bar;
bar.a = 1;
return bar.a;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Might be null accessing 'a'",e.getMessage()); }
}
@@ -215,7 +215,7 @@ if (arg) bar = null;
bar.a = 1;
return bar.a;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Type null is not of declared type *Test.Bar", e.getMessage()); }
}
@@ -228,7 +228,7 @@ if (arg) bar = null;
if( bar ) bar.a = 1;
return bar.a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,1,.a);", code.print());
}
@@ -244,7 +244,7 @@ if( !bar ) rez=4;
else bar.a = 1;
return rez;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,4,3);", code.print());
}
@@ -261,7 +261,7 @@ while(arg) {
}
return ret;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) {
assertEquals("Might be null accessing 'v0'", e.getMessage()); }
}
@@ -298,7 +298,7 @@ while( i.x < i.len ) {
}
return sum;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("Stop[ return Phi(Loop,0,(Phi(Loop,0,(Phi_x+1))+Phi_sum)); return MEM[ 2:___ 3:.x=0; 4:.len=0;]; return Test.Iter; ]", code.print());
}
@@ -317,7 +317,7 @@ while(arg) {
}
return ret;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("Stop[ return Phi(Loop,Test.s0,Phi(Region,Test.s0,Phi_ret)); return MEM[ 2:___ 3:.v0=0;]; return Test.s0; ]", code.print());
}
@@ -334,7 +334,7 @@ while(arg) {
}
return ret.v0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return .v0;", code.print());
}
@@ -351,7 +351,7 @@ while(arg < 10) {
}
return ret.v0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return .v0;", code.print());
}
@@ -370,7 +370,7 @@ s0 b = new s0();
// a.x==1, b.x==1, cnt==2
return a.x * 100 + b.x * 10 + cnt;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("Stop[ return 112; return MEM[ 2:___ 3:___ 4:.x=1;]; return Test.s0; ]", code.print());
}
@@ -399,7 +399,7 @@ if(0) {
}
return 0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
}
@@ -413,7 +413,7 @@ if(0) return 0;
else return new s0;
if(new s0.f0) return 0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
assertEquals("Stop[ return Test.s0; return MEM[ 2:___ 3:.f0=0;]; return Test.s0; ]", code.print());
}
@@ -429,7 +429,7 @@ while(0<arg) {
}
return 0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
}
@Test
@@ -441,7 +441,7 @@ while(v0.f0) {}
s0 v1 = v0;
return v1;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("Stop[ return (const)Test.s0; return MEM[ 2:___ 3:.f0=0;]; return Test.s0; ]", code.print());
}
@@ -474,7 +474,7 @@ while(0) {}
}
return 0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
}
@@ -485,7 +485,7 @@ int v0=arg==0;
while(v0) continue;
return 0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter12Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter12Test.java
index 19c531f8..fae7611d 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter12Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter12Test.java
@@ -14,7 +14,7 @@ public class Chapter12Test {
"""
return 3;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 3;", code.print());
assertEquals("3", Eval2.eval(code, 0));
}
@@ -34,7 +34,7 @@ while( arg ) {
}
return head.next.i;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Might be null accessing 'next'",e.getMessage()); }
}
@@ -56,7 +56,7 @@ _LLI? next = head.next;
if( next==null ) return 1;
return next.q;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
assertEquals("return Phi(Region,1,.q,0);", code.print());
assertEquals("2", Eval2.eval(code, 3));
}
@@ -75,7 +75,7 @@ i0.f = f0;
f0.i = i0;
return f0.i.f.i.i;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
assertEquals("return 17;", code.print());
}
@@ -87,7 +87,7 @@ struct _N { !_N? !next; int i; };
_N n = new _N;
return n.next;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return null;", code.print());
}
@@ -100,7 +100,7 @@ struct N { !M !next; int i; new N = { !M m -> next = m; }; };
N n = new N(new M);
return n.next;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("Stop[ return (const)Test.M; return MEM[ 2:___ 3:.m=0;]; return Test.M; return MEM[ 2:___ 3:___ 4:___ 5:___ 6:___ 7:.next=Parm_m(Test.N.N,*Test.M {i64 !m; }); 8:.i=0;]; return MEM[ 2:___ 3:___ 4:___ 5:___ 6:___ 7:___ 8:.i=0;]; return Test.N; ]", code.print());
}
@@ -113,7 +113,7 @@ struct N { !M !next; int i; new N = { !M m -> next = m; }; };
N n = new N(null);
return n.next;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Argument #0 isa null, but must be a *Test.M {i64 !m; }",e.getMessage()); }
}
@@ -126,20 +126,20 @@ struct N { !N? !next; int i; };
n.i = 3.14;
return n.i;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
assertEquals("3",Eval2.eval(code,0));
}
@Test
public void testNullRef4() {
CodeGen code = new CodeGen("return -null-5/null-5;");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Cannot null + 5",e.getMessage()); }
}
@Test public void testNullRef5() {
CodeGen code = new CodeGen("return null+42;");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Cannot null + 42",e.getMessage()); }
}
@@ -150,7 +150,7 @@ return n.i;
struct _S{};
return 0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
assertEquals("0", Eval2.eval(code, 0));
}
@@ -162,7 +162,7 @@ return 0;
struct S1 { S2? s; };
return new S2;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Unknown struct type 'S2'",e.getMessage()); }
}
@@ -174,7 +174,7 @@ struct _S1 { !_S2? !s; };
struct _S2 { int x; };
return (new _S1).s=new _S2;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Test._S2;", code.print());
}
@@ -191,7 +191,7 @@ p2.pi.i = 2;
if (arg) p1 = new P;
return p1.pi.i + 1;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Might be null accessing 'i'",e.getMessage()); }
}
@@ -210,7 +210,7 @@ c.f0=a; c.f1=b;
return a.f0.f1.f0.f1.f0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck().GCM().localSched();
+ code.driver(CodeGen.Phase.FinalizeIR).driver(CodeGen.Phase.Schedule).localSched();
assertEquals("return Test._B;", code.print());
assertEquals("Test._B{f0=Test._C{f0=Test._A{f0=$cyclic,f1=$cyclic},f1=$cyclic},f1=$cyclic}", Eval2.eval(code, 0));
}
@@ -276,7 +276,7 @@ z.a=k; z.b=s; z.c=e;
return a.b.c.a.b.c.a.b.c.a.b.c.a.b.c.a.b.c;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck().GCM().localSched();
+ code.driver(CodeGen.Phase.FinalizeIR).driver(CodeGen.Phase.Schedule).localSched();
assertEquals("return Test._R;", code.print());
assertEquals("Test._R{a=Test._C{a=Test._N{a=Test._Y{a=Test._J{a=Test._U{a=Test._F{a=Test._Q{a=Test._B{a=Test._M{a=Test._X{a=Test._I{a=Test._T{a=Test._E{a=Test._P{a=Test._A{a=Test._L{a=Test._W{a=Test._H{a=Test._S{a=Test._D{a=Test._O{a=Test._Z{a=Test._K{a=Test._V{a=Test._G{a=$cyclic,b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic},b=$cyclic,c=$cyclic}", Eval2.eval(code, 0));
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter13Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter13Test.java
index 9786006c..214bc69e 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter13Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter13Test.java
@@ -34,7 +34,7 @@ while( prime <= arg ) {
}
return primeCount;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,0,Phi(Loop,1,Phi(Region,Phi_primeCount,Phi_primeCount,(Phi_primeCount+1))));", code.print());
assertEquals("0", Eval2.eval(code, 1)); // No primes 1 or below
assertEquals("1", Eval2.eval(code, 2)); // 2
@@ -73,7 +73,7 @@ i=v.f;
if (arg) v.f=1;
return i;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 2;", code.print());
assertEquals("2", Eval2.eval(code, 0));
assertEquals("2", Eval2.eval(code, 1));
@@ -96,7 +96,7 @@ if (arg) {
}
return i;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,.f,0);", code.print());
}
@@ -115,7 +115,7 @@ if (v1) {
}
return v0.f;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,.f,2);", code.print());
}
@@ -133,7 +133,7 @@ if (arg+1) arg= 0;
while (arg) v.f = 2;
return i;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return arg;", code.print());
}
@@ -150,7 +150,7 @@ while(1) {
}
return v.f;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,0,2);", code.print());
for( int arg : new int[]{-1,0,1,3,100} )
assertEquals("0",Eval2.eval(code,arg));
@@ -167,7 +167,7 @@ while( -arg )
while(1)
arg = arg+ptr.v;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Top;", code.print());
}
@@ -185,7 +185,7 @@ while (arg) {
}
return i;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
}
@@ -205,7 +205,7 @@ while(arg) {
}
return arg;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
}
@@ -223,7 +223,7 @@ if (arg) {
}
return v.f;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
}
@@ -242,7 +242,7 @@ while (arg > 0) {
}
return v;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
//assertEquals("return new _S;", code.print());
}
@@ -259,7 +259,7 @@ while(0>=0) {
}
return 0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Top;", code.print());
}
@@ -277,7 +277,7 @@ u32 v0=0;
return v1;
}
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter14FloatTest.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter14FloatTest.java
index ccca2e2b..e058a822 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter14FloatTest.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter14FloatTest.java
@@ -18,7 +18,7 @@ public class Chapter14FloatTest {
{"f32 rounded=arg+16777216.0; return rounded;", "1.6777232E7", "1.6777199E7"}
};
for( String[] test : tests ) {
- var code = new CodeGen(test[0]).parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ var code = new CodeGen(test[0]).driver(CodeGen.Phase.TypeCheck);
assertEquals(test[0],test[1],Eval2.eval(code,17));
assertEquals(test[0],test[2],Eval2.eval(code,-17));
}
@@ -26,7 +26,7 @@ public class Chapter14FloatTest {
@Test public void testSubZeroFloat() {
- var code = new CodeGen("flt x = arg; return 0-x;").parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ var code = new CodeGen("flt x = arg; return 0-x;").driver(CodeGen.Phase.TypeCheck);
// Compare strings so +0.0 and -0.0 remain distinct.
assertEquals("0.0", Eval2.eval(code,0));
assertEquals("-1.0", Eval2.eval(code,1));
@@ -40,7 +40,7 @@ public class Chapter14FloatTest {
{"return 2.5; return 7;", "2.5"}
} ) {
String src = test[0];
- var code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ var code = new CodeGen(src).driver(CodeGen.Phase.TypeCheck);
assertEquals(src,test[1],Eval2.eval(code,0));
}
}
@@ -53,7 +53,7 @@ public class Chapter14FloatTest {
"""
return 0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
assertEquals("0", Eval2.eval(code, 0));
}
@@ -65,7 +65,7 @@ return 0;
flt x = 3.14;
return 0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
assertEquals("0", Eval2.eval(code, 0));
}
@@ -84,7 +84,7 @@ return guess;
""");
// TODO: One of the problems with <clinit> returning an OS error code,
// is it chops all results to int.
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,(flt)arg,((Phi_guess+(ToFloat/Phi_guess))*0.5f));", code.print());
assertEquals("3.0", Eval2.eval(code, 9));
assertEquals("1.414213562373095", Eval2.eval(code, 2));
@@ -97,7 +97,7 @@ return guess;
flt x = arg;
return x+1==x;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return ((flt)arg==(ToFloat+1.0f));", code.print());
assertEquals("0", Eval2.eval(code, 1));
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter14Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter14Test.java
index 3ba03b48..bc2ad8d3 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter14Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter14Test.java
@@ -16,7 +16,7 @@ public class Chapter14Test {
"""
return 3.14;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 3.14;", code.print());
assertEquals("3.14", Eval2.eval(code, 0));
}
@@ -32,7 +32,7 @@ if( b < 0 ) c = -1;
if( b > 2 ) c = 1;
return c;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 99;", code.print());
assertEquals("99", Eval2.eval(code, 0));
}
@@ -45,7 +45,7 @@ u8 b = 123;
b = b + 456;// Truncate
return b;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 67;", code.print());
assertEquals("67", Eval2.eval(code, 0));
}
@@ -59,7 +59,7 @@ u8 b = 123;
while( b ) b = b + 456;// Truncate
return b;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
}
@@ -72,7 +72,7 @@ b = b + 456;// Truncate
u1 c = b; // No more truncate needed
return c;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 1;", code.print());
assertEquals("1", Eval2.eval(code, 0));
}
@@ -85,7 +85,7 @@ int b = 123;
b = b+456 & 31; // Precedence
return b;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 3;", code.print());
assertEquals("3", Eval2.eval(code, 0));
}
@@ -99,7 +99,7 @@ struct _Foo { u1 b; };
f.b = 123;
return f.b;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
assertEquals("return 1;", code.print());
assertEquals("1", Eval2.eval(code, 0));
}
@@ -111,7 +111,7 @@ return f.b;
i8 b = 255; // Chopped
return b; // Sign extend
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return -1;", code.print());
assertEquals("-1", Eval2.eval(code, 0));
}
@@ -124,7 +124,7 @@ i8 b = arg;
b = b + 1;// Truncate
return b;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return (((((arg<<56)>>56)+1)<<56)>>56);", code.print());
assertEquals("1", Eval2.eval(code, 0));
assertEquals("-128", Eval2.eval(code, 127));
@@ -138,7 +138,7 @@ u16 mask = (1<<16)-1; // AND mask
int c = 123456789 & mask;
return c; //
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 52501;", code.print());
assertEquals("52501", Eval2.eval(code, 0));
}
@@ -149,7 +149,7 @@ return c; //
"""
return (arg | 123 ^ 456) >>> 1;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return (((arg|123)^456)>>>1);", code.print());
assertEquals("217", Eval2.eval(code, 0));
}
@@ -162,7 +162,7 @@ flt f = arg;
arg = f & 1;
return arg;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Cannot '&' flt",e.getMessage()); }
}
@@ -175,7 +175,7 @@ while(arg) v1=-v0;
while(v1) break;
return v1;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,(((1<<arg)&1)&Shl),0);", code.print());
assertEquals("1", Eval2.eval(code, 0));
}
@@ -194,7 +194,7 @@ if(0&0>>>0) {
}
return v0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
assertEquals("0", Eval2.eval(code, 0));
}
@@ -220,7 +220,7 @@ f32 ff32 = 3.141592653589793; if( ff32 != 3.1415927410125732) return 5;
return 0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
assertEquals("0", Eval2.eval(code, 0));
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter15Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter15Test.java
index 3c1254d2..25f00474 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter15Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter15Test.java
@@ -17,7 +17,7 @@ public class Chapter15Test {
"""
return 3.14;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 3.14;", code.print());
assertEquals("3.14", Eval2.eval(code, 0));
}
@@ -31,7 +31,7 @@ struct _C { !_C? !l; };
c.l = c;
return c;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Test._C;", code.print());
assertEquals("Test._C{l=$cyclic}", Eval2.eval(code, 0));
}
@@ -50,7 +50,7 @@ while (i < old#) {
output[i] = 1;
return output;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return []u8;", code.print());
assertEquals("\u0001", Eval2.eval(code, 0));
}
@@ -62,7 +62,7 @@ return output;
int[] is = new int[2];
return is[1];
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
assertEquals("0", Eval2.eval(code, 0));
}
@@ -75,7 +75,7 @@ int[] is = new int[2];
int[] is2 = new int[2];
return is[1];
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
assertEquals("0", Eval2.eval(code, 0));
}
@@ -89,7 +89,7 @@ a[0] = 1;
a[1] = 2;
return a[0];
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 1;", code.print());
assertEquals("1", Eval2.eval(code, 0));
}
@@ -102,7 +102,7 @@ struct _A { int i; };
!_A?[] !a = new !_A?[2];
return a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return []*Test._A?;", code.print());
assertEquals("*Test._A {i64 !i; }?[ null,null]", Eval2.eval(code, 0));
}
@@ -131,7 +131,7 @@ else {
}
return rez;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,1.2,.y,2.3);", code.print());
assertEquals("3.14", Eval2.eval(code, 0));
assertEquals("1.2", Eval2.eval(code, 1));
@@ -156,7 +156,7 @@ if( iss[arg] )
if( iss[arg][2] )
rez = iss[arg][2].y;
return rez;""");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
assertEquals("return Phi(Region,1.2,1.2,.y);", code.print());
assertEquals("3.14", Eval2.eval(code, 0));
try { Eval2.eval(code, 10); fail(); } // Fails AIOOBE in Eval2, no range checks
@@ -174,7 +174,7 @@ root._kids = new !_Tree?[2]; // NO BANG SO ARRAY IS OF IMMUTABLE TREES????
root._kids[0] = new _Tree;
return root;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
assertEquals("return Test._Tree;", code.print());
assertEquals("Test._Tree{_kids=*Test._Tree {*[]*Test._Tree?[mutable]? !_kids; }?[ Test._Tree{_kids=null},null]}", Eval2.eval(code, 0));
}
@@ -186,7 +186,7 @@ return root;
struct _S { int a; int[] !b; new _S = { int[] ary -> b=ary; }; };
return 0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
}
@@ -209,7 +209,7 @@ while( i < ary# - 1 ) {
}
return ary[1] * 1000 + ary[3]; // 1 * 1000 + 6
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
assertEquals("return (.[]+(.[]*1000));", code.print());
assertEquals("1006", Eval2.eval(code, 4));
}
@@ -218,7 +218,7 @@ return ary[1] * 1000 + ary[3]; // 1 * 1000 + 6
public void sieveOEratosthenes() throws IOException {
String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/sieve.smp"));
CodeGen code = new CodeGen(src+"return sieve(arg);");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return []u32;", code.print());
assertEquals("u32[ 2,3,5,7,11,13,17,19]",Eval2.eval(code, 20));
}
@@ -235,7 +235,7 @@ s2.f = 2.0;
if (arg) s1 = new _S;
return s1.i + s1.f;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return ((flt).i+.f);", code.print());
assertEquals("0.0", Eval2.eval(code, 0));
}
@@ -247,7 +247,7 @@ return s1.i + s1.f;
"""
return new flt;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR(); fail(); }
+ try { code.driver(CodeGen.Phase.FinalizeIR); fail(); }
catch( Exception e ) { assertEquals("Cannot allocate a flt",e.getMessage()); }
}
@@ -258,7 +258,7 @@ return new flt;
flt is = new int[2];
return is;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Type *[]i64 is not of declared type flt",e.getMessage()); }
}
@@ -269,7 +269,7 @@ return is;
int[] is = new int[3.14];
return is[1];
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Cannot '<<' 3.14",e.getMessage()); }
}
@@ -279,7 +279,7 @@ return is[1];
int[] is = new int[arg];
return is[1];
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
assertEquals("0", Eval2.eval(code, 4));
try { Eval2.eval(code,-1); fail(); }
@@ -312,7 +312,7 @@ while(v5+(0&0)) {
}
return v1;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
assertEquals("0", Eval2.eval(code, 0));
}
@@ -328,7 +328,7 @@ int v8=0;
while(0<--1>>>---(v7*0==v8)) {}
return 0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
}
@@ -353,7 +353,7 @@ else {
}
return 0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
}
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter16Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter16Test.java
index ad9b99bc..2942cfee 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter16Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter16Test.java
@@ -15,7 +15,7 @@ public class Chapter16Test {
"""
return 3.14;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 3.14;", code.print());
assertEquals("3.14", Eval2.eval(code, 0));
}
@@ -28,7 +28,7 @@ return 3.14;
int x, y;
return x+y;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
assertEquals("0", Eval2.eval(code, 0));
}
@@ -39,7 +39,7 @@ return x+y;
int x=2, y=x+1;
return x+y;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 5;", code.print());
assertEquals("5", Eval2.eval(code, 0));
}
@@ -52,7 +52,7 @@ struct _X { int x=3; };
_X z = new _X;
return z.x;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 3;", code.print());
assertEquals("3", Eval2.eval(code, 0));
}
@@ -64,7 +64,7 @@ struct _X { int x=3; new _X = { int xx -> x=xx; }; };
_X z = new _X(4);
return z.x;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 4;", code.print());
assertEquals("4", Eval2.eval(code, 0));
}
@@ -85,7 +85,7 @@ _LLI? next = head.next;
if( !next ) return 1;
return next.i;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,1,.i,0);", code.print());
assertEquals("0", Eval2.eval(code, 0));
assertEquals("1", Eval2.eval(code, 1));
@@ -115,7 +115,7 @@ _LLI? next = head.next;
if( !next ) return 1;
return next.i;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,1,.i,0);", code.print());
assertEquals("0", Eval2.eval(code, 0));
assertEquals("1", Eval2.eval(code, 1));
@@ -140,7 +140,7 @@ struct _Square {
};
return new _Square;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Test._Square;", code.print());
assertEquals("Test._Square{side=3.0,diag=1.7320508075688772}", Eval2.eval(code, 3));
assertEquals("Test._Square{side=4.0,diag=2.0}", Eval2.eval(code, 4));
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter17aTest.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter17aTest.java
index 95a0fc37..ea7afe56 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter17aTest.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter17aTest.java
@@ -15,7 +15,7 @@ int x=2, y=3;
if( arg ) { int x = y; x = x*x; y=x; } // Shadow final x
return y;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,9,3);", code.print());
assertEquals("3", Eval2.eval(code, 0));
assertEquals("9", Eval2.eval(code, 1));
@@ -28,7 +28,7 @@ struct _X { int ~x; new _X = { int xx -> x=xx; }; };
_X z = new _X(3);
return z.x;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 3;", code.print());
assertEquals("3", Eval2.eval(code, 0));
}
@@ -40,7 +40,7 @@ struct _Point { int ~x, ~y; new _Point = { int xx, int yy -> x=xx; y=yy; }; };
_Point p = new _Point(3,4);
return p;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return (const)Test._Point;", code.print());
assertEquals("Test._Point{x=3,y=4}", Eval2.eval(code, 0));
}
@@ -53,7 +53,7 @@ struct _Point { int x=3, y=4; new _Point = { int xx, int yy -> x=xx; y=yy; }; };
p.x++;
return p;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Cannot modify final field 'x'",e.getMessage()); }
}
@@ -65,7 +65,7 @@ struct _Point { int x=3, y=4; };
p.x++;
return p;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Cannot modify final field 'x'",e.getMessage()); }
}
@@ -77,7 +77,7 @@ _Point p = new _Point;
p.x++;
return p;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR(); fail(); }
+ try { code.driver(CodeGen.Phase.FinalizeIR); fail(); }
catch( Exception e ) { assertEquals("'Test._Point' is not fully initialized, field 'x' needs to be set in a constructor",e.getMessage()); }
}
@@ -89,7 +89,7 @@ _Point p = new _Point;
p.x++;
return p;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Cannot modify final field 'x'",e.getMessage()); }
}
@@ -101,7 +101,7 @@ struct _Point { var x=3; var y=4; };
p.x++;
return p;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Test._Point;", code.print());
assertEquals("Test._Point{x=4,y=4}", Eval2.eval(code, 0));
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter17bTest.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter17bTest.java
index 6137c166..e85ce31d 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter17bTest.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter17bTest.java
@@ -15,7 +15,7 @@ public class Chapter17bTest {
"""
return 1;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
assertEquals("return 1;", code.print());
assertEquals("1", Eval2.eval(code, 0));
}
@@ -27,7 +27,7 @@ return 1;
CodeGen code = new CodeGen("""
return arg++;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return arg;", code.print());
assertEquals("0", Eval2.eval(code, 0));
}
@@ -37,7 +37,7 @@ return arg++;
CodeGen code = new CodeGen("""
return arg+++arg++;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return ((arg<<1)+1);", code.print());
assertEquals("1", Eval2.eval(code, 0));
}
@@ -48,7 +48,7 @@ return arg+++arg++;
// -(arg--)-(arg--)
return -arg---arg--;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return (-((arg<<1)+-1));", code.print());
assertEquals("1", Eval2.eval(code, 0));
}
@@ -61,7 +61,7 @@ xs[0]++;
xs[1]++;
return xs[0];
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 1;", code.print());
assertEquals("1", Eval2.eval(code, 2));
}
@@ -73,7 +73,7 @@ u8[] !xs = new u8[1];
xs[0]--;
return xs[0];
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 255;", code.print());
assertEquals("255", Eval2.eval(code, 2));
}
@@ -86,7 +86,7 @@ struct _S { u16 x; };
s.x--;
return s.x;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 65535;", code.print());
assertEquals("65535", Eval2.eval(code, 2));
}
@@ -94,7 +94,7 @@ return s.x;
@Test
public void testInc6() {
CodeGen code = new CodeGen("return --arg;");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return (arg+-1);", code.print());
assertEquals("-1", Eval2.eval(code, 0));
}
@@ -102,7 +102,7 @@ return s.x;
@Test
public void testInc7() {
CodeGen code = new CodeGen("u8 x=0; return --x;");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 255;", code.print());
assertEquals("255", Eval2.eval(code, 0));
}
@@ -110,7 +110,7 @@ return s.x;
@Test
public void testInc8() {
CodeGen code = new CodeGen("int x; x+=2; return x+=3;");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 5;", code.print());
assertEquals("5", Eval2.eval(code, 0));
}
@@ -118,14 +118,14 @@ return s.x;
@Test
public void testInc9() {
CodeGen code = new CodeGen("flt x = 1.5; x++; return x;");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 2.5f;", code.print());
assertEquals("2.5", Eval2.eval(code, 0));
}
@Test public void testInt10() {
CodeGen code = new CodeGen("flt x = 1.5; x++; int i = x; return i;");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
assertEquals("2",Eval2.eval(code,0));
}
@@ -133,73 +133,73 @@ return s.x;
// ---------------------------------------------------------------
@Test public void testVar0() {
CodeGen code = new CodeGen("var d; return d;");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR(); fail(); }
+ try { code.driver(CodeGen.Phase.FinalizeIR); fail(); }
catch( Exception e ) { assertEquals("Syntax error, expected `=expression` but found `;`",e.getMessage()); }
}
@Test public void testVar1() {
CodeGen code = new CodeGen("val d; return d;");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR(); fail(); }
+ try { code.driver(CodeGen.Phase.FinalizeIR); fail(); }
catch( Exception e ) { assertEquals("Syntax error, expected `=expression` but found `;`",e.getMessage()); }
}
@Test public void testVar2() {
CodeGen code = new CodeGen("int x; x=3; x++; return x; // Ok, no initializer so x is mutable ");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 4;", code.print());
assertEquals("4", Eval2.eval(code, 0));
}
@Test public void testVar3() {
CodeGen code = new CodeGen("int x=3; x++; return x; // Ok, primitive so x is mutable despite initializer ");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 4;", code.print());
assertEquals("4", Eval2.eval(code, 0));
}
@Test public void testVar4() {
CodeGen code = new CodeGen("struct _S{int x;}; !_S? !s; s=new _S; s.x++; return s.x; // Ok, no initializer so x is mutable ");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 1;", code.print());
assertEquals("1", Eval2.eval(code, 0));
}
@Test public void testVar5() {
CodeGen code = new CodeGen("struct _S{int x; new _S={ int xx -> x=xx; };}; !_S? !s; s=new _S(3); s.x++; return s.x; // Ok, no initializer so x is mutable ");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 4;", code.print());
assertEquals("4", Eval2.eval(code, 0));
}
@Test public void testVar6() {
CodeGen code = new CodeGen("struct S{int x;}; ~S s = new S; s.x++; return s.x; // Error initializer so x is immutable ");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Cannot modify final field 'x'",e.getMessage()); }
}
@Test public void testVar7() {
CodeGen code = new CodeGen("struct S{int x; new S={ int xx -> x=xx; };}; ~S s = new S(3); s.x++; return s.x; // Error initializer so x is immutable ");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Cannot modify final field 'x'",e.getMessage()); }
}
@Test public void testVar8() {
CodeGen code = new CodeGen("struct _S{int x;}; !_S !s=new _S; s.x++; return s.x; // Ok, has '!' so s.x is mutable ");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 1;", code.print());
assertEquals("1", Eval2.eval(code, 0));
}
@Test public void testVar9() {
CodeGen code = new CodeGen("struct _S{int x;}; var s=new _S; s.x++; return s.x; // Ok, has var so s.x is mutable ");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 1;", code.print());
assertEquals("1", Eval2.eval(code, 0));
}
@Test public void testVar10() {
CodeGen code = new CodeGen("struct S{int x;}; ~S s=new S; s.x++; return s.x; // Error, has val so x is immutable ");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Cannot modify final field 'x'",e.getMessage()); }
}
@@ -218,7 +218,7 @@ foo.bar.x++; // Ok foo and foo.bar and foo.bar.x are all mutable
xfoo.bar.x++; // Error, cannot mutate through xfoo
return xfoo.bar.x;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Cannot modify final field 'x'",e.getMessage()); }
}
@@ -239,7 +239,7 @@ foo.bar.x++; // Bumps to 5
int x5 = xfoo.bar.x; // Ok to read through xfoo, gets 5
return x4*10+x5;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 45;", code.print());
assertEquals("45", Eval2.eval(code, 0));
}
@@ -249,7 +249,7 @@ return x4*10+x5;
CodeGen code = new CodeGen("""
int i,i++;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Redefining name 'i'",e.getMessage()); }
}
@@ -264,7 +264,7 @@ struct A { !B !b; new A = { ->
}; };
A x = new A;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Field 'b' might not be initialized",e.getMessage()); }
}
@@ -296,7 +296,7 @@ A x = new A;
"!B !b; new A = { -> if (arg) { b = new B; return 0; } b = new B; };",
} ) {
CodeGen code = new CodeGen("struct B {}; struct A { "+fields+" }; return new A.b != null;");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
assertEquals("1",Eval2.eval(code,0));
assertEquals("1",Eval2.eval(code,1));
}
@@ -314,7 +314,7 @@ val x = 1;
return x;
"""
);
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Undefined name 'x'",e.getMessage()); }
}
@@ -343,7 +343,7 @@ return me;
CodeGen code = new CodeGen("""
return arg ? 1 : 2;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,1,2);", code.print());
assertEquals("2", Eval2.eval(code, 0));
assertEquals("1", Eval2.eval(code, 1));
@@ -354,7 +354,7 @@ return arg ? 1 : 2;
CodeGen code = new CodeGen("""
return arg ? 0 : arg;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 0;", code.print());
assertEquals("0", Eval2.eval(code, 0));
}
@@ -368,7 +368,7 @@ val get = { !S s -> s.x; };
if( !s || !arg ) return 0;
return get(s);
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
}
@Test
@@ -378,7 +378,7 @@ struct _Bar { int x; };
var b = arg ? new _Bar : null;
return b ? b.x++ + b.x++ : -1;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,((.x<<1)+1),-1);", code.print());
assertEquals("-1", Eval2.eval(code, 0));
@@ -392,7 +392,7 @@ struct _Bar { int x; };
var b = arg ? new _Bar;
return b ? b.x++ + b.x++ : -1;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,((.x<<1)+1),-1);", code.print());
assertEquals("-1", Eval2.eval(code, 0));
assertEquals("1", Eval2.eval(code, 1));
@@ -406,7 +406,7 @@ struct _Bar { !_Bar? !next; int x; new _Bar = { !_Bar? !n, int xx -> next=n; x=x
var b = arg ? new _Bar((arg==2) ? new _Bar(null,2), 1);
return b ? b.next ? b.next.x : b.x; // parses "b ? (b.next ? b.next.x : b.x) : 0"
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,.x,0,.x);", code.print());
assertEquals("0", Eval2.eval(code, 0));
assertEquals("1", Eval2.eval(code, 1));
@@ -419,7 +419,7 @@ return b ? b.next ? b.next.x : b.x; // parses "b ? (b.next ? b.next.x : b.x) : 0
flt f=arg?1:1.2;
return f; // missing widening
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Region,1.0f,1.2);", code.print());
assertEquals("1.2", Eval2.eval(code, 0));
}
@@ -431,7 +431,7 @@ return f; // missing widening
struct S{};
return arg ? 7 : new S;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Cannot return generic scalar",e.getMessage()); }
}
@@ -444,7 +444,7 @@ for( int i=0; i<arg; i++ )
sum += i;
return sum;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,0,(Phi_sum+Phi(Loop,0,(Phi_i+1))));", code.print());
assertEquals("3", Eval2.eval(code, 3));
assertEquals("45", Eval2.eval(code, 10));
@@ -457,7 +457,7 @@ for( ; i<arg; i++ )
sum += i;
return sum;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,0,(Phi_sum+Phi(Loop,0,(Phi_i+1))));", code.print());
assertEquals("3", Eval2.eval(code, 3));
assertEquals("45", Eval2.eval(code, 10));
@@ -472,7 +472,7 @@ for( int i=0; ; i++ ) {
}
return sum;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,0,(Phi_sum+Phi(Loop,0,(Phi_i+1))));", code.print());
assertEquals("3", Eval2.eval(code, 3));
assertEquals("45", Eval2.eval(code, 10));
@@ -485,7 +485,7 @@ for( int i=0; i<arg; )
sum += i++;
return sum;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,0,(Phi_sum+Phi(Loop,0,(Phi_i+1))));", code.print());
assertEquals("3", Eval2.eval(code, 3));
assertEquals("45", Eval2.eval(code, 10));
@@ -498,7 +498,7 @@ for( int i=0; i<arg; i++ )
sum += i;
return i;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR(); fail(); }
+ try { code.driver(CodeGen.Phase.FinalizeIR); fail(); }
catch( Exception e ) { assertEquals("Undefined name 'i'",e.getMessage()); }
}
@Test
@@ -506,7 +506,7 @@ return i;
CodeGen code = new CodeGen("""
for(;;arg++;) {}
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR(); fail(); }
+ try { code.driver(CodeGen.Phase.FinalizeIR); fail(); }
catch( Exception e ) { assertEquals("Syntax error, expected `Unexpected code after expression` but found `;`",e.getMessage()); }
}
@@ -522,7 +522,7 @@ struct _A {
};
return new _A;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Test._A;", code.print());
assertEquals("Test._A{f1=null,f2=null}", Eval2.eval(code,0));
}
@@ -537,7 +537,7 @@ struct _A {
};
return new _A(new !B?[0]).array_of_b;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return []*B?;", code.print());
assertEquals("*B {}?[]", Eval2.eval(code,0));
}
@@ -556,7 +556,7 @@ for( ; ptr; ptr = ptr.next )
sum += ptr.i;
return sum;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return Phi(Loop,0,(Phi_sum+.i));", code.print());
assertEquals("45", Eval2.eval(code, 10));
}
@@ -587,7 +587,7 @@ for( int j=0; j<nprimes; j++ )
rez[j] = primes[j];
return rez;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck().GCM();
+ code.driver(CodeGen.Phase.FinalizeIR).driver(CodeGen.Phase.Schedule);
assertEquals("return []i64;", code.print());
assertEquals("i64[ 2,3,5,7,11,13,17,19]",Eval2.eval(code, 20));
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter18Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter18Test.java
index d88d8e9d..ae1dca5f 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter18Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter18Test.java
@@ -91,7 +91,7 @@ public class Chapter18Test {
"No common type amongst int and reference"}
} ) {
try {
- new CodeGen(test[0]).parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ new CodeGen(test[0]).driver(CodeGen.Phase.TypeCheck);
fail("Expected incompatible return types: " + test[0]);
} catch( Parser.ParseException e ) {
assertEquals("Cannot return generic scalar",e.getMessage());
@@ -140,7 +140,7 @@ while(arg--) {
}
return a;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
assertEquals("return Phi(Loop,1,Phi(Loop,2,Phi_a));", code.print());
assertEquals("1", Eval2.eval(code, 0));
assertEquals("2", Eval2.eval(code, 1));
@@ -157,7 +157,7 @@ return a;
{int -> int}? x2 = null; // null function ptr
return x2;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return null;", code.print());
assertEquals("null", Eval2.eval(code, 0 ) );
}
@@ -170,7 +170,7 @@ return x2;
x*x;
};
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("Stop[ return { sq}; return (Parm_x(sq,i64)*x); ]", code.print());
assertEquals("{ ptr i64 -> i64 #[ 3]}", Eval2.eval(code, 3));
}
@@ -197,7 +197,7 @@ return _sq(arg)+_sq(3);
int cnt=1; // Global scope; exactly one of these
return { -> cnt++; }; // Escape global-scope variable is OK
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("Stop[ return { ptr -> i64 #[ 3]}; return .cnt; ]", code.print());
assertEquals("{ ptr -> i64 #[ 3]}", Eval2.eval(code, 0));
}
@@ -216,7 +216,7 @@ val B = ctr(); // Make a counter
A(); // Increment counter A
return A()*10 + B(); // Incr A and B; result: 2*10+1 == 21
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR(); fail(); }
+ try { code.driver(CodeGen.Phase.FinalizeIR); fail(); }
catch( Exception e ) { assertEquals("Variable 'cnt' is out of function scope and must be a final constant",e.getMessage()); }
}
@@ -228,7 +228,7 @@ return A()*10 + B(); // Incr A and B; result: 2*10+1 == 21
val cnt=2;
return { -> cnt; }();
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return 2;", code.print());
assertEquals("2", Eval2.eval(code, 0));
}
@@ -241,7 +241,7 @@ return { -> cnt; }();
var fcn = arg ? { int x -> x*x; } : { int x -> x+x; };
return fcn(3);
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("Stop[ return #2; return (Parm_x($fun3,i64,3)*x); return (Parm_x($fun4,i64,3)<<1); ]", code.print());
assertEquals("6", Eval2.eval(code, 0));
assertEquals("9", Eval2.eval(code, 1));
@@ -251,7 +251,7 @@ return fcn(3);
@Test
public void testFcn5() {
CodeGen code = new CodeGen("val _fact = { int x -> x <= 1 ? 1 : x*_fact(x-1); }; return _fact(arg);");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
String ir = code.print();
assertTrue(ir.equals("Stop[ return #2; return Phi(Region,1,(Parm_x(_fact,arg,(x-1))*#2)); ]") ||
ir.equals("Stop[ return Phi(Region,1,(arg*#2)); return Phi(Region,1,(Parm_x(_fact,(arg-1),(x-1))*#2)); ]") ||
@@ -269,7 +269,7 @@ return fcn(3);
@Test
public void testFcn5Float() {
CodeGen code = new CodeGen("val _fact = { int x -> x <= 1 ? 1.0 : x*_fact(x-1); }; return _fact(arg);");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
assertEquals("1.0", Eval2.eval(code, 0));
assertEquals("1.0", Eval2.eval(code, 1));
assertEquals("2.0", Eval2.eval(code, 2));
@@ -280,7 +280,7 @@ return fcn(3);
@Test
public void testFcn5Minus() {
CodeGen code = new CodeGen("val _neg = { int x -> x ? -_neg(x-1) : 1; }; return _neg(arg);");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
assertEquals( "1", Eval2.eval(code, 0));
assertEquals("-1", Eval2.eval(code, 1));
assertEquals( "1", Eval2.eval(code, 2));
@@ -295,7 +295,7 @@ struct _S { int i; new _S = { int x -> i=x; }; };
val _newS = { int x -> return new _S(x); };
return _newS(1).i;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
assertEquals("return 1;", code.print());
assertEquals("1", Eval2.eval(code, 0));
}
@@ -310,7 +310,7 @@ val _g = {->2;};
if( arg ? _f : _g ) return 1;
return 2;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
assertEquals("return 1;", code.print());
assertEquals("1", Eval2.eval(code, 0));
}
@@ -388,7 +388,7 @@ for(;;) {
}
return 1;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR(); fail(); }
+ try { code.driver(CodeGen.Phase.FinalizeIR); fail(); }
catch( Exception e ) { assertEquals("No active loop for a break or continue",e.getMessage()); }
}
@@ -404,7 +404,7 @@ for(;;) {
}
return 0;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Might be null calling { ptr i64 -> i64 #[ 3]}?",e.getMessage()); }
}
@@ -416,7 +416,7 @@ return 0;
val f = { int i, int j -> return i+j; };
return f();
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Expecting 3 arguments, but found 1",e.getMessage()); }
}
@@ -432,7 +432,7 @@ val x = { -> return 1; };
S? s = new S;
return s.x;
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("Accessing unknown field 'x' from '*Test.S'",e.getMessage()); }
}
@@ -445,7 +445,7 @@ val g = { ->
};
return g();
""");
- try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { code.driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) { assertEquals("No defined return type",e.getMessage()); }
}
@@ -459,7 +459,7 @@ val is_even = { int x -> x ? is_odd (x-1) : true ; };
val is_odd = { int x -> x ? is_even(x-1) : false; };
return is_even(arg);
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
assertEquals("Stop[ return #2; return Phi(Region,0,1,#2); ]", code.print());
assertEquals("1", Eval2.eval(code, 0));
assertEquals("0", Eval2.eval(code, 1));
@@ -481,7 +481,7 @@ for(;;) {
if (s) return s.f;
}
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck().GCM();
+ code.driver(CodeGen.Phase.FinalizeIR).driver(CodeGen.Phase.Schedule);
assertEquals("return 0;", code.print());
assertEquals("0", Eval2.eval(code, 0));
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter19Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter19Test.java
index 2763e53d..6f290279 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter19Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter19Test.java
@@ -37,7 +37,7 @@ public class Chapter19Test {
CodeGen code = new CodeGen("""
return 0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
assertEquals("return 0;", code.print());
assertEquals("0", Eval2.eval(code, 2));
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter20Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter20Test.java
index 9f537fe7..0458941e 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter20Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter20Test.java
@@ -69,7 +69,7 @@ return f(s);
// The entry of g can disappear before its Return is folded into f.
// Exercise both worklist orders; deleting the entry does not kill 123.
for( int seed=0; seed<64; seed++ ) {
- CodeGen code = new CodeGen(src,seed,true).parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ CodeGen code = new CodeGen(src,seed,true).driver(CodeGen.Phase.TypeCheck);
assertEquals("seed "+seed, "123", Eval2.eval(code,0));
}
}
@@ -92,7 +92,7 @@ return f(s);
@Test
public void testJig() {
CodeGen code = new CodeGen("return 0;");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
assertEquals("return 0;", code.print());
assertEquals("0", Eval2.eval(code, 2));
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter21Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter21Test.java
index 83342ab8..07ae42eb 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter21Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter21Test.java
@@ -48,7 +48,7 @@ public class Chapter21Test {
else if(i==4) b.x=40;
}
return sum;
- """).parse().iter().opto().iterPostOpto().finalizeIR();
+ """).driver(CodeGen.Phase.FinalizeIR);
// The i==2 read still sees 10: three reads of 10, then three of 30.
assertEquals("120",Eval2.eval(code,0));
assertEquals("60",Eval2.eval(code,1));
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter22Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter22Test.java
index cbb08438..00d77f65 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter22Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter22Test.java
@@ -88,7 +88,7 @@ public class Chapter22Test {
@Test public void testSubZeroTypeError() {
try {
- new CodeGen("return null-0;").parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ new CodeGen("return null-0;").driver(CodeGen.Phase.TypeCheck);
fail("Subtraction must reject null even when the other operand is zero");
} catch( Parser.ParseException e ) {
assertEquals("Cannot null - 0",e.getMessage());
@@ -283,7 +283,7 @@ aa.c = cc;
bb.c = cc;
return cc.cz;
""";
- CodeGen code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ CodeGen code = new CodeGen(src).driver(CodeGen.Phase.TypeCheck);
assertEquals("return 25;", code.print());
assertEquals("25", Eval2.eval(code, 0));
}
@@ -322,7 +322,7 @@ return 0;
@Test
public void testStrLoad() {
CodeGen code = new CodeGen("return \"abc\"[1];");
- code.parse().iter().opto().iterPostOpto().finalizeIR();
+ code.driver(CodeGen.Phase.FinalizeIR);
assertEquals("return .[];", code.print());
}
@@ -342,7 +342,7 @@ val _sum = { i32[~] is -> // final array
};
return _sum(is);
""";
- CodeGen code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ CodeGen code = new CodeGen(src).driver(CodeGen.Phase.TypeCheck);
assertEquals("return Phi(Loop,0,(Phi_sum+.[]));", code.print());
assertEquals("14", Eval2.eval(code, 0));
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter23Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter23Test.java
index b5da4d91..df02d3b4 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter23Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter23Test.java
@@ -120,10 +120,10 @@ return a && b ? 0 : 1; // Expected answer 0
@Test
public void testLogicalValueSemantics() {
- assertEquals("42", Eval2.eval(new CodeGen("return 7 && 42;").parse().iter().opto().iterPostOpto().finalizeIR(), 0));
- assertEquals("0", Eval2.eval(new CodeGen("return 0 && 42;").parse().iter().opto().iterPostOpto().finalizeIR(), 0));
- assertEquals("7", Eval2.eval(new CodeGen("return 7 || 42;").parse().iter().opto().iterPostOpto().finalizeIR(), 0));
- assertEquals("42", Eval2.eval(new CodeGen("return 0 || 42;").parse().iter().opto().iterPostOpto().finalizeIR(), 0));
+ assertEquals("42", Eval2.eval(new CodeGen("return 7 && 42;").driver(CodeGen.Phase.FinalizeIR), 0));
+ assertEquals("0", Eval2.eval(new CodeGen("return 0 && 42;").driver(CodeGen.Phase.FinalizeIR), 0));
+ assertEquals("7", Eval2.eval(new CodeGen("return 7 || 42;").driver(CodeGen.Phase.FinalizeIR), 0));
+ assertEquals("42", Eval2.eval(new CodeGen("return 0 || 42;").driver(CodeGen.Phase.FinalizeIR), 0));
}
@Test
@@ -133,7 +133,7 @@ struct S {};
S? s = arg ? new S;
return !(!s || !arg) ? 1 : 0;
""");
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ code.driver(CodeGen.Phase.TypeCheck);
assertEquals("0", Eval2.eval(code, 0));
assertEquals("1", Eval2.eval(code, 1));
}
@@ -146,7 +146,7 @@ struct S { !S? !fld; new S = { !S? f -> fld=f; }; };
val ptr = arg == 1 ? null : new S(arg==1 ? null : new S(null));
return ptr && ptr.fld ? "true" : "false";
""";
- CodeGen code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ CodeGen code = new CodeGen(src).driver(CodeGen.Phase.TypeCheck);
assertEquals("true", Eval2.eval(code, 0));
// Evaluate on RISC5 emulator
@@ -276,7 +276,7 @@ struct _Scan {
return _s.peek('q');
""";
- CodeGen code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ CodeGen code = new CodeGen(src).driver(CodeGen.Phase.TypeCheck);
assertEquals("return Phi(Region,0,1);", code.print());
assertEquals("1", Eval2.eval(code, 0));
testCPU(src,"x86_64_v2", "win64",23,null);
@@ -301,7 +301,7 @@ struct _Scan {
return s.skip().x;
""";
- try { new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); }
+ try { new CodeGen(src).driver(CodeGen.Phase.TypeCheck); fail(); }
catch( Exception e ) {
// Bad error message, but basically requires a mutable 'x' field.
org.junit.Assert.assertTrue(e.getMessage().startsWith("Argument #0 isa"));
@@ -331,7 +331,7 @@ struct _Scan {
return _s.require('[');
""";
- CodeGen code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ CodeGen code = new CodeGen(src).driver(CodeGen.Phase.TypeCheck);
assertEquals("return (.[]==91);", code.print());
assertEquals("1", Eval2.eval(code, 0));
testCPU(src,"x86_64_v2", "win64",4, null);
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter24Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter24Test.java
index 4bfb0d30..2f125ed0 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter24Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter24Test.java
@@ -257,7 +257,7 @@ while (cnt) {
}
return x;
""";
- CodeGen code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ CodeGen code = new CodeGen(src).driver(CodeGen.Phase.TypeCheck);
assertEquals("return 1;", code.print());
}
@@ -272,7 +272,7 @@ while( cnt-- )
x = 2-x;
return x;
""";
- CodeGen code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ CodeGen code = new CodeGen(src).driver(CodeGen.Phase.TypeCheck);
assertEquals("return 1;", code.print());
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter25Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter25Test.java
index 4e8effbe..275be96a 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter25Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter25Test.java
@@ -28,6 +28,36 @@ import static org.junit.Assert.*;
public class Chapter25Test {
+ @Test public void testFlagSpills() throws IOException {
+ com.seaofnodes.simple.codegen.FlagSpillTestSupport.run();
+ }
+
+ @Ignore
+ @Test
+ public void testJig() {
+ String src = "{ i32 -> i32 } close = \"C\"; val main = { u8[] a -> if (a# > 1) return close(0); return a[0]; };";
+ CodeGen code = new CodeGen(src).driver(CodeGen.Phase.Encoding,"riscv","SystemV");
+ assertEquals("return (arg+3);", code.print());
+ assertEquals("3",Eval2.eval(code,0));
+ }
+
+ @Test public void testConditionalClassInitX86() throws IOException {
+ Path build=Path.of("build/objs");
+ Files.createDirectories(build);
+ Path dir=Files.createTempDirectory(build,"init_flags_");
+ // Keep B separately compiled so its first-touch check survives.
+ new CodeGen(null,dir.toString(),null,"B","int value=17+arg;",123,true,TypeInteger.BOT)
+ .driver("x86_64_v2","win64",false,false);
+ // GCM can hoist the fused B.$init compare above the test of take.
+ // Its flags then cross another flag definition and need a legal split.
+ new CheckedCodeGen(null,dir.toString(),new Ary<>(new String[]{dir.toString()}),
+ "Main","val run={int take -> return take ? B.value : 0; };",123,true,TypeInteger.BOT)
+ .driver(CodeGen.Phase.Encoding,"x86_64_v2","win64");
+ // Remove successful fixtures; preserve the object if compilation fails.
+ Files.delete(dir.resolve("B.o"));
+ Files.delete(dir);
+ }
+
@Test public void testPublicInstanceMethod() {
String src = """
struct Scan {
@@ -63,15 +93,6 @@ public class Chapter25Test {
}
}
- @Ignore
- @Test
- public void testJig() {
- String src = "int x = arg/17; if( arg == 0 ) return arg + x; return arg + x;";
- CodeGen code = new CodeGen(src).driver(CodeGen.Phase.TypeCheck);
- assertEquals("return (arg+3);", code.print());
- assertEquals("3",Eval2.eval(code,0));
- }
-
@Test public void testNeverReturnPointerRiscV() {
new CodeGen("""
struct _S { int x; };
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/ClassInitDependenciesTest.java b/chapter25/src/test/java/com/seaofnodes/simple/ClassInitDependenciesTest.java
index cc010668..47e10f97 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/ClassInitDependenciesTest.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/ClassInitDependenciesTest.java
@@ -433,6 +433,88 @@ public class ClassInitDependenciesTest {
assertEquals(1,stores[0]);
}
+ @Test public void testInitializationExecution() throws Exception {
+ Path dir=tempDir("execution-");
+ object(dir,dir,"State","int count=0;");
+ object(dir,dir,"B","State.count++; int value=17+arg;");
+ String src="int value=arg ? B.value+B.value : 0; return value+100*State.count;";
+ for( long seed : new long[]{1,123,987654321} ) {
+ CodeGen code=new CodeGen(null,dir.toString(),new Ary<>(new String[]{dir.toString()}),
+ "Main",src,seed,true,TypeInteger.BOT).driver(CodeGen.Phase.TypeCheck);
+ assertNotNull(code._stop.walk(n -> n instanceof CLInitNode ? n : null));
+ assertEquals("0",Eval2.eval(code,0));
+ assertNull(code._stop.walk(n -> n instanceof CLInitNode ? n : null));
+ assertEquals("134",Eval2.eval(code,1));
+ }
+
+ object(dir,dir,"Main","val run={int take -> "+src.replace("arg ?","take ?")+" };");
+ Path cfile=dir.resolve("check.c");
+ Files.writeString(cfile,"""
+ #include <stdint.h>
+ __attribute__((CALL_CONV)) extern int64_t run(int64_t take);
+ int main(void) {
+ return run(0)!=0 || run(1)!=134 || run(1)!=134 || run(0)!=100;
+ }
+ """);
+ String exe=dir.resolve(TestC.OS.startsWith("Windows") ? "check.exe" : "check").toString();
+ TestC.linkExe(dir.resolve("Main.o").toString(),TestC.CALL_CONVENTION.equals("win64") ? "ms_abi" : "sysv_abi",
+ cfile.toString(),new Ary<>(new String[]{dir.resolve("B.o").toString(),dir.resolve("State.o").toString()}),exe);
+ assertEquals("",TestC.exec(exe));
+ for( String cpu : new String[]{"arm","riscv"} )
+ new CodeGen(null,dir.toString(),new Ary<>(new String[]{dir.toString()}),
+ "Main",src,123,true,TypeInteger.BOT).driver(CodeGen.Phase.Encoding,cpu,"SystemV");
+ }
+
+ @Test public void testParentInitializationExecution() throws Exception {
+ Path dir=tempDir("execution-");
+ object(dir,dir,"State","int count=0;");
+ module(dir,dir,"P",Map.of("P","val C=C; State.count=State.count*10+1;",
+ "P/C","State.count=State.count*10+2; int value=arg;"));
+ for( long seed : new long[]{1,123,987654321} ) {
+ CodeGen code=new CodeGen(null,dir.toString(),new Ary<>(new String[]{dir.toString()}),
+ "Main","return P.C.value+State.count;",seed,true,TypeInteger.BOT).driver(CodeGen.Phase.TypeCheck);
+ assertEquals("12",Eval2.eval(code,99));
+ }
+ object(dir,dir,"Main","val run={ -> P.C.value+State.count; };");
+ Path cfile=dir.resolve("check.c");
+ Files.writeString(cfile,"""
+ #include <stdint.h>
+ __attribute__((CALL_CONV)) extern int64_t run(void);
+ int main(void) { return run()!=12 || run()!=12; }
+ """);
+ String exe=dir.resolve(TestC.OS.startsWith("Windows") ? "check.exe" : "check").toString();
+ TestC.linkExe(dir.resolve("Main.o").toString(),TestC.CALL_CONVENTION.equals("win64") ? "ms_abi" : "sysv_abi",
+ cfile.toString(),new Ary<>(new String[]{dir.resolve("P.o").toString(),dir.resolve("State.o").toString()}),exe);
+ assertEquals("",TestC.exec(exe));
+ }
+
+ @Test public void testNonreturningObject() throws Exception {
+ Path dir=tempDir("nonreturning-");
+ object(dir,dir,"Spin","val spin_noInline={ -> while(1) {} return 7; };");
+ CodeGen code=new CodeGen(null,dir.toString(),new Ary<>(new String[]{dir.toString()}),
+ "Main","Spin.spin_noInline(); return 7;",123,true,TypeInteger.BOT).driver(CodeGen.Phase.TypeCheck);
+ assertNull(Eval2.eval(code,0,10));
+ }
+
+ @Test public void testImportedPrivateInitializer() throws Exception {
+ Path dir=tempDir("private-");
+ module(dir,dir,"Library",Map.of("Library","val read={ -> _Hidden.value; };",
+ "Library/_Hidden","int value=17+arg;"));
+ CodeGen code=new CodeGen(null,dir.toString(),new Ary<>(new String[]{dir.toString()}),
+ "Main","return Library.read();",123,true,TypeInteger.BOT).driver(CodeGen.Phase.TypeCheck);
+ assertEquals("17",Eval2.eval(code,99));
+ // Even a request stopping at Select must drop imported bodies. They
+ // remain available only to the ideal evaluator above, not this object.
+ for( String cpu : new String[]{"x86_64_v2","arm","riscv"} ) {
+ CodeGen selected=new CodeGen(null,dir.toString(),new Ary<>(new String[]{dir.toString()}),
+ "Main","return Library.read();",123,true,TypeInteger.BOT).driver(CodeGen.Phase.Select,cpu,"SystemV");
+ assertNull(selected._serial);
+ for( CompUnit cu : selected._compunits.values() )
+ if( cu._src==null ) assertNull(cu._stop);
+ selected.driver(CodeGen.Phase.Encoding,cpu,"SystemV");
+ }
+ }
+
@Test public void testOverlappingFunctionAndClassCycles() throws Exception {
// Fixed function graph: Opto/inlining must not erase the overlap that
// exercises SCC traversal. One clinit is legal, two in the SCC are not.
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/CompoundAssignmentTest.java b/chapter25/src/test/java/com/seaofnodes/simple/CompoundAssignmentTest.java
index db41363a..e2d822d0 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/CompoundAssignmentTest.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/CompoundAssignmentTest.java
@@ -88,7 +88,7 @@ public class CompoundAssignmentTest {
}
private static void check(String src, long arg, long expected) {
- var code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ var code = new CodeGen(src).driver(CodeGen.Phase.TypeCheck);
assertEquals(src, Long.toString(expected), Eval2.eval(code, arg));
}
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Eval2.java b/chapter25/src/test/java/com/seaofnodes/simple/Eval2.java
index 21e677ce..366bd7f4 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Eval2.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Eval2.java
@@ -114,6 +114,9 @@ public abstract class Eval2 {
// Current active Frame, to avoid having to pass it everywhere
public static Frame F;
+ // Class pointers and initializer self parameters share one object per run.
+ private static final HashMap<String,Object[]> CLASSES = new HashMap<>();
+
public static String eval( CodeGen code, long arg ) { return eval(code,arg,1000); }
public static String eval( CodeGen code, long arg, int timeout ) {
if( code._start.uctrl()==null ) return ""; // The empty program
@@ -122,6 +125,7 @@ public abstract class Eval2 {
code.driver(CodeGen.Phase.LocalSched);
// Set global, so don't have to pass everywhere
CODE = code;
+ CLASSES.clear();
// Timer for when we run too long. Ticks once per backedge or function call
int loopCnt = 0;
@@ -140,7 +144,7 @@ public abstract class Eval2 {
TypeStruct clz = ((TypeMemPtr)fun.sig().arg(0))._obj;
// Map from the <clinit> self parameter to the
// singleton class structure.
- F.put(fun.parm(2),alloc(clz));
+ F.put(fun.parm(2),classObject(clz));
}
@@ -203,9 +207,9 @@ public abstract class Eval2 {
// Parms read from Call args -
// - except RPC is the actual prior frame
- // - except <clinit> takes the singleton class object and external args
+ // - except entry <clinit> takes the external program argument
Object val;
- if( isClz && phi instanceof ParmNode parm && parm._idx==3 )
+ if( isClz && prior instanceof StartNode && phi instanceof ParmNode parm && parm._idx==3 )
PHICACHE[i] = arg; // Reading the initial arguments to <clinit>
else {
Node n = phi instanceof ParmNode parm
@@ -349,6 +353,8 @@ public abstract class Eval2 {
yield new Object[0];
}
+ } else if( Parser.startsClzPrefix(tmp._obj._name) ) {
+ yield classObject(tmp._obj);
} else {
// Constant object with all zeros
yield alloc(tmp._obj);
@@ -417,6 +423,12 @@ public abstract class Eval2 {
return ptr;
}
+ private static Object[] classObject(TypeStruct type) {
+ Object[] ptr = CLASSES.get(type._name);
+ if( ptr==null ) CLASSES.put(type._name,ptr=alloc(type));
+ return ptr;
+ }
+
private static Object not( NotNode not ) {
Object n = val(not.in(1));
return ( n==null || (n instanceof Double D && D==0.0) || n instanceof Long L && L==0 )
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Main.java b/chapter25/src/test/java/com/seaofnodes/simple/Main.java
index 97129f5b..1248a6cf 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Main.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Main.java
@@ -11,7 +11,7 @@ public class Main {
String src = Files.readString(Path.of(args[0]));
int arg = Integer.valueOf(args[1]);
CodeGen code = new CodeGen(src);
- code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck().GCM().localSched();
+ code.driver(CodeGen.Phase.FinalizeIR).driver(CodeGen.Phase.Schedule).localSched();
System.out.println(code._stop);
System.out.println(Eval2.eval(code,arg,100000));
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/MemoryEncodingTest.java b/chapter25/src/test/java/com/seaofnodes/simple/MemoryEncodingTest.java
index 4934c91f..adeba136 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/MemoryEncodingTest.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/MemoryEncodingTest.java
@@ -58,7 +58,7 @@ public class MemoryEncodingTest {
// Exercise both unresolved Store aliases and nested value-Phi cleanup.
for( long seed : new long[]{0,9,126} )
for( int p=0; p<sources.length; p++ ) {
- CodeGen code=new CodeGen(sources[p],seed,true).parse().iter().opto().iterPostOpto().finalizeIR();
+ CodeGen code=new CodeGen(sources[p],seed,true).driver(CodeGen.Phase.FinalizeIR);
if( p==0 ) assertNull(code._stop.walk(n ->
n instanceof LoadNode ld && ld.ptr() instanceof ProjNode ptr &&
ptr.in(0) instanceof NewNode nn &&
@@ -86,7 +86,7 @@ public class MemoryEncodingTest {
if (arg>1) { v=p.x; p.x=41; p.y=5; }
else { v=q.x; q.x=42; }
return v;
- """).parse().iter().opto().iterPostOpto().finalizeIR();
+ """).driver(CodeGen.Phase.FinalizeIR);
StopNode stop = code._stop;
assertEquals(2,countMemoryNodes(stop,LoadNode.class,new BitSet()));
assertEquals("-1",Eval2.eval(code,-1));
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/MutabilityTest.java b/chapter25/src/test/java/com/seaofnodes/simple/MutabilityTest.java
index 9727857e..8bd77c06 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/MutabilityTest.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/MutabilityTest.java
@@ -6,12 +6,12 @@ import com.seaofnodes.simple.codegen.CodeGen;
public class MutabilityTest {
private static void ok(String src, String result) {
- var code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ var code = new CodeGen(src).driver(CodeGen.Phase.TypeCheck);
assertEquals(result,Eval2.eval(code,0));
}
private static void bad(String src) {
try {
- new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().typeCheck();
+ new CodeGen(src).driver(CodeGen.Phase.TypeCheck);
} catch( RuntimeException expected ) {
String msg = expected.getMessage();
assertTrue("Expected a permission error, got: "+expected,
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/PhaseTest.java b/chapter25/src/test/java/com/seaofnodes/simple/PhaseTest.java
new file mode 100644
index 00000000..7252378a
--- /dev/null
+++ b/chapter25/src/test/java/com/seaofnodes/simple/PhaseTest.java
@@ -0,0 +1,64 @@
+package com.seaofnodes.simple;
+
+import com.seaofnodes.graph.GraphObserver;
+import com.seaofnodes.simple.codegen.CodeGen;
+import com.seaofnodes.simple.codegen.CodeGen.Phase;
+import com.seaofnodes.simple.node.Node;
+import java.util.ArrayList;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class PhaseTest {
+ private static final String SRC = "int sum=0; for(int i=0; i<arg; i++) sum+=i; return sum;";
+
+ @Test public void testIdealPhasesAndResume() {
+ ArrayList<String> phases = new ArrayList<>();
+ CodeGen code = new CodeGen(SRC);
+ code._obs = new GraphObserver<Node>() {
+ @Override public void before(Node n) {}
+ @Override public void after(Node n, Node repl, boolean applied) {}
+ @Override public void phase(String phase) { phases.add(phase); }
+ };
+ code.driver(Phase.TypeCheck);
+ code.driver(Phase.TypeCheck); // A repeated request does not rerun anything.
+ code.driver(Phase.LocalSched);
+ assertEquals("Parse Iter Opto IterPostOpto FinalizeIR TypeCheck Lower LoopTree Unlink Schedule LocalSched",
+ String.join(" ",phases));
+ assertNull(code._serial);
+ assertNull(code._mach);
+ assertEquals("45",Eval2.eval(code,10));
+ }
+
+ @Test public void testEncodingWithoutSerialization() {
+ for( String cpu : new String[]{"x86_64_v2","arm","riscv"} ) {
+ CodeGen code = new CodeGen(SRC).driver(Phase.TypeCheck);
+ code.driver(Phase.Unlink,cpu,"SystemV");
+ code.driver(Phase.Select,cpu,"SystemV");
+ code.driver(Phase.Encoding,cpu,"SystemV");
+ assertNull(code._serial);
+ byte[] staged = code._encoding._bits.toByteArray();
+ CodeGen direct = new CodeGen(SRC).driver(Phase.Encoding,cpu,"SystemV");
+ assertArrayEquals(staged,direct._encoding._bits.toByteArray());
+ }
+ }
+
+ @Test public void testExplicitSerializationAndMemoryExport() {
+ CodeGen code = new CodeGen(SRC).driver(Phase.Serialize);
+ assertNotNull(code._serial);
+ assertEquals(Phase.Serialize,code._phase);
+ code.driver(Phase.Encoding,"riscv","SystemV");
+ assertNotNull(code._serial);
+
+ CodeGen memory = new CodeGen(SRC).driver("riscv","SystemV",true,false);
+ assertNull(memory._serial);
+ assertEquals(Phase.Export,memory._phase);
+
+ CodeGen late = new CodeGen(SRC).driver(Phase.Encoding,"riscv","SystemV");
+ try {
+ late.exportELF(false,false);
+ fail("Cannot recover ideal IR after lowering and instruction selection");
+ } catch( IllegalStateException expected ) {
+ assertTrue(expected.getMessage().contains("Serialize before Lower"));
+ }
+ }
+}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Simple.java b/chapter25/src/test/java/com/seaofnodes/simple/Simple.java
index 9078a33a..2d688bbe 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Simple.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Simple.java
@@ -49,6 +49,7 @@ Options:
--dump-after-iter-post-opto - dump after SCCP-driven peepholes and inlining
--dump-after-finalize-ir - dump after field layout and IR finalization
--dump-after-type-check - dump intermediate representation after type check pass
+ --dump-after-lower - dump expanded class initialization before loop trees
--dump-after-select - dump intermediate representation after instruction selection pass
--dump-after-gcm - dump intermediate representation after GCM pass
--dump-after-local-sched - dump intermediate representation after local scheduling pass
@@ -119,6 +120,7 @@ Options:
case "--dump-after-iter-post-opto": dump |= 1<<Phase.IterPostOpto.ordinal(); break;
case "--dump-after-finalize-ir": dump |= 1<<Phase.FinalizeIR.ordinal() ; break;
case "--dump-after-type-check": dump |= 1<<Phase.TypeCheck .ordinal() ; break;
+ case "--dump-after-lower": dump |= 1<<Phase.Lower .ordinal() ; break;
case "--dump-after-loop-tree": dump |= 1<<Phase.LoopTree .ordinal() ; break;
case "--dump-after-select": dump |= 1<<Phase.Select .ordinal() ; break;
case "--dump-after-gcm": dump |= 1<<Phase.Schedule .ordinal() ; break;
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/StaticDataTest.java b/chapter25/src/test/java/com/seaofnodes/simple/StaticDataTest.java
index 070b7a9e..03df05a7 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/StaticDataTest.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/StaticDataTest.java
@@ -2,6 +2,9 @@ package com.seaofnodes.simple;
import com.seaofnodes.simple.codegen.CodeGen;
import com.seaofnodes.simple.codegen.StaticData;
+import com.seaofnodes.simple.node.ConstantNode;
+import com.seaofnodes.simple.node.StoreNode;
+import com.seaofnodes.simple.type.TypeMem;
import com.seaofnodes.simple.type.TypeStruct;
import com.seaofnodes.simple.type.TypeInteger;
import com.seaofnodes.simple.util.Ary;
@@ -16,14 +19,25 @@ public class StaticDataTest {
private static final String SRC="val n=42; val f={int x -> x+n;}; return 0;";
private static StaticData.ObjectData root(CodeGen code) {
- return code._encoding._data.entries().stream()
- .filter(obj -> obj.symbol.endsWith("Test.$class")).findFirst().orElseThrow();
+ for( var obj : code._encoding._data.entries() )
+ if( obj.symbol.endsWith("Test.$class") ) return obj;
+ throw new AssertionError("Missing Test class object");
}
// Read the image before <clinit>, then call the function through its data slot.
@Test public void testEmulatorImage() {
for( String cpu : new String[]{"arm","riscv"} ) {
- CodeGen code=new CodeGen(SRC).driver(cpu,"SystemV",true,false);
+ CodeGen code=new CodeGen(SRC).driver(CodeGen.Phase.TypeCheck);
+ assertNull("Constant fields fold before instruction selection",
+ code._stop.walk(n -> n instanceof StoreNode st &&
+ (st._name.equals("n") || st._name.equals("f")) ? n : null));
+ assertNotNull(code._stop.walk(n -> n instanceof ConstantNode &&
+ n._type instanceof TypeMem mem && mem.isConstant() &&
+ mem._t==TypeInteger.constant(42) ? n : null));
+ assertNotNull("The runtime initialization flag still needs its Store",
+ code._stop.walk(n -> n instanceof StoreNode st &&
+ st._name.equals("$init") ? n : null));
+ code.driver(cpu,"SystemV",true,false);
var e=code._encoding;
var obj=root(code);
TypeStruct ts=(TypeStruct)obj.type;
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/codegen/FlagSpillTestSupport.java b/chapter25/src/test/java/com/seaofnodes/simple/codegen/FlagSpillTestSupport.java
new file mode 100644
index 00000000..445acb61
--- /dev/null
+++ b/chapter25/src/test/java/com/seaofnodes/simple/codegen/FlagSpillTestSupport.java
@@ -0,0 +1,141 @@
+package com.seaofnodes.simple.codegen;
+
+import com.seaofnodes.isa.X86;
+import com.seaofnodes.isa.eval.EvalArm64;
+import com.seaofnodes.simple.TestC;
+import com.seaofnodes.simple.node.*;
+import com.seaofnodes.simple.node.cpus.arm.arm;
+import com.seaofnodes.simple.node.cpus.x86_64_v2.x86_64_v2;
+import com.seaofnodes.simple.type.TypeInteger;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import static org.junit.Assert.*;
+
+// Force overlapping flags, then force every GPR unavailable across the gap.
+public class FlagSpillTestSupport {
+ private static class Op extends MachConcreteNode {
+ final RegMask _def, _use, _kill;
+ Op(RegMask def,RegMask use,RegMask kill,Node... ins) {
+ super(ins); _def=def; _use=use; _kill=kill; _type=TypeInteger.BOT;
+ }
+ @Override public String op() { return "flagsProbe"; }
+ @Override public RegMask outregmap() { return _def; }
+ @Override public RegMask regmap(int i) { return _use; }
+ @Override public RegMask killmap() { return _kill; }
+ @Override public void encoding(Encoding enc) { throw new AssertionError(); }
+ }
+
+ public static void run() throws IOException {
+ StringBuilder asm = new StringBuilder(".text\n");
+ for( boolean isArm : new boolean[]{false,true} )
+ for( boolean stack : new boolean[]{false,true} ) {
+ CodeGen code = new CodeGen("");
+ code._callingConv="SystemV";
+ code._mach=isArm ? new arm(code) : new x86_64_v2(code);
+ RegionNode block = new RegionNode(null,code._start,code._start);
+ code._cfg.add(block);
+ int flagsReg=isArm ? 64 : 32, firstStack=flagsReg+1;
+ RegMask flags = new RegMask(flagsReg);
+ Op def = new Op(flags,null,null,block);
+ RegMask killMask = stack ? (isArm ? new RegMask(0x7fffffffL,1L) : new RegMask(0x1ffffffefL)) : flags;
+ Op kill = new Op(null,null,killMask,block);
+ new Op(null,flags,null,block,def);
+ RegAlloc alloc = new RegAlloc(code);
+ alloc.regAlloc();
+
+ int splits=0, slots=0;
+ for( Node n : block._outputs ) if( n instanceof SplitNode split ) {
+ int dst=alloc.regnum(n), src=alloc.regnum(n.in(1));
+ assertTrue(split.outregmap().test(dst));
+ assertTrue(split.regmap(1).test(src));
+ for( int fp=isArm ? 32 : 16; fp<flagsReg; fp++ ) {
+ assertFalse("FP output allowed",split.outregmap().test(fp));
+ assertFalse("FP input allowed",split.regmap(1).test(fp));
+ }
+ if( dst>=firstStack || src>=firstStack ) slots++;
+ splits++;
+ }
+ assertTrue(splits>=2);
+ assertEquals(stack,slots!=0);
+
+ // Keep the allocated registers, supplying a frame for encoding stack offsets.
+ FunNode frame = new FunNode(null,null,"flags",null,(Node)null);
+ code._regAlloc=new RegAlloc(code);
+ for( Node n : block._outputs )
+ if( alloc.regnum(n)>=0 ) code._regAlloc.newLRG(n,frame)._reg=alloc.regnum(n);
+ Encoding save = new Encoding(code), restore = new Encoding(code);
+ Encoding enc = save;
+ for( Node n : block._outputs ) {
+ if( n==kill ) enc=restore;
+ if( n instanceof SplitNode split ) split.encoding(enc);
+ }
+ if( isArm ) {
+ for( int bits=0; bits<16; bits++ ) {
+ EvalArm64 cpu = new EvalArm64(new byte[1024],512);
+ System.arraycopy(save._bits.buf(),0,cpu._buf,0,save._bits.size());
+ System.arraycopy(restore._bits.buf(),0,cpu._buf,save._bits.size(),restore._bits.size());
+ cpu.N=(bits&8)!=0; cpu.Z=(bits&4)!=0; cpu.C=(bits&2)!=0; cpu.V=(bits&1)!=0;
+ assertEquals(0,cpu.step(save._bits.size()/4));
+ cpu.N=cpu.Z=cpu.C=cpu.V=false;
+ if( stack ) for( int r=0; r<31; r++ ) cpu.regs[r]=0;
+ assertEquals(0,cpu.step(restore._bits.size()/4));
+ assertEquals((bits&8)!=0,cpu.N); assertEquals((bits&4)!=0,cpu.Z);
+ assertEquals((bits&2)!=0,cpu.C); assertEquals((bits&1)!=0,cpu.V);
+ assertEquals(512,cpu.regs[31]);
+ }
+ } else {
+ Encoding body = new Encoding(code);
+ int[] preserved={3,5,6,7,12,13,14,15};
+ for( int r : preserved ) pushPop(body,r,false);
+ X86.imm(body,0x81,5,4,16); // Reserve spill storage.
+ X86.flags(body,TestC.OS.startsWith("Windows") ? 1 : 7,true);
+ bytes(body,save);
+ if( stack ) {
+ for( int r=0; r<16; r++ ) if( r!=4 ) X86.constant(body,r,0);
+ } else X86.reg(body,0x39,0,0); // CMP rax,rax clobbers only flags.
+ bytes(body,restore);
+ X86.flags(body,0,false); // Return the restored flags.
+ X86.imm(body,0x81,0,4,16);
+ for( int i=preserved.length-1; i>=0; i-- ) pushPop(body,preserved[i],true);
+ X86.ret(body);
+ String name=stack ? "flags_stack" : "flags_reg";
+ asm.append(".globl ").append(name).append('\n').append(name).append(":\n.byte ");
+ for( int i=0; i<body._bits.size(); i++ ) {
+ if( i!=0 ) asm.append(',');
+ asm.append(body._bits.buf()[i]&255);
+ }
+ asm.append('\n');
+ }
+ }
+ Path dir=Files.createTempDirectory(Path.of("build/objs"),"flag_spills_");
+ Files.writeString(dir.resolve("flags.s"),asm);
+ Files.writeString(dir.resolve("flags.c"),"""
+ typedef unsigned long long u64;
+ u64 __attribute__((CALL_CONV)) flags_reg(u64);
+ u64 __attribute__((CALL_CONV)) flags_stack(u64);
+ int main(void) {
+ const int positions[]={0,2,4,6,7,11};
+ for(int bits=0; bits<64; bits++) {
+ u64 flags=0x202;
+ for(int i=0;i<6;i++) if(bits&(1<<i)) flags|=1ULL<<positions[i];
+ if((flags_reg(flags)&0x8d5)!=(flags&0x8d5)) return 1;
+ if((flags_stack(flags)&0x8d5)!=(flags&0x8d5)) return 2;
+ }
+ return 0;
+ }
+ """);
+ String exe=dir.resolve(TestC.OS.startsWith("Windows") ? "flags.exe" : "flags").toString();
+ TestC.exec("gcc","-DCALL_CONV="+(TestC.OS.startsWith("Windows") ? "ms_abi" : "sysv_abi"),
+ "-o",exe,dir.resolve("flags.c").toString(),dir.resolve("flags.s").toString());
+ TestC.exec(exe);
+ }
+
+ private static void bytes(Encoding dst,Encoding src) {
+ for( int i=0; i<src._bits.size(); i++ ) dst.add1(src._bits.buf()[i]&255);
+ }
+ private static void pushPop(Encoding enc,int reg,boolean pop) {
+ if( reg>=8 ) enc.add1(0x41);
+ enc.add1((pop ? 0x58 : 0x50)+(reg&7));
+ }
+}
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 93380c87..292f1ae7 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/codegen/RegAllocTestSupport.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/codegen/RegAllocTestSupport.java
@@ -29,6 +29,12 @@ public class RegAllocTestSupport {
return code;
}
+ private static SplitNode testSplit(CodeGen code, MachNode def) {
+ LRG lrg = new LRG((short)0,null);
+ lrg._machDef = def;
+ return code._mach.split(lrg,"test",(byte)0);
+ }
+
public static void uncoloredFixedNeighbor() throws Exception {
CodeGen code = graph();
RegAlloc alloc = new RegAlloc(code);
@@ -225,11 +231,11 @@ public class RegAllocTestSupport {
RegAlloc alloc = new RegAlloc(code);
Op def = new Op(A,null,null,false,code._start);
alloc.newLRG(def,null)._reg=0;
- SplitNode hi = code._mach.split(null,"test",(byte)0);
+ SplitNode hi = testSplit(code,def);
hi.setDef(0,code._start); hi.setDef(1,def);
alloc.newLRG(hi,null)._reg=1;
new Op(null,null,killed ? A : null,false,code._start);
- SplitNode lo = code._mach.split(null,"test",(byte)0);
+ SplitNode lo = testSplit(code,hi);
lo.setDef(0,code._start); lo.setDef(1,hi);
alloc.newLRG(lo,null)._reg=0;
Op use = new Op(null,A,null,false,code._start,lo);
@@ -243,7 +249,7 @@ public class RegAllocTestSupport {
uncolored.newLRG(def0,null)._mask=A;
Op fixed = new Op(A,null,null,false,pre._start);
uncolored.newLRG(fixed,null)._mask=A;
- SplitNode copy = pre._mach.split(null,"test",(byte)0);
+ SplitNode copy = testSplit(pre,def0);
copy.setDef(0,pre._start); copy.setDef(1,def0);
assertFalse("A fixed definition clobbers even before coloring",uncolored.sameBlockNoClobber(copy));
}
@@ -284,7 +290,7 @@ public class RegAllocTestSupport {
RegAlloc alloc = new RegAlloc(code);
Op def = new Op(A,null,null,false,code._start);
alloc.newLRG(def,null)._reg=0;
- SplitNode copy = code._mach.split(null,"test",(byte)0);
+ SplitNode copy = testSplit(code,def);
copy.setDef(0,code._start); copy.setDef(1,def);
alloc.newLRG(copy,null)._reg=1;
if( kind==3 ) new Op(null,null,A,false,code._start);
@@ -307,7 +313,7 @@ public class RegAllocTestSupport {
CodeGen code = graph();
RegAlloc alloc = new RegAlloc(code);
Op def = new Op(new RegMask(3L),null,null,false,code._start);
- SplitNode copy = code._mach.split(null,"test",(byte)0);
+ SplitNode copy = testSplit(code,def);
copy.setDef(0,code._start); copy.setDef(1,def);
Op use = new Op(null,new RegMask(3L),null,false,code._start,copy);
LRG from = alloc.newLRG(def,null), to = alloc.newLRG(copy,null);