From 695429df954b084d2226fe2a6c1a47e1861bcc01 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Tue, 22 Sep 2026 16:02:08 -0700 Subject: int fallbacks for int ops all chapters, a little sharper for int ops --- .../src/main/java/com/seaofnodes/simple/node/AddNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/BoolNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/DivNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/MinusNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/MulNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/NotNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/SubNode.java | 2 +- chapter05/README.md | 4 ++++ .../src/main/java/com/seaofnodes/simple/node/AddNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/BoolNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/DivNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/MinusNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/MulNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/NotNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/PhiNode.java | 5 ++++- .../src/main/java/com/seaofnodes/simple/node/SubNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/AddNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/BoolNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/DivNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/MinusNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/MulNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/NotNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/SubNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/AddNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/BoolNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/DivNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/MinusNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/MulNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/NotNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/SubNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/AddNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/BoolNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/DivNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/MinusNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/MulNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/NotNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/SubNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/AddNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/BoolNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/DivNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/MinusNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/MulNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/NotNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/SubNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/AddNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/BoolNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/DivNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/MinusNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/MulNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/NotNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/SubNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/AddNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/BoolNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/DivNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/MinusNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/MulNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/NotNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/SubNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/AddNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/DivNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/MinusNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/MulNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/NotNode.java | 6 ++++-- .../src/main/java/com/seaofnodes/simple/node/SubNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/AddNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/DivNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/MinusNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/MulNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/NotNode.java | 6 ++++-- .../src/main/java/com/seaofnodes/simple/node/SubNode.java | 10 +++++++--- .../src/main/java/com/seaofnodes/simple/node/MinusNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/NotNode.java | 5 +++-- .../src/main/java/com/seaofnodes/simple/node/MinusNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/NotNode.java | 5 +++-- .../src/main/java/com/seaofnodes/simple/node/MinusNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/NotNode.java | 5 +++-- .../src/main/java/com/seaofnodes/simple/node/MinusNode.java | 2 +- .../src/main/java/com/seaofnodes/simple/node/NotNode.java | 3 ++- docs/chapter-backports.md | 1 + graph/README.md | 9 +++++++++ 80 files changed, 245 insertions(+), 128 deletions(-) diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/AddNode.java b/chapter04/src/main/java/com/seaofnodes/simple/node/AddNode.java index f568416c..0291a900 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/AddNode.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/node/AddNode.java @@ -23,7 +23,7 @@ public class AddNode extends Node { return TypeInteger.constant(i0.value()+i1.value()); return i0.meet(i1); } - return Type.BOTTOM; + return TypeInteger.BOT; } @Override diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/BoolNode.java b/chapter04/src/main/java/com/seaofnodes/simple/node/BoolNode.java index af0d22b7..143a6fde 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/BoolNode.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/node/BoolNode.java @@ -29,7 +29,7 @@ abstract public class BoolNode extends Node { return TypeInteger.constant(doOp(i0.value(), i1.value()) ? 1 : 0); return i0.meet(i1); } - return Type.BOTTOM; + return TypeInteger.BOT; } abstract boolean doOp(long lhs, long rhs); diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/DivNode.java b/chapter04/src/main/java/com/seaofnodes/simple/node/DivNode.java index c7276710..bffa4b44 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/DivNode.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/node/DivNode.java @@ -25,7 +25,7 @@ public class DivNode extends Node { : TypeInteger.constant(i0.value()/i1.value()); return i0.meet(i1); } - return Type.BOTTOM; + return TypeInteger.BOT; } @Override diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/MinusNode.java b/chapter04/src/main/java/com/seaofnodes/simple/node/MinusNode.java index b83c41a5..ad6e513a 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/MinusNode.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/node/MinusNode.java @@ -18,7 +18,7 @@ public class MinusNode extends Node { public Type compute() { if (in(1)._type instanceof TypeInteger i0) return i0.isConstant() ? TypeInteger.constant(-i0.value()) : i0; - return Type.BOTTOM; + return TypeInteger.BOT; } @Override diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/MulNode.java b/chapter04/src/main/java/com/seaofnodes/simple/node/MulNode.java index 68ba9025..60103b8b 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/MulNode.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/node/MulNode.java @@ -23,7 +23,7 @@ public class MulNode extends Node { return TypeInteger.constant(i0.value()*i1.value()); return i0.meet(i1); } - return Type.BOTTOM; + return TypeInteger.BOT; } @Override diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/NotNode.java b/chapter04/src/main/java/com/seaofnodes/simple/node/NotNode.java index 83c63244..6a56ff64 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/NotNode.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/node/NotNode.java @@ -18,7 +18,7 @@ public class NotNode extends Node { public Type compute() { if( in(1)._type instanceof TypeInteger i0 ) return i0.isConstant() ? TypeInteger.constant(i0.value()==0 ? 1 : 0) : i0; - return Type.BOTTOM; + return TypeInteger.BOT; } @Override diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/SubNode.java b/chapter04/src/main/java/com/seaofnodes/simple/node/SubNode.java index c12e7388..f5ad663d 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/SubNode.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/node/SubNode.java @@ -27,7 +27,7 @@ public class SubNode extends Node { return TypeInteger.constant(i0.value()-i1.value()); return i0.meet(i1); } - return Type.BOTTOM; + return TypeInteger.BOT; } @Override diff --git a/chapter05/README.md b/chapter05/README.md index 7337da33..2732066e 100644 --- a/chapter05/README.md +++ b/chapter05/README.md @@ -83,6 +83,10 @@ one for each of the control inputs to that `Region`. The result computed by a control input to the `Region` can be active at a time, and the `Phi` passes through the data value from the matching input.[^1] +Its type is the meet of its data-input types. Two different integer constants +merge to `TypeInteger.BOT`: the value is unknown, but it is still an integer. +Integer arithmetic likewise retains an integer result type when it cannot fold. + #### `RegionNode` In this Sea of Nodes, there is an embedded Control Flow Graph - and like a diff --git a/chapter05/src/main/java/com/seaofnodes/simple/node/AddNode.java b/chapter05/src/main/java/com/seaofnodes/simple/node/AddNode.java index 0600222a..2772c4c5 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/AddNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/AddNode.java @@ -23,7 +23,7 @@ public class AddNode extends Node { return TypeInteger.constant(i0.value()+i1.value()); return i0.meet(i1); } - return Type.BOTTOM; + return TypeInteger.BOT; } @Override diff --git a/chapter05/src/main/java/com/seaofnodes/simple/node/BoolNode.java b/chapter05/src/main/java/com/seaofnodes/simple/node/BoolNode.java index f5db6574..87acc6cc 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/BoolNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/BoolNode.java @@ -29,7 +29,7 @@ abstract public class BoolNode extends Node { return TypeInteger.constant(doOp(i0.value(), i1.value()) ? 1 : 0); return i0.meet(i1); } - return Type.BOTTOM; + return TypeInteger.BOT; } abstract boolean doOp(long lhs, long rhs); diff --git a/chapter05/src/main/java/com/seaofnodes/simple/node/DivNode.java b/chapter05/src/main/java/com/seaofnodes/simple/node/DivNode.java index 1bb04be7..f80f092d 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/DivNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/DivNode.java @@ -25,7 +25,7 @@ public class DivNode extends Node { : TypeInteger.constant(i0.value()/i1.value()); return i0.meet(i1); } - return Type.BOTTOM; + return TypeInteger.BOT; } @Override diff --git a/chapter05/src/main/java/com/seaofnodes/simple/node/MinusNode.java b/chapter05/src/main/java/com/seaofnodes/simple/node/MinusNode.java index b83c41a5..ad6e513a 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/MinusNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/MinusNode.java @@ -18,7 +18,7 @@ public class MinusNode extends Node { public Type compute() { if (in(1)._type instanceof TypeInteger i0) return i0.isConstant() ? TypeInteger.constant(-i0.value()) : i0; - return Type.BOTTOM; + return TypeInteger.BOT; } @Override diff --git a/chapter05/src/main/java/com/seaofnodes/simple/node/MulNode.java b/chapter05/src/main/java/com/seaofnodes/simple/node/MulNode.java index 46ee6058..b1d9e44a 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/MulNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/MulNode.java @@ -23,7 +23,7 @@ public class MulNode extends Node { return TypeInteger.constant(i0.value()*i1.value()); return i0.meet(i1); } - return Type.BOTTOM; + return TypeInteger.BOT; } @Override diff --git a/chapter05/src/main/java/com/seaofnodes/simple/node/NotNode.java b/chapter05/src/main/java/com/seaofnodes/simple/node/NotNode.java index 83c63244..6a56ff64 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/NotNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/NotNode.java @@ -18,7 +18,7 @@ public class NotNode extends Node { public Type compute() { if( in(1)._type instanceof TypeInteger i0 ) return i0.isConstant() ? TypeInteger.constant(i0.value()==0 ? 1 : 0) : i0; - return Type.BOTTOM; + return TypeInteger.BOT; } @Override diff --git a/chapter05/src/main/java/com/seaofnodes/simple/node/PhiNode.java b/chapter05/src/main/java/com/seaofnodes/simple/node/PhiNode.java index 95c0fdf9..b3b5462d 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/PhiNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/PhiNode.java @@ -24,7 +24,10 @@ public class PhiNode extends Node { @Override public Type compute() { - return Type.BOTTOM; + Type t = in(1)._type; + for( int i=2; itop, bot->bot, null->1, *void->0, not-null ptr->0, ptr/nil->bot // If input in null then true @@ -33,7 +35,7 @@ public class NotNode extends Node { if( t0.getClass() != Type.class ) // Only doing NOT on ints and ptrs throw Utils.TODO(); - return t0==Type.TOP ? Type.TOP : Type.BOTTOM; + return t0==Type.TOP ? TypeInteger.TOP : TypeInteger.BOT; } } diff --git a/chapter12/src/main/java/com/seaofnodes/simple/node/SubNode.java b/chapter12/src/main/java/com/seaofnodes/simple/node/SubNode.java index c9d20ce0..d8538277 100644 --- a/chapter12/src/main/java/com/seaofnodes/simple/node/SubNode.java +++ b/chapter12/src/main/java/com/seaofnodes/simple/node/SubNode.java @@ -20,17 +20,21 @@ public class SubNode extends Node { @Override public Type compute() { + Type t1 = in(1)._type, t2 = in(2)._type; + if( t1==Type.TOP || t1==TypeInteger.TOP || + t2==Type.TOP || t2==TypeInteger.TOP ) + return TypeInteger.TOP; // Sub of same is 0 if( in(1)==in(2) ) return TypeInteger.ZERO; - if (in(1)._type instanceof TypeInteger i0 && - in(2)._type instanceof TypeInteger i1) { + if (t1 instanceof TypeInteger i0 && + t2 instanceof TypeInteger i1) { if (i0.isConstant() && i1.isConstant()) return TypeInteger.constant(i0.value()-i1.value()); } - return in(1)._type.meet(in(2)._type); + return TypeInteger.BOT; } @Override diff --git a/chapter13/src/main/java/com/seaofnodes/simple/node/AddNode.java b/chapter13/src/main/java/com/seaofnodes/simple/node/AddNode.java index 1c4b94f8..eb1bd073 100644 --- a/chapter13/src/main/java/com/seaofnodes/simple/node/AddNode.java +++ b/chapter13/src/main/java/com/seaofnodes/simple/node/AddNode.java @@ -19,12 +19,16 @@ public class AddNode extends Node { @Override public Type compute() { - if( in(1)._type instanceof TypeInteger i0 && - in(2)._type instanceof TypeInteger i1 ) { + Type t1 = in(1)._type, t2 = in(2)._type; + if( t1==Type.TOP || t1==TypeInteger.TOP || + t2==Type.TOP || t2==TypeInteger.TOP ) + return TypeInteger.TOP; + if( t1 instanceof TypeInteger i0 && + t2 instanceof TypeInteger i1 ) { if (i0.isConstant() && i1.isConstant()) return TypeInteger.constant(i0.value()+i1.value()); } - return in(1)._type.meet(in(2)._type); + return TypeInteger.BOT; } @Override diff --git a/chapter13/src/main/java/com/seaofnodes/simple/node/DivNode.java b/chapter13/src/main/java/com/seaofnodes/simple/node/DivNode.java index ae73284f..bc9ff7d9 100644 --- a/chapter13/src/main/java/com/seaofnodes/simple/node/DivNode.java +++ b/chapter13/src/main/java/com/seaofnodes/simple/node/DivNode.java @@ -19,14 +19,18 @@ public class DivNode extends Node { @Override public Type compute() { - if (in(1)._type instanceof TypeInteger i0 && - in(2)._type instanceof TypeInteger i1) { + Type t1 = in(1)._type, t2 = in(2)._type; + if( t1==Type.TOP || t1==TypeInteger.TOP || + t2==Type.TOP || t2==TypeInteger.TOP ) + return TypeInteger.TOP; + if (t1 instanceof TypeInteger i0 && + t2 instanceof TypeInteger i1) { if (i0.isConstant() && i1.isConstant()) return i1.value() == 0 ? TypeInteger.ZERO : TypeInteger.constant(i0.value()/i1.value()); } - return in(1)._type.meet(in(2)._type); + return TypeInteger.BOT; } @Override diff --git a/chapter13/src/main/java/com/seaofnodes/simple/node/MinusNode.java b/chapter13/src/main/java/com/seaofnodes/simple/node/MinusNode.java index 0f2669b9..c3be733c 100644 --- a/chapter13/src/main/java/com/seaofnodes/simple/node/MinusNode.java +++ b/chapter13/src/main/java/com/seaofnodes/simple/node/MinusNode.java @@ -20,7 +20,7 @@ public class MinusNode extends Node { public Type compute() { if (in(1)._type instanceof TypeInteger i0) return i0.isConstant() ? TypeInteger.constant(-i0.value()) : i0; - return TypeInteger.TOP.meet(in(1)._type); + return in(1)._type==Type.TOP ? TypeInteger.TOP : TypeInteger.BOT; } @Override diff --git a/chapter13/src/main/java/com/seaofnodes/simple/node/MulNode.java b/chapter13/src/main/java/com/seaofnodes/simple/node/MulNode.java index e631492c..4cd075e4 100644 --- a/chapter13/src/main/java/com/seaofnodes/simple/node/MulNode.java +++ b/chapter13/src/main/java/com/seaofnodes/simple/node/MulNode.java @@ -19,12 +19,16 @@ public class MulNode extends Node { @Override public Type compute() { - if (in(1)._type instanceof TypeInteger i0 && - in(2)._type instanceof TypeInteger i1) { + Type t1 = in(1)._type, t2 = in(2)._type; + if( t1==Type.TOP || t1==TypeInteger.TOP || + t2==Type.TOP || t2==TypeInteger.TOP ) + return TypeInteger.TOP; + if (t1 instanceof TypeInteger i0 && + t2 instanceof TypeInteger i1) { if (i0.isConstant() && i1.isConstant()) return TypeInteger.constant(i0.value()*i1.value()); } - return in(1)._type.meet(in(2)._type); + return TypeInteger.BOT; } @Override diff --git a/chapter13/src/main/java/com/seaofnodes/simple/node/NotNode.java b/chapter13/src/main/java/com/seaofnodes/simple/node/NotNode.java index e987bd82..bb7e9265 100644 --- a/chapter13/src/main/java/com/seaofnodes/simple/node/NotNode.java +++ b/chapter13/src/main/java/com/seaofnodes/simple/node/NotNode.java @@ -20,7 +20,9 @@ public class NotNode extends Node { Type t0 = in(1)._type; switch( t0 ) { case TypeInteger i0: return i0.isConstant() ? TypeInteger.constant(i0.value()==0 ? 1 : 0) : i0; - case TypeFloat i0: return i0.isConstant() ? TypeInteger.constant(i0.value()==0 ? 1 : 0) : i0; + case TypeFloat i0: + if( i0==TypeFloat.TOP ) return TypeInteger.TOP; + return i0.isConstant() ? TypeInteger.constant(i0.value()==0 ? 1 : 0) : TypeInteger.BOT; case TypeMemPtr p0: // top->top, bot->bot, null->1, *void->0, not-null ptr->0, ptr/nil->bot // If input in null then true @@ -33,7 +35,7 @@ public class NotNode extends Node { if( t0.getClass() != Type.class ) // Only doing NOT on ints and ptrs throw Utils.TODO(); - return t0==Type.TOP ? Type.TOP : Type.BOTTOM; + return t0==Type.TOP ? TypeInteger.TOP : TypeInteger.BOT; } } diff --git a/chapter13/src/main/java/com/seaofnodes/simple/node/SubNode.java b/chapter13/src/main/java/com/seaofnodes/simple/node/SubNode.java index 467d9181..4b860c37 100644 --- a/chapter13/src/main/java/com/seaofnodes/simple/node/SubNode.java +++ b/chapter13/src/main/java/com/seaofnodes/simple/node/SubNode.java @@ -20,17 +20,21 @@ public class SubNode extends Node { @Override public Type compute() { + Type t1 = in(1)._type, t2 = in(2)._type; + if( t1==Type.TOP || t1==TypeInteger.TOP || + t2==Type.TOP || t2==TypeInteger.TOP ) + return TypeInteger.TOP; // Sub of same is 0 if( in(1)==in(2) ) return TypeInteger.ZERO; - if (in(1)._type instanceof TypeInteger i0 && - in(2)._type instanceof TypeInteger i1) { + if (t1 instanceof TypeInteger i0 && + t2 instanceof TypeInteger i1) { if (i0.isConstant() && i1.isConstant()) return TypeInteger.constant(i0.value()-i1.value()); } - return in(1)._type.meet(in(2)._type); + return TypeInteger.BOT; } @Override diff --git a/chapter14/src/main/java/com/seaofnodes/simple/node/MinusNode.java b/chapter14/src/main/java/com/seaofnodes/simple/node/MinusNode.java index 27b4a478..176d2a3d 100644 --- a/chapter14/src/main/java/com/seaofnodes/simple/node/MinusNode.java +++ b/chapter14/src/main/java/com/seaofnodes/simple/node/MinusNode.java @@ -24,7 +24,7 @@ public class MinusNode extends Node { if( i0 == TypeInteger.BOT || i0._min == Long.MIN_VALUE ) return TypeInteger.BOT; return TypeInteger.make(-i0._max,-i0._min); } - return TypeInteger.TOP.meet(in(1)._type); + return in(1)._type.isHigh() ? TypeInteger.TOP : TypeInteger.BOT; } @Override diff --git a/chapter14/src/main/java/com/seaofnodes/simple/node/NotNode.java b/chapter14/src/main/java/com/seaofnodes/simple/node/NotNode.java index 3ef5d19e..17b6e46e 100644 --- a/chapter14/src/main/java/com/seaofnodes/simple/node/NotNode.java +++ b/chapter14/src/main/java/com/seaofnodes/simple/node/NotNode.java @@ -21,7 +21,8 @@ public class NotNode extends Node { if( t0.isHigh() ) return TypeInteger.BOOL.dual(); switch( t0 ) { case TypeInteger i0: return i0._max < 0 || i0._min > 0 ? TypeInteger.FALSE : (i0==TypeInteger.ZERO ? TypeInteger.TRUE : TypeInteger.BOT); - case TypeFloat i0: return i0.isConstant() ? TypeInteger.constant(i0.value()==0 ? 1 : 0) : i0; + case TypeFloat i0: + return i0.isConstant() ? TypeInteger.constant(i0.value()==0 ? 1 : 0) : TypeInteger.BOT; case TypeMemPtr p0: // top->top, bot->bot, null->1, *void->0, not-null ptr->0, ptr/nil->bot // If input in null then true @@ -34,7 +35,7 @@ public class NotNode extends Node { if( t0.getClass() != Type.class ) // Only doing NOT on ints and ptrs throw Utils.TODO(); - return t0==Type.TOP ? Type.TOP : Type.BOTTOM; + return t0==Type.TOP ? TypeInteger.TOP : TypeInteger.BOT; } } diff --git a/chapter15/src/main/java/com/seaofnodes/simple/node/MinusNode.java b/chapter15/src/main/java/com/seaofnodes/simple/node/MinusNode.java index 7e95088f..63cfd110 100644 --- a/chapter15/src/main/java/com/seaofnodes/simple/node/MinusNode.java +++ b/chapter15/src/main/java/com/seaofnodes/simple/node/MinusNode.java @@ -22,7 +22,7 @@ public class MinusNode extends Node { if( i0.isHigh() ) return TypeInteger.TOP; return i0==TypeInteger.BOT ? TypeInteger.BOT : TypeInteger.make(-i0._max,-i0._min); } - return TypeInteger.TOP.meet(in(1)._type); + return in(1)._type.isHigh() ? TypeInteger.TOP : TypeInteger.BOT; } @Override diff --git a/chapter15/src/main/java/com/seaofnodes/simple/node/NotNode.java b/chapter15/src/main/java/com/seaofnodes/simple/node/NotNode.java index 3ef5d19e..17b6e46e 100644 --- a/chapter15/src/main/java/com/seaofnodes/simple/node/NotNode.java +++ b/chapter15/src/main/java/com/seaofnodes/simple/node/NotNode.java @@ -21,7 +21,8 @@ public class NotNode extends Node { if( t0.isHigh() ) return TypeInteger.BOOL.dual(); switch( t0 ) { case TypeInteger i0: return i0._max < 0 || i0._min > 0 ? TypeInteger.FALSE : (i0==TypeInteger.ZERO ? TypeInteger.TRUE : TypeInteger.BOT); - case TypeFloat i0: return i0.isConstant() ? TypeInteger.constant(i0.value()==0 ? 1 : 0) : i0; + case TypeFloat i0: + return i0.isConstant() ? TypeInteger.constant(i0.value()==0 ? 1 : 0) : TypeInteger.BOT; case TypeMemPtr p0: // top->top, bot->bot, null->1, *void->0, not-null ptr->0, ptr/nil->bot // If input in null then true @@ -34,7 +35,7 @@ public class NotNode extends Node { if( t0.getClass() != Type.class ) // Only doing NOT on ints and ptrs throw Utils.TODO(); - return t0==Type.TOP ? Type.TOP : Type.BOTTOM; + return t0==Type.TOP ? TypeInteger.TOP : TypeInteger.BOT; } } diff --git a/chapter16/src/main/java/com/seaofnodes/simple/node/MinusNode.java b/chapter16/src/main/java/com/seaofnodes/simple/node/MinusNode.java index 7e95088f..63cfd110 100644 --- a/chapter16/src/main/java/com/seaofnodes/simple/node/MinusNode.java +++ b/chapter16/src/main/java/com/seaofnodes/simple/node/MinusNode.java @@ -22,7 +22,7 @@ public class MinusNode extends Node { if( i0.isHigh() ) return TypeInteger.TOP; return i0==TypeInteger.BOT ? TypeInteger.BOT : TypeInteger.make(-i0._max,-i0._min); } - return TypeInteger.TOP.meet(in(1)._type); + return in(1)._type.isHigh() ? TypeInteger.TOP : TypeInteger.BOT; } @Override diff --git a/chapter16/src/main/java/com/seaofnodes/simple/node/NotNode.java b/chapter16/src/main/java/com/seaofnodes/simple/node/NotNode.java index 9e4cc324..38c6c90e 100644 --- a/chapter16/src/main/java/com/seaofnodes/simple/node/NotNode.java +++ b/chapter16/src/main/java/com/seaofnodes/simple/node/NotNode.java @@ -21,7 +21,8 @@ public class NotNode extends Node { if( t0.isHigh() ) return TypeInteger.BOOL.dual(); switch( t0 ) { case TypeInteger i0: return i0._max < 0 || i0._min > 0 ? TypeInteger.FALSE : (i0==TypeInteger.ZERO ? TypeInteger.TRUE : TypeInteger.BOOL); - case TypeFloat i0: return i0.isConstant() ? TypeInteger.constant(i0.value()==0 ? 1 : 0) : i0; + case TypeFloat i0: + return i0.isConstant() ? TypeInteger.constant(i0.value()==0 ? 1 : 0) : TypeInteger.BOT; case TypeMemPtr p0: // top->top, bot->bot, null->1, *void->0, not-null ptr->0, ptr/nil->bot // If input in null then true @@ -34,7 +35,7 @@ public class NotNode extends Node { if( t0.getClass() != Type.class ) // Only doing NOT on ints and ptrs throw Utils.TODO(); - return t0==Type.TOP ? Type.TOP : Type.BOTTOM; + return t0==Type.TOP ? TypeInteger.TOP : TypeInteger.BOT; } } diff --git a/chapter17/src/main/java/com/seaofnodes/simple/node/MinusNode.java b/chapter17/src/main/java/com/seaofnodes/simple/node/MinusNode.java index 50377061..a9e21814 100644 --- a/chapter17/src/main/java/com/seaofnodes/simple/node/MinusNode.java +++ b/chapter17/src/main/java/com/seaofnodes/simple/node/MinusNode.java @@ -25,7 +25,7 @@ public class MinusNode extends Node { return TypeInteger.BOT; return TypeInteger.make(-i0._max,-i0._min); } - return TypeInteger.TOP.meet(in(1)._type); + return in(1)._type.isHigh() ? TypeInteger.TOP : TypeInteger.BOT; } @Override 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 cca84a2d..3f4b291c 100644 --- a/chapter17/src/main/java/com/seaofnodes/simple/node/NotNode.java +++ b/chapter17/src/main/java/com/seaofnodes/simple/node/NotNode.java @@ -21,7 +21,8 @@ public class NotNode extends Node { if( t0.isHigh() ) return TypeInteger.BOOL.dual(); switch( t0 ) { case TypeInteger i0: return i0._max < 0 || i0._min > 0 ? TypeInteger.FALSE : (i0==TypeInteger.ZERO ? TypeInteger.TRUE : TypeInteger.BOOL); - case TypeFloat i0: return i0.isConstant() ? TypeInteger.constant(i0.value()==0 ? 1 : 0) : i0; + case TypeFloat i0: + return i0.isConstant() ? TypeInteger.constant(i0.value()==0 ? 1 : 0) : TypeInteger.BOOL; case TypeMemPtr p0: // top->top, bot->bot, null->1, *void->0, not-null ptr->0, ptr/nil->bot // If input in null then true diff --git a/docs/chapter-backports.md b/docs/chapter-backports.md index 150afe20..650d7c26 100644 --- a/docs/chapter-backports.md +++ b/docs/chapter-backports.md @@ -218,6 +218,7 @@ Unresolved reproductions have been promoted to the pending queue above. | Completed work | Scope and evidence retained | |---|---| +| Integer result types | Integer-op fallbacks in 4-13 and remaining unary cases through 17 retain integer types; 5's Phis meet their data-input types. Full Make suites in 4-17 passed, plus a chapter 5 snapshot check of Phi/Add types. Integer BOT starts in 4; later arithmetic already has typed fallbacks, with unresolved bimorphic modes preserved in 25. | | B14 cyclic leaf-kind equality | 23-24 backport; 25 already correct. Cyclic equality starts in 23. `TypeTest.testCyclicLeafKinds` fails before the fix; earlier interned-child equality already checks kinds. Full affected suites passed. | | B13 / #246 null guards | Nested Not/null guard discovery from 10; short-circuit Phi availability in 23-24. Regression and full suites in 10-25 passed. Separate null-dereference diagnostic remains queued. | | B09 and #251 debug printing | Side-effect-free print/accessor paths from their first applicable chapters; `_` diagnostic naming, type interning allowed, layouts forbidden. Dead nodes use `isDead()`, not null `_inputs`, from 7. Original-printer negative checks and full affected suites passed. | diff --git a/graph/README.md b/graph/README.md index b98ca9d3..eb3e8d18 100644 --- a/graph/README.md +++ b/graph/README.md @@ -178,6 +178,15 @@ ordering are follow-up work, along with preserving positions across rewrites. Each visited frame currently retains a full snapshot and layout; bounded history, checkpoints and deltas are also follow-up work. +Pending graph work: + +- Improve CFG placement with compiler-provided RPO and nested regions for + compilation units, functions and loops. +- Preserve positions across peepholes, then animate edits and zoom into the + peep neighborhood before returning to the whole graph. +- For large compilations, add checkpoints and forward deltas with a bounded + cache of recent backward steps. + ELK runs locally from the pinned elkjs 0.12.0 worker; see [`web/vendor/elk-README.md`](web/vendor/elk-README.md) for provenance and licensing. No npm or Maven step is needed to use it. -- cgit v1.2.3