From 2f779dd115acf1fc99c7b3b416273fdb66ad48cb Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Sat, 19 Sep 2026 18:50:22 -0700 Subject: debug printers no longer call self-optimizing accessors --- .../main/java/com/seaofnodes/simple/codegen/CodeGen.java | 6 +++--- .../main/java/com/seaofnodes/simple/codegen/Encoding.java | 11 +++++++++-- .../src/main/java/com/seaofnodes/simple/codegen/Opto.java | 2 +- .../main/java/com/seaofnodes/simple/codegen/RegAlloc.java | 12 ++++++++++-- .../src/main/java/com/seaofnodes/simple/node/CallNode.java | 4 ++-- .../main/java/com/seaofnodes/simple/node/ConstantNode.java | 6 +++--- .../main/java/com/seaofnodes/simple/node/FunPtrNode.java | 2 +- .../main/java/com/seaofnodes/simple/node/MemMergeNode.java | 2 +- .../main/java/com/seaofnodes/simple/print/ASMPrinter.java | 13 +++++++------ .../main/java/com/seaofnodes/simple/type/TypeFunPtr.java | 2 +- .../main/java/com/seaofnodes/simple/type/TypeInteger.java | 4 ++-- 11 files changed, 40 insertions(+), 24 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 ca2cc955..2fccb5f3 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java @@ -378,8 +378,8 @@ public class CodeGen { public FunNode link( TypeFunPtr tfp ) { return link(tfp.fidx()); } // Read-only linker lookup, suitable for printers and debugger display. // In particular, do not lazily remove a partially dead function. - public FunNode lookupFun(int fidx) { return _linker.atX(fidx); } - public FunNode lookupFun(TypeFunPtr tfp) { return lookupFun(tfp.fidx()); } + public FunNode _link(int fidx) { return _linker.atX(fidx); } + public FunNode _link(TypeFunPtr tfp) { return _link(tfp.fidx()); } // Return the FunNode from a fidx public FunNode link( int fidx ) { FunNode fun =_linker.atX(fidx); @@ -409,7 +409,7 @@ public class CodeGen { public String externFunc(int fidx) { return _externFunc.get(fidx); } public String funcName(int fidx ) { - FunNode fun = link(fidx); + FunNode fun = _link(fidx); if( fun!=null ) return fun._name; return externFunc(fidx); } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/codegen/Encoding.java b/chapter25/src/main/java/com/seaofnodes/simple/codegen/Encoding.java index 48ca4335..618ec689 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/codegen/Encoding.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/codegen/Encoding.java @@ -46,17 +46,24 @@ public class Encoding { public static class Relo { public final Node _op; public final Type _t; // Constant type + public final int _align; // Log alignment, captured for diagnostic display + public final int _structSize; // Capture layout during encoding, not printing public final byte _off; // Offset from start of opcode public final byte _elf; // ELF relocation type, e.g. 2/PC32 public int _target; // Where constant is finally placed public int _opStart; // Opcode start Relo( Node op, Type t, byte off, byte elf ) { _op=op; _t=t; _off=off; _elf=elf; + _align = t.alignment(); + _structSize = t instanceof TypeStruct ts ? ts.size() : 0; + _readOnly = readOnly(t); } - public boolean readOnly() { + public boolean readOnly() { return _readOnly; } + private final boolean _readOnly; + private static boolean readOnly(Type t) { // Class initializers still write their fields, even when every // final value is constant. Their storage must remain writable. - return !(_t instanceof TypeStruct ts) || + return !(t instanceof TypeStruct ts) || (!Parser.startsClzPrefix(ts._name) && ts.isConstant()); } } 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 7c14965c..132705aa 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/codegen/Opto.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/codegen/Opto.java @@ -140,7 +140,7 @@ abstract public class Opto { // unlinkStart deliberately leaves uncalled functions in a // temporarily dead limbo. A newly discovered call revives them; // do not use the cleanup lookup which removes dead linker entries. - FunNode fun = code.lookupFun(fidx); + FunNode fun = code._link(fidx); // null here means an external function; i.e. this Call // calls to an outside library and all its arguments escape. if( fun != null && !call.linked(fun) ) { diff --git a/chapter25/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java b/chapter25/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java index 6650b19c..f8c96ff2 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java @@ -130,14 +130,22 @@ public class RegAlloc { } + // Diagnostic lookup: do not compress leaders or rewrite the node mapping. + private LRG _lrg(Node n) { + LRG lrg = _lrgs.get(n); + if( lrg != null ) + while( lrg._leader != null ) lrg = lrg._leader; + return lrg; + } + public short regnum( Node n ) { - LRG lrg = lrg(n); + LRG lrg = _lrg(n); return lrg==null ? -1 : lrg._reg; } // Printable register number for node n String reg( Node n ) { - LRG lrg = lrg(n); + LRG lrg = _lrg(n); return lrg==null ? null : reg(lrg); } String reg( LRG lrg ) { 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 51d10702..c053f377 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/CallNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/CallNode.java @@ -38,8 +38,8 @@ public class CallNode extends CFGNode { return sb.append(")"); } public String name() { - if( fptr()._type instanceof TypeFunPtr tfp && tfp.isConstant() ) { - FunNode fun = CodeGen.CODE.lookupFun(tfp); + if( fptr()._type instanceof TypeFunPtr tfp && tfp._isConstant() && tfp.notNull() ) { + FunNode fun = CodeGen.CODE._link(tfp); if( fun !=null ) return fun._name; if( fptr() instanceof ExternNode ex ) return ex._extern; } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/ConstantNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/ConstantNode.java index feed8c5c..df2dc27b 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/ConstantNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ConstantNode.java @@ -45,7 +45,7 @@ public class ConstantNode extends TypeNode { CodeGen.CODE._phase.ordinal() > CodeGen.Phase.Opto.ordinal() ) return raw(type); if( type instanceof TypeFunPtr tfp && tfp.isConstant() ) { - FunNode fun = CodeGen.CODE.lookupFun(tfp); + FunNode fun = CodeGen.CODE._link(tfp); if( fun != null ) return new FunPtrNode(tfp,CodeGen.CODE._start,fun.ret()).init(); // TODO: A singleton FIDX can also emerge after merging and @@ -74,8 +74,8 @@ public class ConstantNode extends TypeNode { @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { - if( _con instanceof TypeFunPtr tfp && tfp.isConstant() ) { - FunNode fun = CodeGen.CODE.lookupFun(tfp); + if( _con instanceof TypeFunPtr tfp && tfp._isConstant() && tfp.notNull() ) { + FunNode fun = CodeGen.CODE._link(tfp); if( fun!=null && fun._name != null ) return sb.append("{ ").append(fun._name).append("}"); } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/FunPtrNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/FunPtrNode.java index ce53b073..7f0b2b7d 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/FunPtrNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/FunPtrNode.java @@ -35,7 +35,7 @@ public class FunPtrNode extends TypeNode { @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { - FunNode fun = CodeGen.CODE.lookupFun(((TypeFunPtr)_con).fidx()); + FunNode fun = CodeGen.CODE._link(((TypeFunPtr)_con).fidx()); return fun!=null && fun._name!=null ? sb.append("{ ").append(fun._name).append("}") : sb.append(_con); diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/MemMergeNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/MemMergeNode.java index 87d982f1..e16eee9e 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/MemMergeNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/MemMergeNode.java @@ -32,7 +32,7 @@ public class MemMergeNode extends Node { Node n = in(j); while( n instanceof ScopeNode loop ) { sb.append("Lazy_"); - n = loop.mem(j); + n = loop.mem(); } if( n==null ) sb.append("___ "); else n._print0(sb, visited).append(" "); diff --git a/chapter25/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java b/chapter25/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java index 7f9f3ad9..ff3eada2 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java @@ -8,7 +8,9 @@ import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.type.*; import com.seaofnodes.simple.util.*; import java.util.HashMap; -import java.util.HashSet; +import java.util.Collections; +import java.util.IdentityHashMap; +import java.util.Set; public abstract class ASMPrinter { @@ -43,16 +45,15 @@ public abstract class ASMPrinter { sb.p("--- ").p(msg).p(" ------").nl(); // radix sort the big constants by alignment Ary[] raligns = new Ary[5]; - for( Node op : bigCons.keySet() ) { - Relo relo = bigCons.get(op); + for( Relo relo : bigCons.values() ) { if( relo.readOnly() != ro ) continue; - int align = relo._t.alignment(); + int align = relo._align; Ary relos = raligns[align]==null ? (raligns[align]=new Ary<>( Relo.class)) : raligns[align]; relos.add(relo); } - HashSet targets = new HashSet<>(); + Set targets = Collections.newSetFromMap(new IdentityHashMap<>()); // By alignment int dadr=0; @@ -64,7 +65,7 @@ public abstract class ASMPrinter { targets.add(relo._t); sb.hex2(iadr+dadr).p(" "); if( relo._t instanceof TypeStruct ts ) { - int sz = ts.size(); + int sz = relo._structSize; int log = 1<