From 0be52f8dd82f70d4c557fe916d47dc425401f848 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Sat, 17 Oct 2026 17:38:12 -0700 Subject: Phase cleanup heading into CLInit expansion --- .../java/com/seaofnodes/simple/Chapter05Test.java | 16 ++-- .../java/com/seaofnodes/simple/Chapter06Test.java | 32 ++++---- .../java/com/seaofnodes/simple/Chapter07Test.java | 22 ++--- .../java/com/seaofnodes/simple/Chapter08Test.java | 22 ++--- .../java/com/seaofnodes/simple/Chapter09Test.java | 40 ++++----- .../java/com/seaofnodes/simple/Chapter10Test.java | 46 +++++------ .../java/com/seaofnodes/simple/Chapter12Test.java | 34 ++++---- .../java/com/seaofnodes/simple/Chapter13Test.java | 26 +++--- .../com/seaofnodes/simple/Chapter14FloatTest.java | 14 ++-- .../java/com/seaofnodes/simple/Chapter14Test.java | 30 +++---- .../java/com/seaofnodes/simple/Chapter15Test.java | 42 +++++----- .../java/com/seaofnodes/simple/Chapter16Test.java | 16 ++-- .../java/com/seaofnodes/simple/Chapter17aTest.java | 16 ++-- .../java/com/seaofnodes/simple/Chapter17bTest.java | 94 +++++++++++----------- .../java/com/seaofnodes/simple/Chapter18Test.java | 40 ++++----- .../java/com/seaofnodes/simple/Chapter19Test.java | 2 +- .../java/com/seaofnodes/simple/Chapter20Test.java | 6 +- .../java/com/seaofnodes/simple/Chapter21Test.java | 4 +- .../java/com/seaofnodes/simple/Chapter22Test.java | 27 ++++--- .../java/com/seaofnodes/simple/Chapter23Test.java | 18 ++--- .../java/com/seaofnodes/simple/Chapter24Test.java | 4 +- .../java/com/seaofnodes/simple/Chapter25Test.java | 36 +++++++++ .../simple/ClassInitDependenciesTest.java | 73 ++++++++++++++++- .../seaofnodes/simple/CompoundAssignmentTest.java | 2 +- .../src/test/java/com/seaofnodes/simple/Main.java | 2 +- .../com/seaofnodes/simple/MemoryEncodingTest.java | 4 +- .../java/com/seaofnodes/simple/MutabilityTest.java | 4 +- .../test/java/com/seaofnodes/simple/Simple.java | 6 +- .../java/com/seaofnodes/simple/fuzzer/Fuzzer.java | 2 +- 29 files changed, 396 insertions(+), 284 deletions(-) (limited to 'chapter25/src/test') diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter05Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter05Test.java index 79af6ae7..5b57e701 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().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return Phi(Region,(arg+2),(arg-3));", code.print()); } @@ -36,7 +36,7 @@ if (arg == 1) { } return c; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return (arg==Phi(Region,3,2));", code.print()); } @@ -148,7 +148,7 @@ else a=3; return a; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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 fdf6963f..c503b56c 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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 1;", code.print()); } @@ -44,7 +44,7 @@ else a=3; return a; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 2;", code.print()); assertTrue(code.ctrl() instanceof FunNode); } @@ -65,7 +65,7 @@ else b=5; return b; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return Phi(Region,42,5);", code.print()); } @@ -84,7 +84,7 @@ if( arg==2 ) else b=5; return b;"""); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); +""", TypeInteger.constant(2)).parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 5;", code.print()); } @@ -124,7 +124,7 @@ else if( arg==3 ) else a=5; return a; -""", TypeInteger.constant(1)).parse().opto(); +""", TypeInteger.constant(1)).parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 3;", code.print()); } @@ -144,7 +144,7 @@ else a=5; return a; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return Phi(Region,3,5,4);", code.print()); } @@ -165,7 +165,7 @@ else a=5; return a; """, TypeInteger.constant(1)); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 3;", code.print()); } @@ -186,7 +186,7 @@ else a=5; return a; """, TypeInteger.constant(3)); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 4;", code.print()); } @@ -202,7 +202,7 @@ if( arg ) { } return a+b; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return Phi(Region,4,1);", code.print()); } @@ -221,7 +221,7 @@ if( arg ) { } return a+b; """, TypeInteger.constant(1)); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 4;", code.print()); } @@ -239,7 +239,7 @@ if( arg ) { } return a+b; """, TypeInteger.constant(0)); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 1;", code.print()); } @@ -257,7 +257,7 @@ if( arg ) { } return a+b+c; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 6;", code.print()); } @@ -298,7 +298,7 @@ if( arg ) { } return a+b+c; """, TypeInteger.constant(2)); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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 2ca6f8dd..498038c1 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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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 09669cc7..61815840 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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 0;", code.print()); } @@ -167,7 +167,7 @@ while(arg < 10) { } return arg; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return arg;", code.print()); } @@ -184,7 +184,7 @@ while(arg < 10) { } return a; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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 d36cdf7f..839b834d 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().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); } @Test @@ -40,7 +40,7 @@ else { } return x; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 0;", code.print()); } @@ -128,14 +128,14 @@ while(v1+arg) { } return 0; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return arg;", code.print()); } @@ -148,7 +148,7 @@ if(0) while(0) { } return 0; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 4;", code.print()); } @Test public void testSwap2() { CodeGen code = new CodeGen("return 1+(1+1);"); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 3;", code.print()); } @@ -181,7 +181,7 @@ while(arg) { } return a; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 1;", code.print()); } @@ -222,7 +222,7 @@ while(1) { if(1<0) while(arg==-0) arg=arg-arg; } """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return Top;", code.print()); } @@ -244,7 +244,7 @@ while(1) { } return 0!=0; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return Top;", code.print()); } @@ -257,7 +257,7 @@ while(0==1) while(v0) v0=1+v0; return 0; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 0;", code.print()); } @@ -273,14 +273,14 @@ while(1) v1=1; return v1+v0; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return Top;", code.print()); } @Test public void testFuzz8() { CodeGen code = new CodeGen("while(arg) arg = arg - 1; return arg;"); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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 cfffeb83..1b542d63 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().opto().typeCheck(); + var code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().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().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 0;", code.print()); } @@ -122,7 +122,7 @@ bar.a = 1; bar.a = 2; return bar.a; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 2;", code.print()); } @@ -138,7 +138,7 @@ else v.y = 3; return v; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); } catch( Exception e ) { assertEquals("Might be null accessing 'zAicm'",e.getMessage()); } } @@ -176,7 +176,7 @@ while (arg) { } return bar.a; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return Phi(Region,4,3);", code.print()); } @@ -261,7 +261,7 @@ while(arg) { } return ret; """); - try { code.parse().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return .v0;", code.print()); } @@ -351,7 +351,7 @@ while(arg < 10) { } return ret.v0; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().typeCheck(); + code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); assertEquals("Stop[ return Test.s0; return MEM[ 2:___ 3:.f0=0;]; return Test.s0; ]", code.print()); } @@ -429,7 +429,7 @@ while(0 next = m; }; }; N n = new N(new M); return n.next; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); + code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); assertEquals("3",Eval2.eval(code,0)); } @Test public void testNullRef4() { CodeGen code = new CodeGen("return -null-5/null-5;"); - try { code.parse().opto().typeCheck(); fail(); } - catch( Exception e ) { assertEquals("Cannot 5 // null",e.getMessage()); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); } catch( Exception e ) { assertEquals("Cannot null + 42",e.getMessage()); } } @@ -150,7 +150,7 @@ return n.i; struct _S{}; return 0; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck().GCM().localSched(); + code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck().GCM().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().opto().typeCheck().GCM().localSched(); + code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck().GCM().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 7cfa5817..9786006c 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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return Phi(Region,.f,0);", code.print()); } @@ -115,7 +115,7 @@ if (v1) { } return v0.f; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return arg;", code.print()); } @@ -150,7 +150,7 @@ while(1) { } return v.f; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return Top;", code.print()); } @@ -185,7 +185,7 @@ while (arg) { } return i; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 0;", code.print()); } @@ -205,7 +205,7 @@ while(arg) { } return arg; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 0;", code.print()); } @@ -223,7 +223,7 @@ if (arg) { } return v.f; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 0;", code.print()); } @@ -242,7 +242,7 @@ while (arg > 0) { } return v; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); //assertEquals("return new _S;", code.print()); } @@ -259,7 +259,7 @@ while(0>=0) { } return 0; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return Top;", code.print()); } @@ -277,7 +277,7 @@ u32 v0=0; return v1; } """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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 c1354e34..ccca2e2b 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().opto().typeCheck(); + var code = new CodeGen(test[0]).parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); + var code = new CodeGen("flt x = arg; return 0-x;").parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); + var code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); assertEquals(src,test[1],Eval2.eval(code,0)); } } @@ -53,7 +53,7 @@ public class Chapter14FloatTest { """ return 0; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 0;", code.print()); assertEquals("0", Eval2.eval(code, 0)); } @@ -84,7 +84,7 @@ return guess; """); // TODO: One of the problems with returning an OS error code, // is it chops all results to int. - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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 086bb824..3ba03b48 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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto().typeCheck(); + code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return Phi(Loop,(((1<>>0) { } return v0; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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 f363847a..3c1254d2 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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto().typeCheck(); + code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); + code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto().typeCheck(); + code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); fail(); } + try { code.parse().iter().opto().iterPostOpto().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return 0;", code.print()); } @@ -353,7 +353,7 @@ else { } return 0; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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 91e5cd38..ad9b99bc 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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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 52acff57..95a0fc37 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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto(); fail(); } + try { code.parse().iter().opto().iterPostOpto().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto(); + code.parse().iter().opto().iterPostOpto().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 b6768d6f..6137c166 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().opto().typeCheck(); + code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto().typeCheck(); + code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto(); fail(); } + try { code.parse().iter().opto().iterPostOpto().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().opto(); fail(); } + try { code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); + code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto().typeCheck(); + code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail(); } catch( Exception e ) { assertEquals("Cannot return generic scalar",e.getMessage()); } } @@ -444,7 +444,7 @@ for( int i=0; i int}? x2 = null; // null function ptr return x2; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return null;", code.print()); assertEquals("null", Eval2.eval(code, 0 ) ); } @@ -170,7 +170,7 @@ return x2; x*x; }; """); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); fail(); } + try { code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto(); + code.parse().iter().opto().iterPostOpto().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().opto().typeCheck(); + code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); + code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); + code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); + code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); + code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); assertEquals("return 1;", code.print()); assertEquals("1", Eval2.eval(code, 0)); } @@ -388,7 +388,7 @@ for(;;) { } return 1; """); - try { code.parse().opto(); fail(); } + try { code.parse().iter().opto().iterPostOpto().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); fail(); } + try { code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); + code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck().GCM(); + code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck().GCM(); 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 2419dc2d..2763e53d 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().opto().typeCheck(); + code.parse().iter().opto().iterPostOpto().finalizeIR().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 5acfbc8f..9f537fe7 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().opto().typeCheck(); + CodeGen code = new CodeGen(src,seed,true).parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); + code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); assertEquals("return 0;", code.print()); assertEquals("0", Eval2.eval(code, 2)); } @@ -122,7 +122,7 @@ return f(s); @Test public void testBasic1() { String src = "return arg | 2;"; - testCPU(src,"x86_64_v2", "SystemV",1,"return (ori,mov(arg));"); + testCPU(src,"x86_64_v2", "SystemV",1,"return mov((ori,arg));"); testCPU(src,"riscv" , "SystemV",0,"return ( arg | #2 );"); testCPU(src,"arm" , "SystemV",0,"return (ori,arg);"); } diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter21Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter21Test.java index 1f4913f0..83342ab8 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().opto(); + """).parse().iter().opto().iterPostOpto().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)); @@ -298,7 +298,7 @@ return new _s0.v1; @Test public void testBasic1() { String src = "return arg | 2;"; - testCPU(src,"x86_64_v2", "SystemV",1,"return (ori,mov(arg));"); + testCPU(src,"x86_64_v2", "SystemV",1,"return mov((ori,arg));"); testCPU(src,"riscv" , "SystemV",0,"return ( arg | #2 );"); testCPU(src,"arm" , "SystemV",0,"return (ori,arg);"); } diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter22Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter22Test.java index 7484a6ae..cbb08438 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().opto().typeCheck(); + new CodeGen("return null-0;").parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); fail("Subtraction must reject null even when the other operand is zero"); } catch( Parser.ParseException e ) { assertEquals("Cannot null - 0",e.getMessage()); @@ -135,6 +135,7 @@ return new s0.v1; static int testCPUSize( String src, String cpu, String os, int spills ) { + // Includes the file initializer's hidden $init=true store. return testCPU(src,cpu,os,spills, "return 0;" )._encoding._bits.size(); } @@ -146,9 +147,9 @@ struct _Person { i32 age;}; p.age = (arg<<17)>>17; return 0; """; - assertEquals(65, testCPUSize(src, "x86_64_v2","win64", 3 )); - assertEquals(76, testCPUSize(src, "riscv", "SystemV", 4 )); - assertEquals(76, testCPUSize(src, "arm" , "SystemV", 4 )); + assertEquals(76, testCPUSize(src, "x86_64_v2","win64", 3 )); + assertEquals(92, testCPUSize(src, "riscv", "SystemV", 4 )); + assertEquals(92, testCPUSize(src, "arm" , "SystemV", 4 )); // do assertEquals here EvalRisc5 R5 = TestRisc5.build( src, "sext_str_not_fold_away", 0, 4, false); @@ -178,9 +179,9 @@ return 0; int trap_arm = A5.step(100); assertEquals(0,trap_arm); - assertEquals(65, testCPUSize(src, "x86_64_v2","win64",3 )); - assertEquals(76, testCPUSize(src, "riscv", "SystemV",4 )); - assertEquals(76, testCPUSize(src, "arm", "SystemV",4 )); + assertEquals(76, testCPUSize(src, "x86_64_v2","win64",3 )); + assertEquals(92, testCPUSize(src, "riscv", "SystemV",4 )); + assertEquals(92, testCPUSize(src, "arm", "SystemV",4 )); } @@ -202,9 +203,9 @@ return 0; int trap_arm = A5.step(100); assertEquals(0,trap_arm); - assertEquals(55, testCPUSize(src, "x86_64_v2","win64",3 )); - assertEquals(72, testCPUSize(src, "riscv", "SystemV",5 )); - assertEquals(72, testCPUSize(src, "arm", "SystemV",5)); + assertEquals(66, testCPUSize(src, "x86_64_v2","win64",3 )); + assertEquals(84, testCPUSize(src, "riscv", "SystemV",5 )); + assertEquals(84, testCPUSize(src, "arm", "SystemV",5)); // do assertEquals here } @@ -282,7 +283,7 @@ aa.c = cc; bb.c = cc; return cc.cz; """; - CodeGen code = new CodeGen(src).parse().opto().typeCheck(); + CodeGen code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); assertEquals("return 25;", code.print()); assertEquals("25", Eval2.eval(code, 0)); } @@ -321,7 +322,7 @@ return 0; @Test public void testStrLoad() { CodeGen code = new CodeGen("return \"abc\"[1];"); - code.parse().opto(); + code.parse().iter().opto().iterPostOpto().finalizeIR(); assertEquals("return .[];", code.print()); } @@ -341,7 +342,7 @@ val _sum = { i32[~] is -> // final array }; return _sum(is); """; - CodeGen code = new CodeGen(src).parse().opto().typeCheck(); + CodeGen code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().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 053621bd..b5da4d91 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().opto(), 0)); - assertEquals("0", Eval2.eval(new CodeGen("return 0 && 42;").parse().opto(), 0)); - assertEquals("7", Eval2.eval(new CodeGen("return 7 || 42;").parse().opto(), 0)); - assertEquals("42", Eval2.eval(new CodeGen("return 0 || 42;").parse().opto(), 0)); + 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)); } @Test @@ -133,7 +133,7 @@ struct S {}; S? s = arg ? new S; return !(!s || !arg) ? 1 : 0; """); - code.parse().opto().typeCheck(); + code.parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); + CodeGen code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); + CodeGen code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); fail(); } + try { new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().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().opto().typeCheck(); + CodeGen code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().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 3e21c73e..4bfb0d30 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().opto().typeCheck(); + CodeGen code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); assertEquals("return 1;", code.print()); } @@ -272,7 +272,7 @@ while( cnt-- ) x = 2-x; return x; """; - CodeGen code = new CodeGen(src).parse().opto().typeCheck(); + CodeGen code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().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 30e1ed79..4e8effbe 100644 --- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter25Test.java +++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter25Test.java @@ -9,6 +9,7 @@ import com.seaofnodes.simple.codegen.RegAllocTestSupport.CheckedCodeGen; import com.seaofnodes.simple.codegen.ElfReader; import com.seaofnodes.simple.codegen.ParseAll; import com.seaofnodes.simple.node.CallNode; +import com.seaofnodes.simple.node.FunNode; import com.seaofnodes.simple.node.LoopNode; import com.seaofnodes.simple.type.TypeInteger; import com.seaofnodes.simple.util.Ary; @@ -27,6 +28,41 @@ import static org.junit.Assert.*; public class Chapter25Test { + @Test public void testPublicInstanceMethod() { + String src = """ + struct Scan { + val visible = { u8 c -> c==255; }; + val _hidden = { u8 c -> c==1; }; + }; + struct _Private { + val hiddenClassMethod = { u8 c -> c==2; }; + }; + return new Scan.visible(44); + """; + for( long seed : new long[]{1,123,987654321} ) { + CodeGen code = new CodeGen(src,seed,true).driver(CodeGen.Phase.Parse); + FunNode visible = null; + int checked = 0; + for( FunNode fun : code._linker ) { + if( fun==null || fun._name==null ) continue; + if( fun._name.equals("visible") ) { + assertTrue(code.publicFIDX(fun.sig().fidx())); + visible = fun; + checked++; + } + if( fun._name.equals("_hidden") || fun._name.equals("hiddenClassMethod") ) { + assertFalse(code.publicFIDX(fun.sig().fidx())); + checked++; + } + } + assertEquals(3,checked); + code.driver(CodeGen.Phase.TypeCheck); + assertTrue(visible.unknownCallers()); + assertEquals(TypeInteger.U8,visible.parm(3)._type); + assertEquals("0",Eval2.eval(code,0)); + } + } + @Ignore @Test public void testJig() { diff --git a/chapter25/src/test/java/com/seaofnodes/simple/ClassInitDependenciesTest.java b/chapter25/src/test/java/com/seaofnodes/simple/ClassInitDependenciesTest.java index e3af8cce..cc010668 100644 --- a/chapter25/src/test/java/com/seaofnodes/simple/ClassInitDependenciesTest.java +++ b/chapter25/src/test/java/com/seaofnodes/simple/ClassInitDependenciesTest.java @@ -1,11 +1,13 @@ package com.seaofnodes.simple; import com.seaofnodes.simple.codegen.*; -import com.seaofnodes.simple.node.FunNode; +import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeFunPtr; import com.seaofnodes.simple.type.Field; import com.seaofnodes.simple.type.TypeInteger; +import com.seaofnodes.simple.type.TypeMem; +import com.seaofnodes.simple.type.TypeTuple; import com.seaofnodes.simple.util.Ary; import java.nio.file.Files; import java.nio.file.Path; @@ -362,6 +364,75 @@ public class ClassInitDependenciesTest { compile("A",Map.of("A","int value=arg; val "+name+"={ -> A.value; }; int result="+name+"();"),seed); } + @Test public void testInitializationMemory() throws Exception { + String[] sources={ + "int value=B.value+B.value;", + "int value; if(arg) value=B.value; else value=B.value+1; value=value+B.value;", + "int value; if(arg) value=B.value; value=value+B.value;" + }; + int[] counts={1,2,2}; + for( long seed : new long[]{1,123,987654321} ) + for( int i=0; i { + if( n instanceof CLInitNode init && init.fun()==fun && init.cu()==b ) { + touches[0]++; + TypeTuple state=(TypeTuple)init._type; + assertSame(TypeMem.BOT,state._types[1]); + TypeMem flag=(TypeMem)state._types[2]; + assertEquals(b._clz.field("$init")._alias,flag._alias); + assertSame(TypeInteger.TRUE,flag._t); + assertNotNull(init.ready()); + } + return null; + }); + assertEquals(sources[i],counts[i],touches[0]); + } + } + + @Test public void testForwardInstanceTouch() { + String src=""" + struct S { int x=7; }; + val _get={ -> _make().x; }; + val _make={ -> new S; }; + return _get(); + """; + for( long seed : new long[]{1,123,987654321} ) { + CodeGen code=new CodeGen(src,seed,true).driver(CodeGen.Phase.Parse); + CLInitNode init=code._stop.walk(n -> n instanceof CLInitNode c ? c : null); + assertNotNull("The unresolved receiver needs a speculative check",init); + assertNotNull("The readiness load is present from parsing",init.ready()); + code.driver(CodeGen.Phase.TypeCheck); + assertNull("An instance needs neither CLInit nor its speculative $init load", + code._stop.walk(n -> n instanceof CLInitNode || + (n instanceof LoadNode ld && ld._name.equals("$init")) ? n : null)); + assertEquals("7",Eval2.eval(code,0)); + } + } + + @Test public void testInitializerFlagStore() throws Exception { + // A same-named struct must retain the file class's hidden flag. + CodeGen code=compile("A",Map.of("A","struct A { int value; }; int value=arg;"),123); + CompUnit a=code._compunits.get("Root/A"); + Field flag=a._clz.field("$init"); + assertNotNull(flag); + assertFalse(flag._final); + FunNode fun=code.link(a); + int[] stores={0}; + code._stop.walk(n -> { + if( n instanceof StoreNode st && st._name.equals("$init") && st._alias==flag._alias ) { + stores[0]++; + assertSame(TypeInteger.TRUE,st.val()._type); + assertSame(fun,CFGNode.earlyCFG(st).fun()); + } + return null; + }); + assertEquals(1,stores[0]); + } + @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 48f739cf..db41363a 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().opto().typeCheck(); + var code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); assertEquals(src, Long.toString(expected), Eval2.eval(code, arg)); } } diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Main.java b/chapter25/src/test/java/com/seaofnodes/simple/Main.java index 589c043b..97129f5b 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().opto().typeCheck().GCM().localSched(); + code.parse().iter().opto().iterPostOpto().finalizeIR().typeCheck().GCM().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 9406f480..4934c91f 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 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().opto(); + """).parse().iter().opto().iterPostOpto().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 60e4c5aa..9727857e 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().opto().typeCheck(); + var code = new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().typeCheck(); assertEquals(result,Eval2.eval(code,0)); } private static void bad(String src) { try { - new CodeGen(src).parse().opto().typeCheck(); + new CodeGen(src).parse().iter().opto().iterPostOpto().finalizeIR().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/Simple.java b/chapter25/src/test/java/com/seaofnodes/simple/Simple.java index b7e10122..9078a33a 100644 --- a/chapter25/src/test/java/com/seaofnodes/simple/Simple.java +++ b/chapter25/src/test/java/com/seaofnodes/simple/Simple.java @@ -45,7 +45,9 @@ Options: --dump-time - print compilation and execution times --dump-after-parse - dump intermediate representation after parse --dump-after-iter - dump intermediate representation after pessimistic iter pass - --dump-after-opto - dump intermediate representation after opto pass + --dump-after-opto - dump intermediate representation after SCCP + --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-select - dump intermediate representation after instruction selection pass --dump-after-gcm - dump intermediate representation after GCM pass @@ -114,6 +116,8 @@ Options: case "--dump-after-parse": dump |= 1<