From ccd14c5901c5eff7a4be463bf7cdd91b03e1ca38 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Mon, 14 Sep 2026 10:39:24 -0700 Subject: int-only ops force inputs to be int-only Lest an int-only op, having lifted result types to int, get a zero-fold (e.g. X^0) to their mode-not-set input and have types fall. Handle idepth-cache overflow --- .../com/seaofnodes/simple/codegen/CodeGen.java | 26 +++++++++++++++++----- .../java/com/seaofnodes/simple/node/AndNode.java | 3 ++- .../java/com/seaofnodes/simple/node/ArithNode.java | 12 ++++++++++ .../java/com/seaofnodes/simple/node/MinusNode.java | 3 ++- .../java/com/seaofnodes/simple/node/OrNode.java | 3 ++- .../com/seaofnodes/simple/node/RegionNode.java | 3 ++- .../java/com/seaofnodes/simple/node/SarNode.java | 3 ++- .../java/com/seaofnodes/simple/node/ShlNode.java | 2 +- .../java/com/seaofnodes/simple/node/ShrNode.java | 2 +- .../java/com/seaofnodes/simple/node/XorNode.java | 3 ++- 10 files changed, 46 insertions(+), 14 deletions(-) (limited to 'chapter25/src/main/java/com/seaofnodes') diff --git a/chapter25/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java b/chapter25/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java index 24a12e6d..ca2cc955 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java @@ -342,19 +342,23 @@ public class CodeGen { // idepths are cached and valid until *inserting* CFG edges (deleting is // OK). This happens with inlining, which bumps the version to bulk // invalidate the idepth caches. + private static final int IDEPTH_STRIDE = 1_000_000; private int _iDepthVersion = 0; - public void invalidateIDepthCaches() { _iDepthVersion++; } + public void invalidateIDepthCaches() { + ++_iDepthVersion; + assert _iDepthVersion < IDEPTH_STRIDE; // Wrapped; needs a major hack to fix + } public boolean validIDepth(int idepth) { if( idepth==0 ) return false; if( _iDepthVersion==0 ) return true; - return (idepth%100)==_iDepthVersion; + return (idepth%IDEPTH_STRIDE)==_iDepthVersion; } public int iDepthAt(int idepth) { - return 100*idepth+_iDepthVersion; + return IDEPTH_STRIDE*idepth+_iDepthVersion; } public int iDepthFrom(int idepth) { assert idepth==0 || validIDepth(idepth); - return idepth+100; + return idepth+IDEPTH_STRIDE; } // Popular visit bitset, declared here, so it gets reused all over @@ -815,7 +819,7 @@ public class CodeGen { // need to be re-hooked to stop/start less they go dead. for( FunNode fun : _linker ) { // Already linked to start, not going dead - if( fun==null || fun.isDead() || fun._type.isHigh() ) + if( fun==null || fun.isDead() ) continue; // Imported functions are not emitted by this object. Unlink any @@ -854,7 +858,7 @@ public class CodeGen { ReturnNode ret = fun.ret(); StartNode start = fun._compunit._start; assert start!=null; - if( fun.in(1) != start ) { + if( fun.nIns() <= 1 || fun.in(1) != start ) { fun.insertDef(1,start); for( Node use : fun._outputs ) if( use instanceof ParmNode parm ) @@ -876,6 +880,16 @@ public class CodeGen { } } + _stop.walk(n -> { + if( n instanceof CallEndNode cend ) + for( int i=1; i> 3 >> (y ? 1 : 2) ==> x >> (y ? 4 : 5) diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/ShlNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/ShlNode.java index 459b26eb..24d9bdb4 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/ShlNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ShlNode.java @@ -33,7 +33,7 @@ public class ShlNode extends ArithNode { if( rhs._type instanceof TypeInteger shl && shl.isConstant() ) { // Shl of 0. - if( (shl.value()&63)==0 ) + if( (shl.value()&63)==0 && forceInt(lhs) ) return lhs; // (x + c) << i => (x << i) + (c << i) if( lhs instanceof AddNode add && addDep(add).in(2)._type instanceof TypeInteger c && c.isConstant() ) { diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/ShrNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/ShrNode.java index 5e4870d1..1bf7d118 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/ShrNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ShrNode.java @@ -23,7 +23,7 @@ public class ShrNode extends ArithNode { Type t2 = rhs._type; // Shr of 0. - if( t2.isConstant() && t2 instanceof TypeInteger i && (i.value()&63)==0 ) + if( t2.isConstant() && t2 instanceof TypeInteger i && (i.value()&63)==0 && forceInt(lhs) ) return lhs; // TODO: x >>> 3 >>> (y ? 1 : 2) ==> x >>> (y ? 4 : 5) diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/XorNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/XorNode.java index 95d4461e..27ebc3dc 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/XorNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/XorNode.java @@ -20,12 +20,13 @@ public class XorNode extends ArithNode { public Node idealize() { Node lhs = in(1); Node rhs = in(2); + Type t1 = lhs._type; Type t2 = rhs._type; // Xor of 0. We do not check for (0^x) because this will already // canonicalize to (x^0) - if( t2.isConstant() && t2 instanceof TypeInteger i && i.value()==0 ) + if( t2.isConstant() && t2 instanceof TypeInteger i && i.value()==0 && forceInt(lhs) ) return lhs; // Move constants to RHS: con*arg becomes arg*con -- cgit v1.2.3