diff options
Diffstat (limited to 'chapter25')
7 files changed, 37 insertions, 7 deletions
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/codegen/Opto.java b/chapter25/src/main/java/com/seaofnodes/simple/codegen/Opto.java index 690ae3ad..6e00d02c 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/codegen/Opto.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/codegen/Opto.java @@ -304,7 +304,11 @@ abstract public class Opto { int mode = 0; for( int i=1; i<n.nIns(); i++ ) mode |= numericEvidence(n.in(i),visited); - assert mode != 0; + // A closed recursive numeric component can have no remaining + // concrete evidence after SCCP, e.g. dead all-integer loops. + // With no float evidence, settle to integer. + if( mode == 0 ) + mode = 1; if( mode != 0 ) { // If both evidence, FP wins modeNode.setMode((byte)((mode&2)==2 ? 2 : 1)).init(); @@ -330,8 +334,9 @@ abstract public class Opto { int evidence = 0; assert !(n instanceof ConvertNode); // No test case - assert !(n instanceof ModeNode); switch( n ) { + case ModeNode modeNode when modeNode.mode() != 0 -> { return modeNode.mode(); } + case ModeNode modeNode -> {} case PhiNode phi -> {} case ReturnNode ret -> {} case ProjNode proj when proj.in(0) instanceof CallEndNode cend -> { diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/ArithNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/ArithNode.java index 8c21aef7..995b4743 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/ArithNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ArithNode.java @@ -57,6 +57,8 @@ public abstract class ArithNode extends Node implements ModeNode { Type bad = null; for( int i=1; i<n.nIns(); i++ ) { Type t = n.in(i)._type; + if( t==null ) + return null; if( t.isHigh() ) return null; // A weak input is not evidence of a bad mode while the graph is @@ -97,6 +99,8 @@ public abstract class ArithNode extends Node implements ModeNode { @Override public final Type compute() { Type t1 = in(1)._type, t2 = in(2)._type; + if( t1==null || t2==null ) + return Type.TOP; if( t1.isHigh() || t2.isHigh() ) return _mode==0 ? Type.TOP : _mode==1 ? TypeInteger.TOP : diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/BoolNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/BoolNode.java index ef71983e..ac3b0bc0 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/BoolNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/BoolNode.java @@ -37,6 +37,8 @@ abstract public class BoolNode extends Node implements ModeNode { public TypeInteger compute() { Type t1 = in(1)._type; Type t2 = in(2)._type; + if( t1==null || t2==null ) + return BOOL; // Exactly equals? if( t1.isHigh() || t2.isHigh() ) return (TypeInteger)BOOL.dual(); @@ -79,6 +81,8 @@ abstract public class BoolNode extends Node implements ModeNode { return this instanceof LT ? CodeGen.CODE.ZERO : ConstantNode.make(TRUE); // Can we decide int vs flt? Type t1 = in(1)._type, t2 = in(2)._type; + if( t1==null || t2==null ) + return null; if( _mode==0 ) { byte mode = ArithNode.mode(t1,t2); if( mode!=0 ) return setMode(mode).init(); diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/CallNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/CallNode.java index 90d7e379..9ce97ac6 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/CallNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/CallNode.java @@ -153,11 +153,14 @@ public class CallNode extends CFGNode { fun.delDef(path); CodeGen.CODE.add(fun); CallEndNode cend = cend(); - ReturnNode ret = fun.ret().keep(); - cend.delDef(cend._inputs.find(ret)); - CodeGen.CODE.add(cend); + ReturnNode ret = fun.ret(); + if( cend != null ) { + ret.keep(); + cend.delDef(cend._inputs.find(ret)); + CodeGen.CODE.add(cend); + ret.unkeep(); + } assert !linked(fun); - ret.unkeep(); } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/MinusNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/MinusNode.java index 6101fba2..642fc2b2 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/MinusNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/MinusNode.java @@ -37,6 +37,8 @@ public class MinusNode extends Node implements ModeNode { @Override public Type compute() { Type t = in(1)._type; + if( t==null ) + return Type.TOP; if( t.isHigh() ) return _mode==0 ? Type.TOP : _mode==1 ? TypeInteger.TOP : diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter25Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter25Test.java index a5ef67e8..f5e3d752 100644 --- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter25Test.java +++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter25Test.java @@ -72,6 +72,17 @@ public class Chapter25Test { assertEquals("1",Eval2.eval(code,0)); } + @Test + public void testFuzzerUnresolvedNumericLoop() { + CodeGen code = new CodeGen(""" + arg=0; + while(arg+0) + while(-arg) + arg=0; + """).driver(CodeGen.Phase.TypeCheck); + assertEquals("return 0;",code.print()); + } + @Test @Ignore public void testModule0() throws IOException { String MODDIR = "src/test/java/com/seaofnodes/simple/test0"; diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Eval2.java b/chapter25/src/test/java/com/seaofnodes/simple/Eval2.java index 715c499e..ea4ec326 100644 --- a/chapter25/src/test/java/com/seaofnodes/simple/Eval2.java +++ b/chapter25/src/test/java/com/seaofnodes/simple/Eval2.java @@ -148,7 +148,7 @@ public abstract class Eval2 { // Evaluate until exit or timeout. Each outer loop step computes // all data nodes under some new Control. while( true ) { - assert BB!=null; + if( BB==null ) return null; traceCtrl(BB,trace); if( trace!=null ) System.out.println(F.p()); @@ -177,6 +177,7 @@ public abstract class Eval2 { case RegionNode r : break; default: throw Utils.TODO(); } + if( BB==null ) return null; assert !BB.isDead(); } } |
