From 6e59fc1b71f2098c8baf90a6c54e5a33b7291e94 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Sat, 19 Sep 2026 22:31:42 -0700 Subject: Unify mixed-return checking and results Unify dominator caching. --- .../main/java/com/seaofnodes/simple/GlobalCodeMotion.java | 4 ++-- .../src/main/java/com/seaofnodes/simple/node/CFGNode.java | 15 +++++++++++---- .../main/java/com/seaofnodes/simple/node/LoopNode.java | 2 +- .../main/java/com/seaofnodes/simple/node/RegionNode.java | 11 +++++------ .../main/java/com/seaofnodes/simple/node/StopNode.java | 2 +- 5 files changed, 20 insertions(+), 14 deletions(-) (limited to 'chapter11/src/main/java') diff --git a/chapter11/src/main/java/com/seaofnodes/simple/GlobalCodeMotion.java b/chapter11/src/main/java/com/seaofnodes/simple/GlobalCodeMotion.java index 14540d46..99f2f0ea 100644 --- a/chapter11/src/main/java/com/seaofnodes/simple/GlobalCodeMotion.java +++ b/chapter11/src/main/java/com/seaofnodes/simple/GlobalCodeMotion.java @@ -148,7 +148,7 @@ public abstract class GlobalCodeMotion { assert early != null; CFGNode lca = null; for( Node use : n._outputs ) - lca = use_block(n,use, late).idom(lca); + lca = use_block(n,use, late).domLCA(lca); // Loads may need anti-dependencies, raising their LCA if( n instanceof LoadNode load ) @@ -226,7 +226,7 @@ public abstract class GlobalCodeMotion { for( ; stblk != defblk.idom(); stblk = stblk.idom() ) { // Store and Load overlap, need anti-dependence if( stblk._anti==load._nid ) { - lca = stblk.idom(lca); // Raise Loads LCA + lca = stblk.domLCA(lca); // Raise Loads LCA if( lca == stblk && st != null && Utils.find(st._inputs,load) == -1 ) // And if something moved, st.addDef(load); // Add anti-dep as well return lca; // Cap this stores' anti-dep to here diff --git a/chapter11/src/main/java/com/seaofnodes/simple/node/CFGNode.java b/chapter11/src/main/java/com/seaofnodes/simple/node/CFGNode.java index b605071b..e02dd1e1 100644 --- a/chapter11/src/main/java/com/seaofnodes/simple/node/CFGNode.java +++ b/chapter11/src/main/java/com/seaofnodes/simple/node/CFGNode.java @@ -48,18 +48,25 @@ public abstract class CFGNode extends Node { *

* See {@link ...} */ - public int _idepth; - public int idepth() { return _idepth==0 ? (_idepth=idom().idepth()+1) : _idepth; } + public char _idepth; + public int idepth() { return _idepth!=0 ? _idepth : cacheIDepth(idom().idepth()+1); } + // Zero depth means uncached. Check before narrowing so overflow cannot wrap. + final int cacheIDepth(int depth) { + assert 0 <= depth && depth <= Character.MAX_VALUE : "Dominator depth exceeds 65535"; + return _idepth = (char)depth; + } + // Return the immediate dominator of this Node and compute dom tree depth. public CFGNode idom() { return cfg(0); } // Return the LCA of two idoms - public CFGNode idom(CFGNode rhs) { + public CFGNode domLCA(CFGNode rhs) { if( rhs==null ) return this; CFGNode lhs = this; while( lhs != rhs ) { - var comp = lhs.idepth() - rhs.idepth(); + if( lhs==null || rhs==null ) return null; + int comp = lhs.idepth() - rhs.idepth(); if( comp >= 0 ) lhs = lhs.idom(); if( comp <= 0 ) rhs = rhs.idom(); } diff --git a/chapter11/src/main/java/com/seaofnodes/simple/node/LoopNode.java b/chapter11/src/main/java/com/seaofnodes/simple/node/LoopNode.java index c662dee6..45549f1d 100644 --- a/chapter11/src/main/java/com/seaofnodes/simple/node/LoopNode.java +++ b/chapter11/src/main/java/com/seaofnodes/simple/node/LoopNode.java @@ -28,7 +28,7 @@ public class LoopNode extends RegionNode { } // Bypass Region idom, same as the default idom() using use in(1) instead of in(0) - @Override public int idepth() { return _idepth==0 ? (_idepth=idom().idepth()+1) : _idepth; } + @Override public int idepth() { return _idepth!=0 ? _idepth : cacheIDepth(entry().idepth()+1); } // Bypass Region idom, same as the default idom() using use in(1) instead of in(0) @Override public CFGNode idom() { return entry(); } diff --git a/chapter11/src/main/java/com/seaofnodes/simple/node/RegionNode.java b/chapter11/src/main/java/com/seaofnodes/simple/node/RegionNode.java index dcc7ccef..060dfb45 100644 --- a/chapter11/src/main/java/com/seaofnodes/simple/node/RegionNode.java +++ b/chapter11/src/main/java/com/seaofnodes/simple/node/RegionNode.java @@ -92,19 +92,18 @@ public class RegionNode extends CFGNode { // Immediate dominator of Region is a little more complicated. @Override public int idepth() { if( _idepth!=0 ) return _idepth; - int d=0; + int depth=0; for( Node n : _inputs ) if( n!=null ) - d = Math.max(d,((CFGNode)n).idepth()+1); - return _idepth=d; + depth = Math.max(depth,((CFGNode)n).idepth()+1); + return cacheIDepth(depth); } @Override public CFGNode idom() { CFGNode lca = null; - // Walk the LHS & RHS idom trees in parallel until they match, or either fails. - // Because this does not cache, it can be linear in the size of the program. + // Recompute from predecessors: CFG edits can change the dominator. for( int i=1; i