diff options
Diffstat (limited to 'chapter17')
17 files changed, 187 insertions, 122 deletions
diff --git a/chapter17/src/main/java/com/seaofnodes/simple/Parser.java b/chapter17/src/main/java/com/seaofnodes/simple/Parser.java index 371bddf1..799e0629 100644 --- a/chapter17/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter17/src/main/java/com/seaofnodes/simple/Parser.java @@ -2,7 +2,6 @@ package com.seaofnodes.simple; import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.type.*; -import static com.seaofnodes.simple.Utils.TODO; import java.util.*; @@ -91,7 +90,7 @@ public class Parser { public final Stack<ScopeNode> _xScopes = new Stack<>(); ScopeNode _continueScope; - ScopeNode _breakScope; + ScopeNode _breakScope; // Merge all the while-breaks here // Mapping from a type name to a Type. The string name matches // `type.str()` call. No TypeMemPtrs are in here, because Simple does not @@ -169,7 +168,7 @@ public class Parser { if( ctrl()._type==Type.CONTROL ) STOP.addReturn(new ReturnNode(ctrl(), ZERO, _scope).peephole()); - _scope.pop(); + _scope.kill(); _xScopes.pop(); for( StructNode init : INITS.values() ) init.unkeep().kill(); @@ -269,7 +268,7 @@ public class Parser { // the loop predicate. Note that body Scope is still our current scope. ctrl(ifF); _xScopes.push(_breakScope = _scope.dup()); - _breakScope.upcast(ifF,pred,true); // Up-cast predicate + _breakScope.addGuards(ifF,pred,true); // Up-cast predicate // No continues yet _continueScope = null; @@ -277,8 +276,9 @@ public class Parser { // Parse the true side, which corresponds to loop body // Our current scope is the body Scope ctrl(ifT.unkeep()); // set ctrl token to ifTrue projection - _scope.upcast(ifT,pred,false); // Up-cast predicate + _scope.addGuards(ifT,pred,false); // Up-cast predicate parseStatement(); // Parse loop body + _scope.removeGuards(ifT); // Merge the loop bottom into other continue statements if (_continueScope != null) { @@ -330,8 +330,17 @@ public class Parser { private void checkLoopActive() { if (_breakScope == null) throw Parser.error("No active loop for a break or continue"); } - private Node parseBreak () { checkLoopActive(); return ( _breakScope = require(jumpTo( _breakScope ),";")); } private Node parseContinue() { checkLoopActive(); return (_continueScope = require(jumpTo( _continueScope ),";")); } + private Node parseBreak () { + checkLoopActive(); + // At the time of the break, and loop-exit conditions are only valid if + // they are ALSO valid at the break. It is the intersection of + // conditions here, not the union. + _breakScope.removeGuards(_breakScope.ctrl()); + _breakScope = require(jumpTo(_breakScope ),";"); + _breakScope.addGuards(_breakScope.ctrl(), null, false); + return _breakScope; + } /** * Parses a statement @@ -365,8 +374,10 @@ public class Parser { // Parse the true side ctrl(ifT.unkeep()); // set ctrl token to ifTrue projection - _scope.upcast(ifT,pred,false); // Up-cast predicate + _scope.addGuards(ifT,pred,false); // Up-cast predicate Node lhs = stmt ? parseStatement() : parseExpression().keep(); // Parse true-side + _scope.removeGuards(ifT); + ScopeNode tScope = _scope; // Parse the false side @@ -374,11 +385,12 @@ public class Parser { ctrl(ifF.unkeep()); // Ctrl token is now set to ifFalse projection // Up-cast predicate, even if not else clause, because predicate can // remain true if the true clause exits: `if( !ptr ) return 0; return ptr.fld;` - _scope.upcast(ifF,pred,true); + _scope.addGuards(ifF,pred,true); boolean doRHS = match(fside); Node rhs = doRHS ? (stmt ? parseStatement() : parseExpression()) : (stmt ? null : con(lhs._type.makeZero())); + _scope.removeGuards(ifF); if( doRHS ) fScope = _scope; pred.unkeep(); @@ -392,7 +404,7 @@ public class Parser { _xScopes.pop(); // Discard pushed from graph display RegionNode r = ctrl(tScope.mergeScopes(fScope)); - Node ret = stmt ? r : new PhiNode("",lhs._type.meet(rhs._type),r,lhs,rhs).peephole(); + Node ret = stmt ? r : peep(new PhiNode("",lhs._type.meet(rhs._type),r,lhs,rhs)); r.peephole(); return ret; } @@ -461,7 +473,7 @@ public class Parser { // Auto-widen int to float if( expr._type instanceof TypeInteger && t instanceof TypeFloat ) - expr = new ToFloatNode(expr).peephole(); + expr = peep(new ToFloatNode(expr)); // Auto-narrow wide ints to narrow ints expr = zsMask(expr,t); // Auto-deepen forward ref types @@ -653,7 +665,7 @@ public class Parser { else if( match("^") ) lhs = new XorNode(lhs,null); else break; lhs.setDef(2,parseComparison()); - lhs = lhs.peephole(); + lhs = peep(lhs); } return lhs; } @@ -681,9 +693,9 @@ public class Parser { else break; // Peepholes can fire, but lhs is already "hooked", kept alive lhs.setDef(idx,parseShift()); - lhs = lhs.widen().peephole(); + lhs = peep(lhs.widen()); if( negate ) // Extra negate for != - lhs = new NotNode(lhs).peephole(); + lhs = peep(new NotNode(lhs)); } return lhs; } @@ -705,7 +717,7 @@ public class Parser { else if( match(">>") ) lhs = new SarNode(lhs,null); else break; lhs.setDef(2,parseAddition()); - lhs = lhs.widen().peephole(); + lhs = peep(lhs.widen()); } return lhs; } @@ -726,7 +738,7 @@ public class Parser { else if( match("-") ) lhs = new SubNode(lhs,null); else break; lhs.setDef(2,parseMultiplication()); - lhs = lhs.widen().peephole(); + lhs = peep(lhs.widen()); } return lhs; } @@ -747,7 +759,7 @@ public class Parser { else if( match("/") ) lhs = new DivNode(lhs,null); else break; lhs.setDef(2,parseUnary()); - lhs = lhs.widen().peephole(); + lhs = peep(lhs.widen()); } return lhs; } @@ -761,8 +773,8 @@ public class Parser { * @return a unary expression {@link Node}, never {@code null} */ private Node parseUnary() { - if (match("-")) return new MinusNode(parseUnary()).widen().peephole(); - if (match("!")) return new NotNode(parseUnary()).peephole(); + if (match("-")) return peep(new MinusNode(parseUnary()).widen()); + if (match("!")) return peep(new NotNode(parseUnary())); return parsePostfix(parsePrimary()); } @@ -787,7 +799,7 @@ public class Parser { if( matchx("++") || matchx("--") ) { if( n._final ) throw error("Cannot reassign final '"+n._name+"'"); - _scope.update(n,new AddNode(rvalue,con( _lexer.peek(-1)=='+' ? 1 : -1)).peephole()); + _scope.update(n,peep(new AddNode(rvalue,con( _lexer.peek(-1)=='+' ? 1 : -1)))); } return rvalue.unkeep(); } @@ -882,7 +894,7 @@ public class Parser { private Node newArray(TypeStruct ary, Node len) { int base = ary.aryBase (); int scale= ary.aryScale(); - Node size = new AddNode(con(base),new ShlNode(len,con(scale)).peephole()).peephole(); + Node size = peep(new AddNode(con(base),peep(new ShlNode(len,con(scale))))); ALTMP.clear(); ALTMP.add(len); ALTMP.add(con(ary._fields[1]._type.makeInit())); return newStruct(ary,size,0,ALTMP); } @@ -935,7 +947,7 @@ public class Parser { Node off = (name.equals("[]") // If field is an array body // Array index math - ? new AddNode(con(base.aryBase()),new ShlNode(require(parseExpression(),"]"),con(base.aryScale())).peephole()).peephole() + ? peep(new AddNode(con(base.aryBase()),peep(new ShlNode(require(parseExpression(),"]"),con(base.aryScale()))))) // Struct field offsets are hardwired : con(base.offset(fidx))).keep(); @@ -958,20 +970,20 @@ public class Parser { // Structs don't need this; they only need a NPE check which is // done via the type system. if( base.isAry() ) load.setDef(0,ctrl()); - load = load.peephole(); + load = peep(load); // ary[idx]++ if( matchx("++") || matchx("--") ) { if( f._final && !f._fname.equals("[]") ) throw error("Cannot reassign final '"+f._fname+"'"); - Node inc = new AddNode(load,con( _lexer.peek(-1)=='+' ? 1 : -1)).peephole(); + Node inc = peep(new AddNode(load,con( _lexer.peek(-1)=='+' ? 1 : -1))); Node val = zsMask(inc,f._type); Node st = new StoreNode(name, f._alias, f._type, memAlias(f._alias), expr, off, val, false); // Arrays include control, as a proxy for a safety range check. // Structs don't need this; they only need a NPE check which is // done via the type system. if( base.isAry() ) st.setDef(0,ctrl()); - memAlias(f._alias, st.peephole()); + memAlias(f._alias, peep(st)); // And use the original loaded value as the result } if( off.unkeep().isDead() ) off.kill(); @@ -987,16 +999,16 @@ public class Parser { if( !(val._type instanceof TypeFloat tval && t instanceof TypeFloat t0 && !tval.isa(t0)) ) return val; // Float rounding - return new RoundF32Node(val).peephole(); + return peep(new RoundF32Node(val)); } if( t0._min==0 ) // Unsigned - return new AndNode(val,con(t0._max)).peephole(); + return peep(new AndNode(val,con(t0._max))); // Signed extension int shift = Long.numberOfLeadingZeros(t0._max)-1; Node shf = con(shift); if( shf._type==TypeInteger.ZERO ) return val; - return new SarNode(new ShlNode(val,shf.keep()).peephole(),shf.unkeep()).peephole(); + return peep(new SarNode(peep(new ShlNode(val,shf.keep())),shf.unkeep())); } @@ -1011,6 +1023,10 @@ public class Parser { private ConstantNode parseLiteral() { return con(_lexer.parseNumber()); } public static Node con( long con ) { return con(TypeInteger.constant(con)); } public static ConstantNode con( Type t ) { return (ConstantNode)new ConstantNode(t).peephole(); } + public Node peep( Node n ) { + // Peephole, then improve with lexically scoped guards + return _scope.upcastGuard(n.peephole()); + } ////////////////////////////////// // Utilities for lexical analysis diff --git a/chapter17/src/main/java/com/seaofnodes/simple/node/Node.java b/chapter17/src/main/java/com/seaofnodes/simple/node/Node.java index 35dbc19e..3827fdac 100644 --- a/chapter17/src/main/java/com/seaofnodes/simple/node/Node.java +++ b/chapter17/src/main/java/com/seaofnodes/simple/node/Node.java @@ -267,6 +267,10 @@ public abstract class Node implements OutNode { } // Test "keep" status public boolean iskeep() { return _outputs.find(null) != -1; } + public void unkill() { + if( unkeep().isUnused() ) + kill(); + } // Replace self with nnn in the graph, making 'this' go dead diff --git a/chapter17/src/main/java/com/seaofnodes/simple/node/NotNode.java b/chapter17/src/main/java/com/seaofnodes/simple/node/NotNode.java index ffd3e01e..664d7c7b 100644 --- a/chapter17/src/main/java/com/seaofnodes/simple/node/NotNode.java +++ b/chapter17/src/main/java/com/seaofnodes/simple/node/NotNode.java @@ -28,15 +28,14 @@ public class NotNode extends Node { // top->top, bot->bot, null->1, *void->0, not-null ptr->0, ptr/nil->bot // If input in null then true // If input is not null ptr then false - if( p0 == TypeMemPtr.TOP ) return TypeInteger.TOP; - if( p0 == TypeMemPtr.NULLPTR ) return TypeInteger.constant(1); - if( !p0._nil ) return TypeInteger.constant(0); - return TypeInteger.BOT; + if( p0 == TypeMemPtr.NULLPTR ) return TypeInteger.TRUE; + if( !p0._nil ) return TypeInteger.FALSE; + return TypeInteger.BOOL; case Type t: if( t0.getClass() != Type.class ) // Only doing NOT on ints and ptrs throw Utils.TODO(); - return t0==Type.TOP ? Type.TOP : Type.BOTTOM; + return TypeInteger.BOOL; } } diff --git a/chapter17/src/main/java/com/seaofnodes/simple/node/RegionNode.java b/chapter17/src/main/java/com/seaofnodes/simple/node/RegionNode.java index a55bb479..9e0f46cb 100644 --- a/chapter17/src/main/java/com/seaofnodes/simple/node/RegionNode.java +++ b/chapter17/src/main/java/com/seaofnodes/simple/node/RegionNode.java @@ -18,7 +18,7 @@ public class RegionNode extends CFGNode { @Override StringBuilder _print1(StringBuilder sb, BitSet visited) { - return sb.append(label()).append(_nid); + return sb.append(label()); } @Override public boolean isMultiHead() { return true; } diff --git a/chapter17/src/main/java/com/seaofnodes/simple/node/ScopeNode.java b/chapter17/src/main/java/com/seaofnodes/simple/node/ScopeNode.java index 2fc495c5..5a735515 100644 --- a/chapter17/src/main/java/com/seaofnodes/simple/node/ScopeNode.java +++ b/chapter17/src/main/java/com/seaofnodes/simple/node/ScopeNode.java @@ -32,12 +32,19 @@ public class ScopeNode extends ScopeMinNode { // True if parsing inside of a constructor public final Ary<Boolean> _inCons; + // Extra guards; tested predicates and casted results + private final Ary<Node> _guards; + // A new ScopeNode - public ScopeNode() { _vars = new Ary<>(Var.class); _lexSize = new Ary<>(Integer.class); _inCons = new Ary<>(Boolean.class); } + public ScopeNode() { + _vars = new Ary<>(Var .class); + _lexSize= new Ary<>(Integer.class); + _inCons = new Ary<>(Boolean.class); + _guards = new Ary<>(Node .class); + } @Override public String label() { return "Scope"; } - @Override StringBuilder _print1(StringBuilder sb, BitSet visited) { sb.append("Scope[ "); @@ -187,9 +194,15 @@ public class ScopeNode extends ScopeMinNode { // 1) duplicate the name bindings of the ScopeNode across all stack levels // 2) Make the new ScopeNode a user of all the nodes bound // 3) Ensure that the order of defs is the same to allow easy merging - dup._vars.addAll(_vars); + dup._vars .addAll(_vars ); dup._lexSize.addAll(_lexSize); dup._inCons .addAll(_inCons ); + dup._guards .addAll(_guards ); + // The dup'd guards all need dup'd keepers, to keep proper accounting + // when later removing all guards + for( Node n : _guards ) + if( !(n instanceof CFGNode) ) + n.keep(); dup.addDef(ctrl()); // Control input is just copied // Memory input is a shallow copy @@ -274,44 +287,78 @@ public class ScopeNode extends ScopeMinNode { // Up-casting: using the results of an If to improve a value. // E.g. "if( ptr ) ptr.field;" is legal because ptr is known not-null. - - // This Scope looks for direct variable uses, or certain simple - // combinations, and replaces the variable with the upcast variant. - public Node upcast( Node ctrl, Node pred, boolean invert ) { - if( ctrl._type == Type.XCONTROL || pred.isDead() ) - return null; // Dead, do not do anything + public void addGuards( Node ctrl, Node pred, boolean invert ) { + assert ctrl instanceof CFGNode; + _guards.add(ctrl); // Marker to distinguish 0,1,2 guards + // add pred & its cast to the normal input list, with special Vars + if( ctrl._type == Type.XCONTROL || pred==null || pred.isDead() ) + return; // Dead, do not add any guards // Invert the If conditional if( invert ) pred = pred instanceof NotNode not ? not.in(1) : IterPeeps.add(new NotNode(pred).peephole()); - - // Direct use of a value as predicate. This is a zero/null test. - if( _inputs.find(pred) != -1 ) { - if( !(pred._type instanceof TypeMemPtr tmp) ) - // Must be an `int`, since int and ptr are the only two value types - // being tested. No representation for a generic not-null int, so no upcast. - return null; - if( tmp.isa(TypeMemPtr.VOIDPTR) ) - return null; // Already not-null, no reason to upcast - // Upcast the ptr to not-null ptr, and replace in scope - return replace(pred,new CastNode(TypeMemPtr.VOIDPTR,ctrl,pred).peephole()); + // This is a zero/null test. + // Compute the positive test type. + Type tnz = pred._type.nonZero(); + Type tcast = tnz.join(pred._type); + if( tcast != pred._type ) { + Node cast = new CastNode(tnz,ctrl,pred.keep()).peephole().keep(); + _guards.add(pred); + _guards.add(cast); + replace(pred,cast); } + // Compute the negative test type. if( pred instanceof NotNode not ) { - // Direct use of a !value as predicate. This is a zero/null test. - if( _inputs.find(not.in(1)) != -1 ) { - Type tinit = not.in(1)._type.makeInit(); - if( not.in(1)._type.isa(tinit) ) return null; // Already zero/null, no reason to upcast - return replace(not.in(1), new ConstantNode(tinit).peephole()); + Node npred = not.in(1); + Type tzero = npred._type.makeZero(); + Type tzcast= tzero.join(npred._type); + if( tzcast != npred._type ) { + Node cast = new CastNode(tzero,ctrl,npred.keep()).peephole().keep(); + _guards.add(npred); + _guards.add( cast); + replace(npred,cast); } } - // Apr/9/2024: Attempted to replace X with Y if guarded by a test of - // X==Y. This didn't seem to help very much, or at least in the test - // cases seen so far was a very minor help. + } - // No upcast - return null; + // Remove matching pred/cast pairs from this guarded region. + public void removeGuards( Node ctrl ) { + assert ctrl instanceof CFGNode; + // 0,1 or 2 guards + while( true ) { + Node g = _guards.pop(); + if( g == ctrl ) break; + if( g instanceof CFGNode ) continue; + g .unkill(); // Pop/kill cast + _guards.pop().unkill(); // Pop/kill pred + } } + // If we find a guarded instance of pred, replace with the upcasted version + public Node upcastGuard( Node pred ) { + // If finding an instanceof pred, replace with cast. + // Otherwise, just pred itself. + int i = _guards._len; + while( i > 0 ) { + Node cast = _guards.at(--i); + if( cast instanceof CFGNode ) continue; // Marker between guard sets + Node xpred = _guards.at(--i); + if( xpred == pred ) + return cast; + } + return pred; + } + + // Kill guards also + @Override public void kill() { + for( Node n : _guards ) + if( !(n instanceof CFGNode) ) + n.unkill(); + _guards.clear(); + super.kill(); + } + + private Node replace( Node old, Node cast ) { assert old!=null && old!=cast; for( int i=0; i<nIns(); i++ ) diff --git a/chapter17/src/test/java/com/seaofnodes/simple/Chapter05Test.java b/chapter17/src/test/java/com/seaofnodes/simple/Chapter05Test.java index b5920125..9afb8f28 100644 --- a/chapter17/src/test/java/com/seaofnodes/simple/Chapter05Test.java +++ b/chapter17/src/test/java/com/seaofnodes/simple/Chapter05Test.java @@ -17,12 +17,11 @@ if (arg == 1) a = arg+2; else { a = arg-3; - } - -return a;"""); +return a; +"""); StopNode ret = parser.parse().iterate(); - assertEquals("return Phi(Region23,(arg+2),(arg-3));", ret.toString()); + assertEquals("return Phi(Region,(arg+2),(arg-3));", ret.toString()); } @Test @@ -37,7 +36,7 @@ if (arg == 1) { } return c;""", TypeInteger.BOT); StopNode ret = parser.parse().iterate(); - assertEquals("return Phi(Region22,4,3);", ret.toString()); + assertEquals("return Phi(Region,4,3);", ret.toString()); } @Test @@ -65,7 +64,7 @@ else b=a+1; return a+b;"""); StopNode ret = parser.parse().iterate(); - assertEquals("return ((arg*2)+Phi(Region26,2,3));", ret.toString()); + assertEquals("return ((arg*2)+Phi(Region,2,3));", ret.toString()); } @Test @@ -80,7 +79,7 @@ else a=b+1; return a+b;"""); StopNode ret = parser.parse().iterate(); - assertEquals("return ((Phi(Region37,(arg*2),arg)+arg)+Phi(Region,4,5));", ret.toString()); + assertEquals("return ((Phi(Region,(arg*2),arg)+arg)+Phi(Region,4,5));", ret.toString()); } @Test @@ -100,7 +99,7 @@ else return a; """, TypeInteger.BOT); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Region43,Phi(Region28,2,3),Phi(Region41,4,5));", stop.toString()); + assertEquals("return Phi(Region,Phi(Region,2,3),Phi(Region,4,5));", stop.toString()); } @Test @@ -116,7 +115,7 @@ if( arg==0 ) return arg+a+b; """, TypeInteger.BOT); StopNode stop = parser.parse(); - assertEquals("return ((arg+Phi(Region20,1,0))+Phi(Region37,2,0));", stop.toString()); + assertEquals("return ((arg+Phi(Region,1,0))+Phi(Region,2,0));", stop.toString()); } @Test @@ -130,7 +129,7 @@ if( arg==1 ) } return a;"""); StopNode ret = parser.parse().iterate(); - assertEquals("return (arg==Phi(Region22,3,2));", ret.toString()); + assertEquals("return (arg==Phi(Region,3,2));", ret.toString()); } @Test diff --git a/chapter17/src/test/java/com/seaofnodes/simple/Chapter06Test.java b/chapter17/src/test/java/com/seaofnodes/simple/Chapter06Test.java index 6308bdea..50c0580d 100644 --- a/chapter17/src/test/java/com/seaofnodes/simple/Chapter06Test.java +++ b/chapter17/src/test/java/com/seaofnodes/simple/Chapter06Test.java @@ -65,7 +65,7 @@ else b=5; return b;""", TypeInteger.BOT); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Region43,42,5);", stop.toString()); + assertEquals("return Phi(Region,42,5);", stop.toString()); } @Test @@ -84,7 +84,7 @@ else b=5; return b;""", TypeInteger.BOT); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Region36,2,5);", stop.toString()); + assertEquals("return Phi(Region,2,5);", stop.toString()); } @Test @@ -144,7 +144,7 @@ else return a; """, TypeInteger.BOT); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Region48,3,Phi(Region46,4,5));", stop.toString()); + assertEquals("return Phi(Region,3,Phi(Region,4,5));", stop.toString()); } @Test @@ -200,7 +200,7 @@ if( arg ) { return a+b; """); StopNode ret = parser.parse().iterate(); - assertEquals("return Phi(Region32,4,1);", ret.toString()); + assertEquals("return Phi(Region,4,1);", ret.toString()); } @@ -251,7 +251,7 @@ if( arg ) { return a+b+c; """); StopNode ret = parser.parse().iterate(); - assertEquals("return (Phi(Region45,Phi(Region29,2,3),0)+Phi(Region,3,1));", ret.toString()); + assertEquals("return (Phi(Region,Phi(Region,2,3),0)+Phi(Region,3,1));", ret.toString()); } diff --git a/chapter17/src/test/java/com/seaofnodes/simple/Chapter07Test.java b/chapter17/src/test/java/com/seaofnodes/simple/Chapter07Test.java index 80cb15d4..23ad18f1 100644 --- a/chapter17/src/test/java/com/seaofnodes/simple/Chapter07Test.java +++ b/chapter17/src/test/java/com/seaofnodes/simple/Chapter07Test.java @@ -18,7 +18,7 @@ public class Chapter07Test { """); Node._disablePeephole = true; StopNode stop = parser.parse(); - assertEquals("return Phi(Loop10,arg,(Phi_arg+1));", stop.toString()); + assertEquals("return Phi(Loop,arg,(Phi_arg+1));", stop.toString()); assertTrue(stop.ret().ctrl() instanceof CProjNode); Node._disablePeephole = false; } @@ -36,7 +36,7 @@ if(arg){}else{ return a; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Region32,1,Phi(Loop18,1,(Phi_a+1)));", stop.toString()); + assertEquals("return Phi(Region,1,Phi(Loop,1,(Phi_a+1)));", stop.toString()); } @Test @@ -56,7 +56,7 @@ while(i < arg) { return sum; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop12,0,Phi(Loop27,Phi_sum,(Phi_sum+Phi(Loop,0,(Phi_j+1)))));", stop.toString()); + assertEquals("return Phi(Loop,0,Phi(Loop,Phi_sum,(Phi_sum+Phi(Loop,0,(Phi_j+1)))));", stop.toString()); } @Test @@ -73,7 +73,7 @@ return b; """); Node._disablePeephole = true; StopNode stop = parser.parse(); - assertEquals("return Phi(Loop12,2,Phi(Region35,Phi_b,4));", stop.toString()); + assertEquals("return Phi(Loop,2,Phi(Region,Phi_b,4));", stop.toString()); assertTrue(stop.ret().ctrl() instanceof CProjNode); Node._disablePeephole = false; } @@ -93,7 +93,7 @@ while(a < 10) { return b; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop12,2,(Phi(Region35,Phi_b,4)+1));", stop.toString()); + assertEquals("return Phi(Loop,2,(Phi(Region,Phi_b,4)+1));", stop.toString()); assertTrue(stop.ret().ctrl() instanceof CProjNode); } @@ -111,7 +111,7 @@ return a; """); Node._disablePeephole = true; StopNode stop = parser.parse(); - assertEquals("return Phi(Loop11,1,((Phi_a+1)+2));", stop.toString()); + assertEquals("return Phi(Loop,1,((Phi_a+1)+2));", stop.toString()); assertTrue(stop.ret().ctrl() instanceof CProjNode); Node._disablePeephole = false; } @@ -128,7 +128,7 @@ while(a < 10) { return a; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop11,1,(Phi_a+3));", stop.toString()); + assertEquals("return Phi(Loop,1,(Phi_a+3));", stop.toString()); assertTrue(stop.ret().ctrl() instanceof CProjNode); } @@ -142,7 +142,7 @@ return a; """); Node._disablePeephole = true; StopNode stop = parser.parse(); - assertEquals("return Phi(Loop11,1,2);", stop.toString()); + assertEquals("return Phi(Loop,1,2);", stop.toString()); assertTrue(stop.ret().ctrl() instanceof CProjNode); Node._disablePeephole = false; } @@ -156,7 +156,7 @@ while(arg) a = 2; return a; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop11,1,2);", stop.toString()); + assertEquals("return Phi(Loop,1,2);", stop.toString()); assertTrue(stop.ret().ctrl() instanceof CProjNode); } @@ -173,7 +173,7 @@ return a; """); Node._disablePeephole = true; StopNode stop = parser.parse(); - assertEquals("return Phi(Loop11,1,((Phi_a+1)+2));", stop.toString()); + assertEquals("return Phi(Loop,1,((Phi_a+1)+2));", stop.toString()); assertTrue(stop.ret().ctrl() instanceof CProjNode); Node._disablePeephole = false; } @@ -190,7 +190,7 @@ while(a < 10) { return a; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop11,1,(Phi_a+3));", stop.toString()); + assertEquals("return Phi(Loop,1,(Phi_a+3));", stop.toString()); assertTrue(stop.ret().ctrl() instanceof CProjNode); } @@ -208,7 +208,7 @@ return a; """); Node._disablePeephole = true; StopNode stop = parser.parse(); - assertEquals("return Phi(Loop12,1,((Phi_a+1)+2));", stop.toString()); + assertEquals("return Phi(Loop,1,((Phi_a+1)+2));", stop.toString()); assertTrue(stop.ret().ctrl() instanceof CProjNode); Node._disablePeephole = false; } @@ -226,7 +226,7 @@ while(a < 10) { return a; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop12,1,(Phi_a+3));", stop.toString()); + assertEquals("return Phi(Loop,1,(Phi_a+3));", stop.toString()); assertTrue(stop.ret().ctrl() instanceof CProjNode); } diff --git a/chapter17/src/test/java/com/seaofnodes/simple/Chapter08Test.java b/chapter17/src/test/java/com/seaofnodes/simple/Chapter08Test.java index 5372388b..29fd09dc 100644 --- a/chapter17/src/test/java/com/seaofnodes/simple/Chapter08Test.java +++ b/chapter17/src/test/java/com/seaofnodes/simple/Chapter08Test.java @@ -23,7 +23,7 @@ while(arg < 10) { return arg; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Region46,Phi(Region33,Phi(Loop10,arg,(Phi_arg+1)),Add),Add);", stop.toString()); + assertEquals("return Phi(Region,Phi(Region,Phi(Loop,arg,(Phi_arg+1)),Add),Add);", stop.toString()); assertTrue(stop.ret().ctrl() instanceof RegionNode); Assert.assertEquals(5L, Evaluator.evaluate(stop, 1)); Assert.assertEquals(10L, Evaluator.evaluate(stop, 6)); @@ -46,7 +46,7 @@ while(arg < 10) { return a; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop11,1,Phi(Region53,Phi_a,(Phi_a+1)));", stop.toString()); + assertEquals("return Phi(Loop,1,Phi(Region,Phi_a,(Phi_a+1)));", stop.toString()); assertTrue(stop.ret().ctrl() instanceof CProjNode); } @@ -65,7 +65,7 @@ while(arg < 10) { return arg; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Region44,Phi(Loop10,arg,(Phi_arg+1)),Add);", stop.toString()); + assertEquals("return Phi(Region,Phi(Loop,arg,(Phi_arg+1)),Add);", stop.toString()); assertTrue(stop.ret().ctrl() instanceof RegionNode); } @@ -81,7 +81,7 @@ while(arg < 10) { return arg; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Region33,Phi(Loop10,arg,(Phi_arg+1)),Add);", stop.toString()); + assertEquals("return Phi(Region,Phi(Loop,arg,(Phi_arg+1)),Add);", stop.toString()); assertTrue(stop.ret().ctrl() instanceof RegionNode); } @@ -100,7 +100,7 @@ while(arg < 10) { return arg; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop10,arg,(Phi_arg+1));", stop.toString()); + assertEquals("return Phi(Loop,arg,(Phi_arg+1));", stop.toString()); assertTrue(stop.ret().ctrl() instanceof CProjNode); } @@ -117,7 +117,7 @@ while(arg < 10) { return arg; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop10,arg,(Phi_arg+1));", stop.toString()); + assertEquals("return Phi(Loop,arg,(Phi_arg+1));", stop.toString()); assertTrue(stop.ret().ctrl() instanceof CProjNode); } @@ -185,7 +185,7 @@ while(arg < 10) { return a; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Region36,Phi(Loop11,1,(Phi_a+1)),Add);", stop.toString()); + assertEquals("return Phi(Region,Phi(Loop,1,(Phi_a+1)),Add);", stop.toString()); assertTrue(stop.ret().ctrl() instanceof RegionNode); } @@ -201,7 +201,7 @@ while(1) { return a; """); StopNode stop = parser.parse().iterate(); - assertEquals("return (Phi(Loop11,1,Add)+1);", stop.toString()); + assertEquals("return (Phi(Loop,1,Add)+1);", stop.toString()); assertTrue(stop.ret().ctrl() instanceof CProjNode prj && prj._idx==1 ); } diff --git a/chapter17/src/test/java/com/seaofnodes/simple/Chapter09Test.java b/chapter17/src/test/java/com/seaofnodes/simple/Chapter09Test.java index 04ab8001..c31afcd6 100644 --- a/chapter17/src/test/java/com/seaofnodes/simple/Chapter09Test.java +++ b/chapter17/src/test/java/com/seaofnodes/simple/Chapter09Test.java @@ -69,7 +69,7 @@ while (arg < 10) { return arg; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop11,arg,(Phi_arg+2));", stop.toString()); + assertEquals("return Phi(Loop,arg,(Phi_arg+2));", stop.toString()); Assert.assertEquals(11L, Evaluator.evaluate(stop, 1)); } @@ -86,7 +86,7 @@ while (arg < 10) { return arg; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop12,arg,(Phi_arg+4));", stop.toString()); + assertEquals("return Phi(Loop,arg,(Phi_arg+4));", stop.toString()); Assert.assertEquals(13L, Evaluator.evaluate(stop, 1)); } @@ -185,7 +185,7 @@ while(arg) { return a; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop13,0,(-(Phi_a+3)));", stop.toString()); + assertEquals("return Phi(Loop,0,(-(Phi_a+3)));", stop.toString()); } @Test diff --git a/chapter17/src/test/java/com/seaofnodes/simple/Chapter10Test.java b/chapter17/src/test/java/com/seaofnodes/simple/Chapter10Test.java index 0bf921f6..44d71b1e 100644 --- a/chapter17/src/test/java/com/seaofnodes/simple/Chapter10Test.java +++ b/chapter17/src/test/java/com/seaofnodes/simple/Chapter10Test.java @@ -104,7 +104,7 @@ while (arg) { return bar.a; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop16,0,(Phi_a+2));", stop.toString()); + assertEquals("return Phi(Loop,0,(Phi_a+2));", stop.toString()); } @Test @@ -156,7 +156,7 @@ if( bar ) bar.a = 1; return bar; """); StopNode stop = parser.parse(false).iterate(); - assertEquals("return Phi(Region38,(*void)Phi(Region24,null,Bar),null);", stop.toString()); + assertEquals("return Phi(Region,(*void)Phi(Region,null,Bar),null);", stop.toString()); } @Test @@ -172,7 +172,7 @@ else bar.a = 1; return rez; """); StopNode stop = parser.parse(false).iterate(); - assertEquals("return Phi(Region44,4,3);", stop.toString()); + assertEquals("return Phi(Region,4,3);", stop.toString()); } @Test @@ -226,7 +226,7 @@ while( i.x < i.len ) { return sum; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop21,0,(Phi(Loop,0,(Phi_x+1))+Phi_sum));", stop.toString()); + assertEquals("return Phi(Loop,0,(Phi(Loop,0,(Phi_x+1))+Phi_sum));", stop.toString()); } @@ -245,7 +245,7 @@ while(arg) { return ret; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop16,s0,Phi(Region45,s0,Phi_ret));", stop.toString()); + assertEquals("return Phi(Loop,s0,Phi(Region,s0,Phi_ret));", stop.toString()); } @Test @@ -263,7 +263,7 @@ while(arg) { return ret; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop20,s0,Phi(Region46,s0,Phi_ret));", stop.toString()); + assertEquals("return Phi(Loop,s0,Phi(Region,s0,Phi_ret));", stop.toString()); } @@ -280,7 +280,7 @@ while(arg < 10) { return ret; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop16,s0,Phi(Region42,s0,Phi_ret));", stop.toString()); + assertEquals("return Phi(Loop,s0,Phi(Region,s0,Phi_ret));", stop.toString()); } @Test diff --git a/chapter17/src/test/java/com/seaofnodes/simple/Chapter11Test.java b/chapter17/src/test/java/com/seaofnodes/simple/Chapter11Test.java index 44814d53..11424720 100644 --- a/chapter17/src/test/java/com/seaofnodes/simple/Chapter11Test.java +++ b/chapter17/src/test/java/com/seaofnodes/simple/Chapter11Test.java @@ -324,7 +324,7 @@ while( prime <= arg ) { return primeCount; """); StopNode stop = parser.parse().iterate(); - assertEquals("Stop[ return 0; return Phi(Loop23,1,Phi(Region102,Phi_primeCount,Phi(Region95,(Phi_primeCount+1),Phi_primeCount))); ]", stop.toString()); + assertEquals("Stop[ return 0; return Phi(Loop,1,Phi(Region,Phi_primeCount,Phi(Region,(Phi_primeCount+1),Phi_primeCount))); ]", stop.toString()); assertEquals(0L, Evaluator.evaluate(stop, 1)); // No primes 1 or below assertEquals(1L, Evaluator.evaluate(stop, 2)); // 2 assertEquals(2L, Evaluator.evaluate(stop, 3)); // 2, 3 @@ -369,7 +369,7 @@ if (arg) { return i; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Region45,.f,0);", stop.toString()); + assertEquals("return Phi(Region,.f,0);", stop.toString()); } @Test diff --git a/chapter17/src/test/java/com/seaofnodes/simple/Chapter12Test.java b/chapter17/src/test/java/com/seaofnodes/simple/Chapter12Test.java index c0f6266a..a70a5f33 100644 --- a/chapter17/src/test/java/com/seaofnodes/simple/Chapter12Test.java +++ b/chapter17/src/test/java/com/seaofnodes/simple/Chapter12Test.java @@ -43,7 +43,7 @@ while( 1 ) { return guess; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop11,(flt)arg,(((ToFloat/Phi_guess)+Phi_guess)/2.0));", stop.toString()); + assertEquals("return Phi(Loop,(flt)arg,(((ToFloat/Phi_guess)+Phi_guess)/2.0));", stop.toString()); assertEquals(3.0, Evaluator.evaluate(stop, 9)); assertEquals(1.414213562373095, Evaluator.evaluate(stop, 2)); } diff --git a/chapter17/src/test/java/com/seaofnodes/simple/Chapter14Test.java b/chapter17/src/test/java/com/seaofnodes/simple/Chapter14Test.java index e72b0c76..01cecebb 100644 --- a/chapter17/src/test/java/com/seaofnodes/simple/Chapter14Test.java +++ b/chapter17/src/test/java/com/seaofnodes/simple/Chapter14Test.java @@ -175,7 +175,7 @@ while(v1) break; return v1; """); StopNode stop = parser.parse().iterate(); - assertEquals("return (Phi(Loop18,((1<<arg)&1),0)&Phi(Loop,Shl,4294967295));", stop.toString()); + assertEquals("return (Phi(Loop,((1<<arg)&1),0)&Phi(Loop,Shl,4294967295));", stop.toString()); assertEquals(1L, Evaluator.evaluate(stop, 0)); } diff --git a/chapter17/src/test/java/com/seaofnodes/simple/Chapter15Test.java b/chapter17/src/test/java/com/seaofnodes/simple/Chapter15Test.java index 4226c201..04958819 100644 --- a/chapter17/src/test/java/com/seaofnodes/simple/Chapter15Test.java +++ b/chapter17/src/test/java/com/seaofnodes/simple/Chapter15Test.java @@ -130,7 +130,7 @@ else { return rez; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Region117,1.2,Phi(Region114,2.3,3.14));", stop.toString()); + assertEquals("return Phi(Region,1.2,Phi(Region,2.3,3.14));", stop.toString()); assertEquals(3.14, Evaluator.evaluate(stop, 0)); assertEquals(1.2 , Evaluator.evaluate(stop, 1)); } @@ -157,7 +157,7 @@ if( iss[arg] ) return rez; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Region122,Phi(Region118,.y,1.2),1.2);", stop.toString()); + assertEquals("return Phi(Region,Phi(Region,.y,1.2),1.2);", stop.toString()); assertEquals(3.14, Evaluator.evaluate(stop, 0)); } diff --git a/chapter17/src/test/java/com/seaofnodes/simple/Chapter16Test.java b/chapter17/src/test/java/com/seaofnodes/simple/Chapter16Test.java index be48ec55..d0e30a7c 100644 --- a/chapter17/src/test/java/com/seaofnodes/simple/Chapter16Test.java +++ b/chapter17/src/test/java/com/seaofnodes/simple/Chapter16Test.java @@ -64,7 +64,7 @@ if( arg ) { int x = y; x = x*x; y=x; } // Shadow final x return y; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Region21,9,3);", stop.toString()); + assertEquals("return Phi(Region,9,3);", stop.toString()); assertEquals(3L, Evaluator.evaluate(stop, 0)); assertEquals(9L, Evaluator.evaluate(stop, 1)); } diff --git a/chapter17/src/test/java/com/seaofnodes/simple/Chapter17Test.java b/chapter17/src/test/java/com/seaofnodes/simple/Chapter17Test.java index 5db9592e..fe275ee9 100644 --- a/chapter17/src/test/java/com/seaofnodes/simple/Chapter17Test.java +++ b/chapter17/src/test/java/com/seaofnodes/simple/Chapter17Test.java @@ -105,7 +105,7 @@ return d; return arg ? 1 : 2; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Region19,1,2);", stop.toString()); + assertEquals("return Phi(Region,1,2);", stop.toString()); assertEquals(2L, Evaluator.evaluate(stop, 0)); assertEquals(1L, Evaluator.evaluate(stop, 1)); } @@ -128,7 +128,7 @@ var b = arg ? new Bar : null; return b ? b.x++ + b.x++ : -1; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Region54,1,-1);", stop.toString()); + assertEquals("return Phi(Region,1,-1);", stop.toString()); assertEquals(-1L, Evaluator.evaluate(stop, 0)); assertEquals( 1L, Evaluator.evaluate(stop, 1)); } @@ -141,21 +141,21 @@ var b = arg ? new Bar; return b ? b.x++ + b.x++ : -1; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Region54,1,-1);", stop.toString()); + assertEquals("return Phi(Region,1,-1);", stop.toString()); assertEquals(-1L, Evaluator.evaluate(stop, 0)); assertEquals( 1L, Evaluator.evaluate(stop, 1)); } - @Ignore @Test public void testTrinary4() { + // This test case will benefit from an unzipping transformation Parser parser = new Parser(""" struct Bar { Bar? next; int x; }; var b = arg ? new Bar { next = (arg==2) ? new Bar{x=2;}; x=1; }; return b ? b.next ? b.next.x : b.x; // parses "b ? (b.next ? b.next.x : b.x) : 0" """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Region51,1,-1);", stop.toString()); + assertEquals("return Phi(Region,Phi(Region,.x,.x),0);", stop.toString()); assertEquals( 0L, Evaluator.evaluate(stop, 0)); assertEquals( 1L, Evaluator.evaluate(stop, 1)); assertEquals( 2L, Evaluator.evaluate(stop, 2)); @@ -178,7 +178,7 @@ while( head ) { return sum; """); StopNode stop = parser.parse().iterate(); - assertEquals("return Phi(Loop35,0,(Phi_sum+.i));", stop.toString()); + assertEquals("return Phi(Loop,0,(Phi_sum+.i));", stop.toString()); assertEquals(45L, Evaluator.evaluate(stop, 10)); } |
