From 5ea32e69433d0c850d02bbc1e6c4a260bc095fec Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Thu, 1 Oct 2026 12:01:57 -0700 Subject: Move debug printing into shared space Same as the graph viewer, moves a lot of code out of all Nodes --- .../java/com/seaofnodes/simple/node/ArithNode.java | 10 +- .../java/com/seaofnodes/simple/node/BoolNode.java | 10 +- .../java/com/seaofnodes/simple/node/CProjNode.java | 5 +- .../com/seaofnodes/simple/node/CallEndNode.java | 14 +- .../java/com/seaofnodes/simple/node/CallNode.java | 16 +- .../com/seaofnodes/simple/node/ConFldOffNode.java | 9 +- .../com/seaofnodes/simple/node/ConstantNode.java | 16 +- .../com/seaofnodes/simple/node/ConvertNode.java | 7 +- .../java/com/seaofnodes/simple/node/CtrlNode.java | 5 +- .../com/seaofnodes/simple/node/EscapeNode.java | 17 +- .../com/seaofnodes/simple/node/ExternNode.java | 1 - .../java/com/seaofnodes/simple/node/FRefNode.java | 8 +- .../com/seaofnodes/simple/node/FldOffNode.java | 9 +- .../com/seaofnodes/simple/node/FunPtrNode.java | 10 +- .../java/com/seaofnodes/simple/node/GuardNode.java | 8 +- .../java/com/seaofnodes/simple/node/IfNode.java | 13 +- .../java/com/seaofnodes/simple/node/LoadNode.java | 4 +- .../seaofnodes/simple/node/MachConcreteNode.java | 12 +- .../com/seaofnodes/simple/node/MemMergeNode.java | 19 +- .../java/com/seaofnodes/simple/node/MemOpNode.java | 6 +- .../java/com/seaofnodes/simple/node/MinusNode.java | 8 +- .../java/com/seaofnodes/simple/node/NeverNode.java | 5 +- .../java/com/seaofnodes/simple/node/NewNode.java | 8 +- .../main/java/com/seaofnodes/simple/node/Node.java | 70 +--- .../java/com/seaofnodes/simple/node/NotNode.java | 8 +- .../java/com/seaofnodes/simple/node/ParmNode.java | 19 +- .../java/com/seaofnodes/simple/node/PhiNode.java | 19 +- .../java/com/seaofnodes/simple/node/ProjNode.java | 11 +- .../com/seaofnodes/simple/node/PtrToIntNode.java | 6 +- .../com/seaofnodes/simple/node/ReadOnlyNode.java | 7 +- .../com/seaofnodes/simple/node/RegionNode.java | 7 +- .../com/seaofnodes/simple/node/ReturnNode.java | 13 +- .../com/seaofnodes/simple/node/RoundF32Node.java | 7 +- .../java/com/seaofnodes/simple/node/ScopeNode.java | 28 +- .../java/com/seaofnodes/simple/node/SplitNode.java | 13 +- .../java/com/seaofnodes/simple/node/StartNode.java | 8 +- .../java/com/seaofnodes/simple/node/StopNode.java | 13 +- .../java/com/seaofnodes/simple/node/StoreNode.java | 7 +- .../com/seaofnodes/simple/node/ToFloatNode.java | 7 +- .../java/com/seaofnodes/simple/node/XCtrlNode.java | 5 +- .../seaofnodes/simple/node/cpus/arm/MemOpARM.java | 5 +- .../seaofnodes/simple/node/cpus/arm/UJmpARM.java | 6 +- .../simple/node/cpus/riscv/BranchRISC.java | 19 +- .../seaofnodes/simple/node/cpus/riscv/ImmRISC.java | 9 +- .../simple/node/cpus/riscv/MemOpRISC.java | 5 +- .../simple/node/cpus/riscv/UJmpRISC.java | 5 +- .../simple/node/cpus/x86_64_v2/MemOpX86.java | 7 +- .../simple/node/cpus/x86_64_v2/StoreX86.java | 13 +- .../simple/node/cpus/x86_64_v2/UJmpX86.java | 6 +- .../com/seaofnodes/simple/print/ASMPrinter.java | 367 +++++---------------- .../com/seaofnodes/simple/print/IRPrinter.java | 329 +++--------------- .../simple/print/SimpleGraphAdapter.java | 42 +-- 52 files changed, 376 insertions(+), 905 deletions(-) (limited to 'chapter25/src/main/java/com') 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 bb370a56..bc47ebfc 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/ArithNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ArithNode.java @@ -1,12 +1,13 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.type.*; import com.seaofnodes.simple.util.BAOS; import com.seaofnodes.simple.util.Utils; -import java.util.BitSet; import java.util.HashMap; import java.util.IdentityHashMap; @@ -23,11 +24,8 @@ public abstract class ArithNode extends Node implements ModeNode { } abstract String op(); - @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { - in(1)._print0(sb.append("("), visited); - in(2)._print0(sb.append(op()), visited); - return sb.append(")"); + @Override protected ExprPrinter _print1(ExprPrinter p) { + return p.open().n(in(1)).p(op()).n(in(2)).close(); } abstract long doOp(long x, long y); 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 f720d02d..73e786e3 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/BoolNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/BoolNode.java @@ -1,11 +1,12 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.type.*; import com.seaofnodes.simple.util.BAOS; import com.seaofnodes.simple.util.Utils; -import java.util.BitSet; import java.util.HashMap; import java.util.IdentityHashMap; import static com.seaofnodes.simple.type.TypeInteger.*; @@ -23,11 +24,8 @@ abstract public class BoolNode extends Node implements ModeNode { abstract public String op(); // String opcode name - @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { - in(1)._print0(sb.append("("), visited); - in(2)._print0(sb.append(op()), visited); - return sb.append(")"); + @Override protected ExprPrinter _print1(ExprPrinter p) { + return p.open().n(in(1)).p(op()).n(in(2)).close(); } @Override diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/CProjNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/CProjNode.java index b74619a3..12fde6c0 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/CProjNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/CProjNode.java @@ -1,12 +1,13 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.codegen.Serialize; import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeTuple; import com.seaofnodes.simple.util.BAOS; -import java.util.BitSet; import java.util.HashMap; import java.util.IdentityHashMap; @@ -35,7 +36,7 @@ public class CProjNode extends CFGNode implements Proj { @Override public String label() { return _label; } - @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { return sb.append(_label); } + @Override protected ExprPrinter _print1(ExprPrinter p) { return p.p(_label); } @Override public boolean blockHead() { return true; } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/CallEndNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/CallEndNode.java index d2286c09..2e921301 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/CallEndNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/CallEndNode.java @@ -1,11 +1,12 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.type.*; import com.seaofnodes.simple.util.BAOS; -import java.util.BitSet; import java.util.HashMap; import java.util.IdentityHashMap; @@ -64,13 +65,12 @@ public class CallEndNode extends CFGNode implements MultiNode { } @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { - sb.append("cend( "); - sb.append( in(0) instanceof CallNode ? "Call, " : "----, "); + protected ExprPrinter _print1(ExprPrinter p) { + p.p("cend( "); + p.p( in(0) instanceof CallNode ? "Call, " : "----, "); for( int i=1; i strs, HashMap types, IdentityHashMap anodes ) { baos.packed1(nIns()); } static Node make( BAOS bais ) { return new CallNode(null,new Node[bais.packed1()]); } - @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { + @Override protected ExprPrinter _print1(ExprPrinter p) { String fname = name(); - if( fname == null ) fptr()._print0(sb,visited); - else sb.append(fname); - sb.append("( "); + if( fname == null ) p.n(fptr()); + else p.p(fname); + p.p("( "); for( int i=2; i _print1(ExprPrinter p) { + return p.p(label()); } @Override public Node idealize() { 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 1dc369d3..47a7bbf6 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/ConstantNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ConstantNode.java @@ -1,11 +1,12 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeFunPtr; import com.seaofnodes.simple.util.BAOS; -import java.util.BitSet; import java.util.HashMap; import java.util.IdentityHashMap; @@ -66,19 +67,22 @@ public class ConstantNode extends TypeNode { // own the constructor function; the class FunPtr does. public static ConstantNode seed( Type type ) { return new ConstantNode(type,true); } - @Override public String label() { return "#"+_con; } - @Override public String uniqueName() { return "Con_" + _nid; } + @Override protected String repeatName() { + return _con==null || _con.toString().length()<=32 ? null : uniqueName(); + } + + @Override public String label() { return "Con"; } @Override public Node copy() { return raw(this); } @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { + protected ExprPrinter _print1(ExprPrinter p) { 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("}"); + return p.p("{ ").p(fun._name).p("}"); } - return sb.append(_con==null ? "---" : _con.toString()); + return p.p(_con==null ? "---" : _con.toString()); } @Override public boolean isConst() { return true; } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/ConvertNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/ConvertNode.java index 4e8e93ce..4ee5521a 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/ConvertNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ConvertNode.java @@ -1,10 +1,11 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.type.*; -import java.util.BitSet; import java.util.HashMap; // Convert a value to an authoritative destination type. The destination is @@ -24,8 +25,8 @@ public class ConvertNode extends Node { public Node val() { return in(1); } @Override public String label() { return "Convert_"+_dst.str(); } - @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { - return val()._print0(sb.append(label()).append("("),visited).append(")"); + @Override protected ExprPrinter _print1(ExprPrinter p) { + return p.p(label()).open().n(val()).close(); } // The declaration fixes the result family during pessimistic parsing. diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/CtrlNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/CtrlNode.java index 39c95aa4..62140873 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/CtrlNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/CtrlNode.java @@ -1,15 +1,16 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.type.Type; -import java.util.BitSet; public class CtrlNode extends CFGNode { public CtrlNode() { super(CodeGen.CODE._start); } @Override public Tag serialTag() { throw com.seaofnodes.simple.util.Utils.TODO(); } @Override public String label() { return "Ctrl"; } - @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { return sb.append("Cctrl"); } + @Override protected ExprPrinter _print1(ExprPrinter p) { return p.p("Cctrl"); } @Override public boolean isConst() { return true; } @Override public Type compute() { return Type.CONTROL; } @Override public Node idealize() { return null; } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/EscapeNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/EscapeNode.java index 5be4d3e8..3e95fffb 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/EscapeNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/EscapeNode.java @@ -1,8 +1,9 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.type.*; import com.seaofnodes.simple.util.*; -import java.util.BitSet; import java.util.HashMap; import java.util.IdentityHashMap; @@ -43,13 +44,13 @@ public class EscapeNode extends TypeNode { } @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { - sb.append("Esc#").append(fld()._alias).append(" {"); - if( self()==null ) sb.append("---"); - else self()._print0(sb,visited).append(","); - priv()._print0(sb,visited).append("}, "); - pub ()._print0(sb,visited); - return sb; + protected ExprPrinter _print1(ExprPrinter p) { + p.p("Esc#").p(fld()._alias).p(" {"); + if( self()==null ) p.p("---"); + else p.n(self()).p(","); + p.n(priv()).p("}, "); + p.n(pub ()); + return p; } @Override diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/ExternNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/ExternNode.java index 58d96745..978298fc 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/ExternNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ExternNode.java @@ -29,7 +29,6 @@ public class ExternNode extends ConstantNode { } @Override public String label() { return "#"+_con+":"+_extern; } - @Override public String uniqueName() { return "Extern_" + _nid; } @Override public boolean eq(Node n) { return this==n; } @Override public void gather( HashMap strs ) { diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/FRefNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/FRefNode.java index 698ba755..644f1434 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/FRefNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/FRefNode.java @@ -1,9 +1,10 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.Var; import com.seaofnodes.simple.type.Type; -import java.util.BitSet; /** * A Forward Reference. Its any final constant, including functions. When @@ -32,10 +33,9 @@ public class FRefNode extends ConstantNode { @Override public String label() { return "FRef"+_name; } - @Override public String uniqueName() { return "FRef_" + _nid; } - @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { - return sb.append("FRef_").append(_name); + @Override protected ExprPrinter _print1(ExprPrinter p) { + return p.p("FRef_").p(_name); } @Override public Node idealize() { diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/FldOffNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/FldOffNode.java index e34799c9..ef894929 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/FldOffNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/FldOffNode.java @@ -1,11 +1,12 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.type.*; import com.seaofnodes.simple.util.SB; import com.seaofnodes.simple.util.Utils; -import java.util.BitSet; import java.util.HashMap; /** @@ -23,11 +24,9 @@ public class FldOffNode extends TypeNode { @Override public String label() { return _fname == " len" ? "sizeof()" : "#"+_fname; } - @Override public String uniqueName() { return "Off_" + _nid; } - @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { - return sb.append(label()); + @Override protected ExprPrinter _print1(ExprPrinter p) { + return p.p(label()); } @Override public Type compute() { 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 141fc357..82053fd8 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/FunPtrNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/FunPtrNode.java @@ -1,10 +1,11 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.type.*; import com.seaofnodes.simple.util.BAOS; -import java.util.BitSet; import java.util.HashMap; import java.util.IdentityHashMap; @@ -25,7 +26,6 @@ public class FunPtrNode extends TypeNode { public FunNode fun() { return ret().fun(); } @Override public String label() { return "#"+_con; } - @Override public String uniqueName() { return "FunPtr_" + _nid; } @Override public Node copy() { FunPtrNode fptr = new FunPtrNode((TypeFunPtr)_con,null,null); fptr._type = _type; @@ -33,11 +33,11 @@ public class FunPtrNode extends TypeNode { } @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { + protected ExprPrinter _print1(ExprPrinter p) { FunNode fun = CodeGen.CODE._link(((TypeFunPtr)_con).fidx()); return fun!=null && fun._name!=null - ? sb.append("{ ").append(fun._name).append("}") - : sb.append(_con); + ? p.p("{ ").p(fun._name).p("}") + : p.p(_con); } @Override public boolean isConst() { return true; } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/GuardNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/GuardNode.java index 076a8388..0ce504d9 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/GuardNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/GuardNode.java @@ -1,11 +1,12 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeScalar; import com.seaofnodes.simple.util.BAOS; import com.seaofnodes.simple.util.Utils; -import java.util.BitSet; import java.util.HashMap; import java.util.IdentityHashMap; @@ -31,10 +32,9 @@ public class GuardNode extends Node { static Node make(BAOS bais) { return new GuardNode(bais.read()!=0,null,null); } @Override public String label() { return _nonZero ? "(!=0)" : "(==0)"; } - @Override public String uniqueName() { return "Guard_"+_nid; } - @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { - return in(1)._print0(sb.append(label()),visited); + @Override protected ExprPrinter _print1(ExprPrinter p) { + return p.p(label()).n(in(1)); } @Override public Type compute() { diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/IfNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/IfNode.java index d8d72411..c83c81d0 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/IfNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/IfNode.java @@ -1,9 +1,10 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.type.*; import com.seaofnodes.simple.util.Utils; -import java.util.BitSet; public class IfNode extends CFGNode implements MultiNode { @@ -15,11 +16,11 @@ public class IfNode extends CFGNode implements MultiNode { @Override public Tag serialTag() { return Tag.If; } @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { - sb.append("if( "); - if( in(1)==null ) sb.append("never"); - else in(1)._print0(sb, visited); - return sb.append(" )"); + protected ExprPrinter _print1(ExprPrinter p) { + p.p("if( "); + if( in(1)==null ) p.p("never"); + else p.n(in(1)); + return p.p(" )"); } public Node ctrl() { return in(0); } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/LoadNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/LoadNode.java index 85ca42cd..a2345d92 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/LoadNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/LoadNode.java @@ -1,5 +1,7 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.codegen.GlobalBits; @@ -53,7 +55,7 @@ public class LoadNode extends MemOpNode { // Debugger label @Override public String label() { return "ld_"+mlabel(); } @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { return sb.append(".").append(_name); } + protected ExprPrinter _print1(ExprPrinter p) { return p.p(".").p(_name); } @Override public Type compute() { diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/MachConcreteNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/MachConcreteNode.java index c2dcae0b..b25fcaaf 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/MachConcreteNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/MachConcreteNode.java @@ -1,8 +1,9 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.type.Type; import java.io.ByteArrayOutputStream; -import java.util.BitSet; // Generic machine-specific class, has a few Node implementations that have to // exist (abstract) but are not useful past the optimizer. @@ -15,12 +16,11 @@ public abstract class MachConcreteNode extends Node implements MachNode { @Override public Type compute () { throw new AssertionError("Do not call compute on "+getClass().getSimpleName()); } @Override public Node idealize() { throw new AssertionError("Do not call idealize on "+getClass().getSimpleName()); } - @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { - sb.append("(").append(op()).append(","); + @Override protected ExprPrinter _print1(ExprPrinter p) { + p.open().p(op()).p(","); for( int i=1; i _print1(ExprPrinter p) { + p.p("MEM[ "); for( int j=2; j _print1(ExprPrinter p) { return _printMach(p); } + protected ExprPrinter _printMach(ExprPrinter p) { throw Utils.TODO(); } // Extra conditions for factoring matching memory operations through a Phi. 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 7c3d49f2..023deba2 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/MinusNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/MinusNode.java @@ -1,11 +1,11 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.type.*; import com.seaofnodes.simple.util.BAOS; import com.seaofnodes.simple.util.Utils; -import java.util.BitSet; import java.util.HashMap; import java.util.IdentityHashMap; @@ -28,11 +28,7 @@ public class MinusNode extends Node implements ModeNode { return this; } - @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { - in(1)._print0(sb.append("(-"), visited); - return sb.append(")"); - } + @Override protected String format() { return "(-%1)"; } @Override public Type compute() { diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/NeverNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/NeverNode.java index e2c279d2..ba1dab8c 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/NeverNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/NeverNode.java @@ -1,11 +1,12 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.type.TypeInteger; import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeTuple; -import java.util.BitSet; // "Never true" for infinite loop exits public class NeverNode extends IfNode { @@ -15,7 +16,7 @@ public class NeverNode extends IfNode { @Override public String label() { return "Never"; } - @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { return sb.append("Never"); } + @Override protected ExprPrinter _print1(ExprPrinter p) { return p.p("Never"); } @Override public Type compute() { return TypeTuple.IF_BOTH; } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/NewNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/NewNode.java index 3e1d78dc..5eedd0cd 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/NewNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/NewNode.java @@ -1,11 +1,12 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.type.*; import com.seaofnodes.simple.util.BAOS; import com.seaofnodes.simple.util.SB; -import java.util.BitSet; import java.util.HashMap; import java.util.IdentityHashMap; @@ -34,9 +35,8 @@ public class NewNode extends Node implements MultiNode { @Override public String label() { return "new_"+(_ts.isAry() ? "ary_"+_ts._fields[1]._t.str() : _ts.str()); } - @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { - sb.append("new "); - return sb.append(_ts.str()); + @Override protected ExprPrinter _print1(ExprPrinter p) { + return p.p("new ").p(_ts.str()); } @Override public TypeTuple compute() { diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/Node.java b/chapter25/src/main/java/com/seaofnodes/simple/node/Node.java index 8842db78..9f5e107a 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/Node.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/Node.java @@ -1,5 +1,7 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.BaseNode; + import com.seaofnodes.simple.IterPeeps; import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.codegen.CodeGen; @@ -16,14 +18,7 @@ import static com.seaofnodes.simple.codegen.CodeGen.CODE; * The Node class provides common functionality used by all subtypes. * Subtypes of Node specialize by overriding methods. */ -public abstract class Node implements Cloneable { - - /** - * Each node has a unique dense Node ID within a compilation context - * The ID is useful for debugging, for using as an offset in a bitvector, - * as well as for computing equality of nodes (to be implemented later). - */ - public int _nid; +public abstract class Node extends BaseNode implements Cloneable { /** * Inputs to the node. These are use-def references to Nodes. @@ -45,16 +40,14 @@ public abstract class Node implements Cloneable { */ public Ary _outputs; - /** * Current computed type for this Node. This value changes as the graph * changes and more knowledge is gained about the program. */ public Type _type; - Node(Node... inputs) { - _nid = CODE.getUID(); // allocate unique dense ID + super(CODE.getUID()); // allocate unique dense ID _inputs = new Ary<>(Node.class); Collections.addAll(_inputs,inputs); _outputs = new Ary<>(Node.class); @@ -66,8 +59,8 @@ public abstract class Node implements Cloneable { // Make a Node using the existing arrays of nodes. // Used by any pass rewriting all Node classes but not the edges. Node( Node n ) { + super(CODE.getUID()); // allocate unique dense ID assert CodeGen.CODE._phase.ordinal() >= CodeGen.Phase.Select.ordinal(); - _nid = CODE.getUID(); // allocate unique dense ID _inputs = new Ary<>(n==null ? new Node[0] : n._inputs.asAry()); _outputs = new Ary<>(Node.class); _type = n==null ? Type.BOTTOM : n._type; @@ -152,48 +145,6 @@ public abstract class Node implements Cloneable { // Easy reading label for debugger, e.g. "Add" or "Region" or "EQ" public String label() { return serialTag().toString(); } - // Unique label for debugging, e.g. "Add12" or "Region30" or "EQ99" - public String uniqueName() { - return label() + _nid; - } - - // Operator symbol used by assembly/debug printing. - public String glabel() { return label(); } - - // Extra fun stuff, for assembly printing. Jump labels, parser locations, - // variable types, etc. - public String comment() { return null; } - - // ------------------------------------------------------------------------ - - // Debugger Printing. - - // {@code toString} is what you get in the debugger. It has to print 1 - // line (because this is what a debugger typically displays by default) and - // has to be robust with broken graph/nodes. - @Override - public final String toString() { return print(); } - - // This is a *deep* print. We print with a mutually recursive tik-tok - // style; the common _print0 calls the per-Node _print1, which calls back - // to _print0; - public final String print() { - return _print0(new StringBuilder(), new BitSet()).toString(); - } - - // This is the common print: check for repeats, check for DEAD and print - // "DEAD" else call the per-Node print1. - public final StringBuilder _print0(StringBuilder sb, BitSet visited) { - if( visited.get(_nid) && !(this instanceof ConstantNode) ) - return sb.append(label()); - visited.set(_nid); - return isDead() - ? sb.append(uniqueName()).append(":DEAD") - : _print1(sb, visited); - } - // Every Node implements this; a partial-line recursive print - abstract public StringBuilder _print1(StringBuilder sb, BitSet visited); - public String p(int depth) { return IRPrinter.prettyPrint(this,depth); } public boolean isConst() { return false; } @@ -201,6 +152,8 @@ public abstract class Node implements Cloneable { // ------------------------------------------------------------------------ // Graph Node & Edge manipulation + @Override public String typeName() { return _type==null ? null : _type.toString(); } + /** * Gets the ith input node * @param i Offset of the input node @@ -279,7 +232,6 @@ public abstract class Node implements Cloneable { setDef(idx,new_def); } - /** * Add a new def to an existing Node. Keep the edges correct by * adding the corresponding def->use edge. @@ -358,7 +310,6 @@ public abstract class Node implements Cloneable { kill(); } - // Mostly used for asserts and printing. public boolean isDead() { return isUnused() && nIns()==0 && _type==null; } @@ -382,7 +333,6 @@ public abstract class Node implements Cloneable { kill(); } - // Replace self with nnn in the graph, making 'this' go dead public void subsume( Node nnn ) { assert nnn!=this; @@ -622,7 +572,6 @@ public abstract class Node implements Cloneable { */ public abstract Node idealize(); - // Some of the peephole rules get complex, and search further afield than // just the nearest neighbor. These peepholes can fail the pattern match // on a node some distance away, and if that node ever changes we should @@ -669,7 +618,6 @@ public abstract class Node implements Cloneable { _deps.clear(); } - // Two nodes are equal if they have the same inputs and the same "opcode" // which means the same Java class, plus same internal parts. @Override public final boolean equals( Object o ) { @@ -687,7 +635,6 @@ public abstract class Node implements Cloneable { // and can assume "this!=n" and has the same Java class. public boolean eq( Node n ) { return true; } - // Cached hash. If zero, then not computed AND this Node is NOT in the GVN // table - and can have its edges hacked (which will change his hash // anyway). If Non-Zero then this Node is IN the GVN table, or is being @@ -703,7 +650,6 @@ public abstract class Node implements Cloneable { _hash=0; // Out of table now } - // Hash of opcode and inputs @Override public final int hashCode() { if( _hash != 0 ) return _hash; @@ -723,7 +669,6 @@ public abstract class Node implements Cloneable { /** Is this Node Memory related */ public boolean isMem() { return false; } - // ------------------------------------------------------------------------ // Peephole utilities @@ -750,7 +695,6 @@ public abstract class Node implements Cloneable { return true; } - // Make a shallow copy (same class) of this Node, with given inputs and // empty outputs and a new Node ID. The original inputs are ignored. // Does not need to be implemented in isCFG() nodes. diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/NotNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/NotNode.java index ed6091fe..2328c287 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/NotNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/NotNode.java @@ -1,18 +1,14 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.type.*; import com.seaofnodes.simple.util.Utils; -import java.util.BitSet; public class NotNode extends Node { public NotNode(Node in) { super(null, in); } @Override public Tag serialTag() { return Tag.Not; } - @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { - in(1)._print0(sb.append("(!"), visited); - return sb.append(")"); - } + @Override protected String format() { return "(!%1)"; } @Override public TypeInteger compute() { diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/ParmNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/ParmNode.java index be36e8d9..899d7639 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/ParmNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ParmNode.java @@ -1,9 +1,10 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.type.*; import com.seaofnodes.simple.util.BAOS; -import java.util.BitSet; import java.util.HashMap; import java.util.IdentityHashMap; @@ -47,18 +48,12 @@ public class ParmNode extends PhiNode { public FunNode fun() { return (FunNode)in(0); } @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { + protected ExprPrinter _print1(ExprPrinter p) { if( fun()._name!=null && fun()._name.endsWith("") && _label.equals("arg") ) - return sb.append("arg"); - sb.append("Parm_").append(_label).append("("); - for( Node in : _inputs ) { - if (in == null) sb.append("____"); - else in._print0(sb, visited); - sb.append(","); - } - sb.setLength(sb.length()-1); - sb.append(")"); - return sb; + return p.p("arg"); + p.p("Parm_").p(_label).open(); + for( Node in : _inputs ) p.n(in).p(","); + return p.unchar(',').close(); } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/PhiNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/PhiNode.java index 9d8adb15..0097c773 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/PhiNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/PhiNode.java @@ -1,10 +1,11 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.*; import com.seaofnodes.simple.codegen.Serialize; import com.seaofnodes.simple.type.*; import com.seaofnodes.simple.util.*; -import java.util.BitSet; import java.util.HashMap; import java.util.IdentityHashMap; @@ -48,18 +49,12 @@ public class PhiNode extends Node { @Override public String label() { return "Phi_"+MemOpNode.mlabel(_label); } @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { + protected ExprPrinter _print1(ExprPrinter p) { if( !(region() instanceof RegionNode r) || r.inProgress() ) - sb.append("Z"); - sb.append("Phi("); - for( Node in : _inputs ) { - if (in == null) sb.append("____"); - else in._print0(sb, visited); - sb.append(","); - } - sb.setLength(sb.length()-1); - sb.append(")"); - return sb; + p.p("Z"); + p.p("Phi("); + for( Node in : _inputs ) p.n(in).p(","); + return p.unchar(',').close(); } public CFGNode region() { return (CFGNode)in(0); } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/ProjNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/ProjNode.java index 5e3c7080..4b29cc3c 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/ProjNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ProjNode.java @@ -1,11 +1,12 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.codegen.Serialize; import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeMem; import com.seaofnodes.simple.type.TypeTuple; import com.seaofnodes.simple.util.BAOS; -import java.util.BitSet; import java.util.HashMap; import java.util.IdentityHashMap; @@ -35,11 +36,11 @@ public class ProjNode extends Node implements Proj { @Override public String label() { return _label; } @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { - if( _label != null ) return sb.append(_label); + protected ExprPrinter _print1(ExprPrinter p) { + if( _label != null ) return p.p(_label); if( in(0) instanceof CallEndNode cend && cend.call()!=null ) - return cend.call()._print0(sb,visited); - return sb.append("LONELY PROJ"); + return p.n(cend.call()); + return p.p("LONELY PROJ"); } @Override public CFGNode cfg0() { diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/PtrToIntNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/PtrToIntNode.java index f0e7ae95..d3d38060 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/PtrToIntNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/PtrToIntNode.java @@ -1,11 +1,11 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeInteger; import com.seaofnodes.simple.type.TypeMemPtr; -import java.util.BitSet; /** * Reinterpret a non-null managed pointer as its raw integer address. @@ -19,9 +19,7 @@ public class PtrToIntNode extends Node { public PtrToIntNode(PtrToIntNode ptr) { super(ptr); } @Override public Tag serialTag() { return Tag.PtrToInt; } - @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { - return in(1)._print0(sb.append("(i64*)"),visited); - } + @Override protected String format() { return "(i64*)%1"; } @Override public Type compute() { return in(1)._type.isHigh() ? TypeInteger.TOP : TypeInteger.BOT; diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/ReadOnlyNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/ReadOnlyNode.java index c36be85a..0a720d5b 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/ReadOnlyNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ReadOnlyNode.java @@ -1,8 +1,8 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeMemPtr; -import java.util.BitSet; /** * Cast a pointer to read-only @@ -12,10 +12,7 @@ public class ReadOnlyNode extends Node { public ReadOnlyNode( ReadOnlyNode n ) { super(n); } @Override public Tag serialTag() { return Tag.ReadOnly; } - @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { - return in(1)._print0(sb.append("(const)"),visited); - } + @Override protected String format() { return "(const)%1"; } @Override public Type compute() { Type t = in(1)._type; return t instanceof TypeMemPtr tmp ? tmp.makeRO() : t; diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/RegionNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/RegionNode.java index a886183e..8883ba8e 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/RegionNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/RegionNode.java @@ -1,5 +1,7 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.type.Type; @@ -17,9 +19,8 @@ public class RegionNode extends CFGNode { public void packed( BAOS baos, HashMap strs, HashMap types, IdentityHashMap anodes ) { baos.packed1(nIns()); } static Node make( BAOS bais ) { return new RegionNode(null,new Node[bais.packed1()]); } - @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { - return sb.append(label()); + @Override protected ExprPrinter _print1(ExprPrinter p) { + return p.p(label()); } @Override public boolean blockHead() { return true; } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/ReturnNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/ReturnNode.java index 0dc14fd2..0431f7d5 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/ReturnNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ReturnNode.java @@ -1,5 +1,7 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.codegen.Encoding; @@ -7,7 +9,6 @@ import com.seaofnodes.simple.codegen.RegMask; import com.seaofnodes.simple.type.*; import com.seaofnodes.simple.util.SB; import com.seaofnodes.simple.util.Utils; -import java.util.BitSet; /** * The Return node has two inputs. The first input is a control node and the @@ -36,11 +37,11 @@ public class ReturnNode extends CFGNode { @Override public FunNode fun() { return _fun; } @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { - sb.append("return "); - if( expr()==null ) sb.append("----"); - else expr()._print0(sb, visited); - return sb.append(";"); + protected ExprPrinter _print1(ExprPrinter p) { + p.p("return "); + if( expr()==null ) p.p("----"); + else p.n(expr()); + return p.p(";"); } // No one unique control follows; can be many call end sites diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/RoundF32Node.java b/chapter25/src/main/java/com/seaofnodes/simple/node/RoundF32Node.java index 61809fe3..1a3592dc 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/RoundF32Node.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/RoundF32Node.java @@ -1,18 +1,15 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeFloat; -import java.util.BitSet; public class RoundF32Node extends Node { public RoundF32Node(Node lhs) { super(null, lhs); } @Override public Tag serialTag() { return Tag.RoundF32; } - @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { - return in(1)._print0(sb.append("((f32)"), visited).append(")"); - } + @Override protected String format() { return "((f32)%1)"; } @Override public Type compute() { diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/ScopeNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/ScopeNode.java index 527d3395..92cad745 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/ScopeNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ScopeNode.java @@ -1,5 +1,7 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.Var; import com.seaofnodes.simple.codegen.CodeGen; @@ -61,28 +63,26 @@ public class ScopeNode extends MemMergeNode { @Override public String label() { return "Scope"; } @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { - sb.append("Scope[ "); + protected ExprPrinter _print1(ExprPrinter p) { + p.p("Scope[ "); int j=1; for( int i=0; i _print1(ExprPrinter p) { + p.p("mov("); + if( in(1) == null ) p.p("---"); + else p.n(in(1)); + return p.close(); } public FunNode fun(Encoding enc) { return enc._code._regAlloc.lrg(this)._fun; } @Override public Type compute() { return in(0)._type; } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/StartNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/StartNode.java index dc21e5eb..84c8a3a7 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/StartNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/StartNode.java @@ -1,11 +1,12 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.type.*; import com.seaofnodes.simple.util.Utils; import java.util.Arrays; -import java.util.BitSet; import java.util.HashSet; /** @@ -31,9 +32,8 @@ public class StartNode extends LoopNode implements MultiNode { @Override public Tag serialTag() { return Tag.Start; } public Type arg() { return _arg; } - @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { - return sb.append(label()); + @Override protected ExprPrinter _print1(ExprPrinter p) { + return p.p(label()); } @Override public CFGNode cfg0() { return null; } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/StopNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/StopNode.java index b0bf8343..e52a49a2 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/StopNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/StopNode.java @@ -1,10 +1,11 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.type.*; import com.seaofnodes.simple.util.BAOS; -import java.util.BitSet; import java.util.HashMap; import java.util.IdentityHashMap; @@ -25,7 +26,7 @@ public class StopNode extends CFGNode { } @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { + protected ExprPrinter _print1(ExprPrinter p) { // For the sake of many old tests, and single value prints as "return val" ReturnNode ret1 = null; for( Node n : _inputs ) { @@ -34,16 +35,16 @@ public class StopNode extends CFGNode { ret1 = ret; } } - if( ret1!=null ) return ret1._print0(sb,visited); + if( ret1!=null ) return p.n(ret1); - sb.append("Stop[ "); + p.p("Stop[ "); for( Node n : _inputs ) if( n instanceof ReturnNode ret ) { String name = ret.fun()._name; if( name== null || !name.startsWith("sys.") ) - ret._print0(sb, visited).append(" "); + p.n(ret).p(" "); } - return sb.append("]"); + return p.p("]"); } @Override public boolean blockHead() { return true; } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/StoreNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/StoreNode.java index fe379c80..7e2963f2 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/StoreNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/StoreNode.java @@ -1,12 +1,13 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.*; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.codegen.GlobalBits; import com.seaofnodes.simple.type.*; import com.seaofnodes.simple.util.BAOS; import com.seaofnodes.simple.util.Utils; -import java.util.BitSet; import java.util.HashMap; import java.util.IdentityHashMap; @@ -67,8 +68,8 @@ public class StoreNode extends MemOpNode { public int log_size() { return Integer.numberOfTrailingZeros(storeSize()); }; @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { - return sb.append(".").append(_name).append("=").append( val()).append(";"); + protected ExprPrinter _print1(ExprPrinter p) { + return p.p(".").p(_name).p("=").p( val()).p(";"); } @Override diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/ToFloatNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/ToFloatNode.java index 15350afb..151a326e 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/ToFloatNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ToFloatNode.java @@ -1,19 +1,16 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeFloat; import com.seaofnodes.simple.type.TypeInteger; -import java.util.BitSet; public class ToFloatNode extends Node { public ToFloatNode(Node lhs) { super(null, lhs); } @Override public Tag serialTag() { return Tag.ToFloat; } - @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { - return in(1)._print0(sb.append("(flt)"), visited); - } + @Override protected String format() { return "(flt)%1"; } @Override public Type compute() { diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/XCtrlNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/XCtrlNode.java index a8c06b37..32e1deb9 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/XCtrlNode.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/XCtrlNode.java @@ -1,14 +1,15 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.type.Type; -import java.util.BitSet; public class XCtrlNode extends CFGNode { public XCtrlNode() { super(new Node[]{CodeGen.CODE._start}); } @Override public Tag serialTag() { return Tag.XCtrl; } - @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { return sb.append("Xctrl"); } + @Override protected ExprPrinter _print1(ExprPrinter p) { return p.p("Xctrl"); } @Override public boolean isConst() { return true; } @Override public Type compute() { return Type.XCONTROL; } @Override public Node idealize() { return null; } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/arm/MemOpARM.java b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/arm/MemOpARM.java index 53a0f8cf..a26f385a 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/arm/MemOpARM.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/arm/MemOpARM.java @@ -1,11 +1,12 @@ package com.seaofnodes.simple.node.cpus.arm; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.type.*; import com.seaofnodes.simple.util.SB; import java.lang.StringBuilder; -import java.util.BitSet; public abstract class MemOpARM extends MemOpNode implements MachNode { final int _off; // Limit 9 bits sized, or (13 bits< _printMach(ExprPrinter p) { return p.p(".").p(_name); } @Override public Type compute() { throw new AssertionError("Do not call compute on "+getClass().getSimpleName()); } @Override public Node idealize() { throw new AssertionError("Do not call idealize on "+getClass().getSimpleName()); } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java index 2dd5fd6b..ce4f523c 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/arm/UJmpARM.java @@ -1,20 +1,18 @@ package com.seaofnodes.simple.node.cpus.arm; + import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.util.SB; import com.seaofnodes.simple.util.Utils; -import java.util.BitSet; // unconditional jump public class UJmpARM extends CFGNode implements MachNode, RIPRelSize { UJmpARM() { } @Override public String op() { return "jmp"; } @Override public String label() { return op(); } - @Override public StringBuilder _print1( StringBuilder sb, BitSet visited ) { - return sb.append("jmp "); - } + @Override protected String format() { return "jmp "; } @Override public RegMask regmap(int i) {return null; } @Override public RegMask outregmap() { return null; } @Override public Type compute() { throw Utils.TODO(); } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java index b7284265..b8664679 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java @@ -1,10 +1,11 @@ package com.seaofnodes.simple.node.cpus.riscv; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.util.SB; import com.seaofnodes.simple.util.Utils; -import java.util.BitSet; // Conditional branch such as: BEQ public class BranchRISC extends IfNode implements MachNode, RIPRelSize { @@ -31,14 +32,14 @@ public class BranchRISC extends IfNode implements MachNode, RIPRelSize { } } - @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { - sb.append("if( "); - if( in(1)==null ) sb.append("0"); - else in(1)._print0(sb,visited); - sb.append(_bop); - if( in(2)==null ) sb.append("0"); - else in(2)._print0(sb,visited); - return sb.append(" )"); + @Override protected ExprPrinter _print1(ExprPrinter p) { + p.p("if( "); + if( in(1)==null ) p.p("0"); + else p.n(in(1)); + p.p(_bop); + if( in(2)==null ) p.p("0"); + else p.n(in(2)); + return p.p(" )"); } @Override public void encoding( Encoding enc ) { diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java index f2beb25c..b4c87872 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java @@ -1,10 +1,11 @@ package com.seaofnodes.simple.node.cpus.riscv; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.type.TypeInteger; import com.seaofnodes.simple.util.SB; -import java.util.BitSet; abstract public class ImmRISC extends MachConcreteNode implements MachNode { public final int _imm12; @@ -28,10 +29,10 @@ abstract public class ImmRISC extends MachConcreteNode implements MachNode { return in(1) instanceof LUI || in(1) instanceof AUIPC; } - @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { + @Override protected ExprPrinter _print1(ExprPrinter p) { int imm12 = (_imm12<<20)>>20; // Sign extend 12 bits - in(1)._print0(sb.append("( "), visited); - return sb.append(String.format(" %s #%d )",glabel(),imm12)); + p.p("( ").n(in(1)); + return p.p(String.format(" %s #%d )",glabel(),imm12)); } abstract int opcode(); diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java index 5fcba6f8..e0bbc219 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java @@ -1,11 +1,12 @@ package com.seaofnodes.simple.node.cpus.riscv; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.util.SB; import com.seaofnodes.simple.util.Utils; import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.type.*; -import java.util.BitSet; public abstract class MemOpRISC extends MemOpNode implements MachNode { final int _off; // Limit 12 bits @@ -25,7 +26,7 @@ public abstract class MemOpRISC extends MemOpNode implements MachNode { @Override public String label() { return op(); } Node val() { return in(4); } // Only for stores - @Override public StringBuilder _printMach(StringBuilder sb, BitSet visited) { return sb.append(".").append(_name); } + @Override protected ExprPrinter _printMach(ExprPrinter p) { return p.p(".").p(_name); } @Override public Type compute() { throw new AssertionError("Do not call compute on "+getClass().getSimpleName()); } @Override public Node idealize() { throw new AssertionError("Do not call idealize on "+getClass().getSimpleName()); } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java index c4d5d8af..160895df 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/riscv/UJmpRISC.java @@ -1,17 +1,18 @@ package com.seaofnodes.simple.node.cpus.riscv; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.util.SB; import com.seaofnodes.simple.util.Utils; -import java.util.BitSet; // unconditional jump public class UJmpRISC extends CFGNode implements MachNode, RIPRelSize { @Override public String op() { return "jmp"; } @Override public String label() { return op(); } - @Override public StringBuilder _print1( StringBuilder sb, BitSet visited ) { return sb.append("jmp "); } + @Override protected ExprPrinter _print1(ExprPrinter p) { return p.p("jmp "); } @Override public RegMask regmap(int i) {return null; } @Override public RegMask outregmap() { return null; } @Override public Type compute() { throw Utils.TODO(); } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemOpX86.java b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemOpX86.java index 87cc6e35..fcca7f8f 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemOpX86.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemOpX86.java @@ -1,11 +1,12 @@ package com.seaofnodes.simple.node.cpus.x86_64_v2; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.type.*; import com.seaofnodes.simple.util.SB; import java.lang.StringBuilder; -import java.util.BitSet; // Generic X86 memory operand base. // inputs: @@ -53,8 +54,8 @@ public abstract class MemOpX86 extends MemOpNode implements MachNode { Node idx() { return in(3); } Node val() { return in(4); } // Only for stores, including op-to-memory - @Override public StringBuilder _printMach(StringBuilder sb, BitSet visited) { - return sb.append(".").append(_name); + @Override protected ExprPrinter _printMach(ExprPrinter p) { + return p.p(".").p(_name); } @Override public String label() { return op(); } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java index faedeb8b..7133e824 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java @@ -1,5 +1,7 @@ package com.seaofnodes.simple.node.cpus.x86_64_v2; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.ConstantNode; import com.seaofnodes.simple.node.Node; @@ -7,19 +9,18 @@ import com.seaofnodes.simple.node.StoreNode; import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeFloat; import com.seaofnodes.simple.util.SB; -import java.util.BitSet; public class StoreX86 extends MemOpX86 { StoreX86( StoreNode st, Node base, Node idx, int off, int scale, int imm, Node val ) { super(st,st, base, idx, off, scale, imm, val); } @Override public String op() { return "st"+_sz; } - @Override public StringBuilder _printMach(StringBuilder sb, BitSet visited) { + @Override protected ExprPrinter _printMach(ExprPrinter p) { Node val = val(); - sb.append(".").append(_name).append("="); - if( val==null ) sb.append(_imm); - else val._print0(sb,visited); - return sb.append(";"); + p.p(".").p(_name).p("="); + if( val==null ) p.p(_imm); + else p.n(val); + return p.p(";"); } // Register mask allowed as a result. 0 for no register. @Override public RegMask outregmap() { return null; } diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/UJmpX86.java b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/UJmpX86.java index 92d2a87d..6f538d27 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/UJmpX86.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/UJmpX86.java @@ -1,20 +1,18 @@ package com.seaofnodes.simple.node.cpus.x86_64_v2; + import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.util.SB; import com.seaofnodes.simple.util.Utils; -import java.util.BitSet; // unconditional jump public class UJmpX86 extends CFGNode implements MachNode, RIPRelSize { UJmpX86() { } @Override public String op() { return "jmp"; } @Override public String label() { return op(); } - @Override public StringBuilder _print1( StringBuilder sb, BitSet visited ) { - return sb.append("jmp "); - } + @Override protected String format() { return "jmp "; } @Override public RegMask regmap(int i) {return null; } @Override public RegMask outregmap() { return null; } @Override public Type compute() { throw Utils.TODO(); } 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 ff3eada2..994065d8 100644 --- a/chapter25/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java +++ b/chapter25/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java @@ -1,309 +1,94 @@ package com.seaofnodes.simple.print; -import com.seaofnodes.simple.codegen.CompUnit; +import com.seaofnodes.print.AssemblyAdapter; +import com.seaofnodes.print.ASMPrinter.Data; +import com.seaofnodes.print.ASMPrinter.Pool; import com.seaofnodes.simple.codegen.CodeGen; -import com.seaofnodes.simple.codegen.Encoding.Relo; -import com.seaofnodes.simple.codegen.Encoding; +import com.seaofnodes.simple.util.SB; import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.type.*; -import com.seaofnodes.simple.util.*; +import java.util.ArrayList; +import com.seaofnodes.simple.codegen.Encoding; +import com.seaofnodes.simple.util.BAOS; import java.util.HashMap; -import java.util.Collections; -import java.util.IdentityHashMap; -import java.util.Set; - -public abstract class ASMPrinter { - - public static SB print(SB sb, CodeGen code ) { - Encoding enc = code._encoding; - Ary cfg = enc == null ? code._cfg : enc._cfg; - if( cfg == null || cfg._len == 0 ) return sb.p("No scheduled code for ").p(code._srcName); - // instruction address - int iadr = 0; - // Print all functions in order - for( int i=0; i0 ) - iadr = printConstantPool(iadr, sb, enc._cpool,enc._bigCons,true ,"Constant Pool"); - - iadr = (iadr+15)&-16; // pad to 16 - if( enc._sdata.size()>0 ) - iadr = printConstantPool(iadr, sb,enc._sdata,enc._bigCons,false, "Static Data" ); - } - - return sb; +/** Machine-specific facts; traversal, columns and byte display live in print/. */ +public final class ASMPrinter extends AssemblyAdapter { + private final CodeGen _code; + private final Encoding _enc; + private ASMPrinter(CodeGen code) { + super(new IRPrinter()); + _code=code; + _enc=code._encoding; } - - - static int printConstantPool( int iadr, SB sb, BAOS bits, HashMap bigCons, boolean ro, String msg ) { - sb.p("--- ").p(msg).p(" ------").nl(); - // radix sort the big constants by alignment - Ary[] raligns = new Ary[5]; - for( Relo relo : bigCons.values() ) { - if( relo.readOnly() != ro ) - continue; - int align = relo._align; - Ary relos = raligns[align]==null ? (raligns[align]=new Ary<>( Relo.class)) : raligns[align]; - relos.add(relo); - } - - Set targets = Collections.newSetFromMap(new IdentityHashMap<>()); - - // By alignment - int dadr=0; - for( int align = 4; align >= 0; align-- ) { - Ary relos = raligns[align]; - if( relos == null ) continue; - for( Relo relo : relos ) { - if( targets.contains(relo._t) ) continue; - targets.add(relo._t); - sb.hex2(iadr+dadr).p(" "); - if( relo._t instanceof TypeStruct ts ) { - int sz = relo._structSize; - int log = 1<(new ASMPrinter(code)).print()); } - - - private static SB pN( BAOS bits, SB sb, int dadr, int log ) { - switch( log ) { - case 0: sb.hex1(bits.read1(dadr)); break; - case 1: sb.hex2(bits.read2(dadr)); break; - case 2: sb.hex4(bits.read4(dadr)); break; - case 3: sb.hex8(bits.read8(dadr)); break; + @Override public ArrayList blocks() { + var blocks=new ArrayList(); + var cfg=_enc==null ? _code._cfg : _enc._cfg; + if( cfg!=null ) for( Node n : cfg ) blocks.add(n); + return blocks; + } + @Override public String op(Node n) { return n instanceof MachNode m ? m.op() : n.label(); } + @Override public String register(Node n) { return _code.reg(n); } + @Override public String comment(Node n) { return n.comment(); } + @Override public String phiName(Node n) { return ((PhiNode)n)._label; } + @Override public String operands(Node n) { + SB sb=new SB(); + if( n instanceof MachNode m ) m.asm(_code,sb); + else if( !(n._type instanceof TypeMem) ) { + sb.p(n._nid).p(": "); + for( Node def : n._inputs ) sb.p(def==null ? "___" : Integer.toString(def._nid)).p(' '); } - return sb; + return sb.toString(); } - - - private static int print(int iadr, SB sb, CodeGen code, Encoding enc, Ary cfg, FunNode fun, int cfgidx) { - // Function header - sb.nl().p("---"); - if( fun._name != null ) sb.p(fun._name).p(" "); - fun.sig().print(sb); - sb.p("---------------------------").nl(); - iadr = (iadr + 15)&-16; // All function entries padded to 16 align - - if( fun._frameAdjust != 0 ) - iadr = doInst(iadr,sb,code,enc, cfgidx,fun,true,enc!=null); - while( !(cfg.at(cfgidx) instanceof ReturnNode) ) - iadr = doBlock(iadr,sb,code,enc,cfg,fun,cfgidx++); - - // Function separator - sb.p("---"); - fun.sig().print(sb); - sb.p("---------------------------").nl(); - return iadr; + @Override public boolean labelBlock(Node n) { + return !(n instanceof FunNode) && !(n instanceof IfNode) && !(n instanceof CallNode) && + !(n instanceof CallEndNode) && !(n instanceof CProjNode && ir.input0(n) instanceof CallEndNode); } - - static private final int opWidth = 5; - static private final int argWidth = 30; - static int doBlock(int iadr, SB sb, CodeGen code, Encoding enc, Ary cfg, FunNode fun, int cfgidx) { - final int encWidth = code._mach==null ? 2 : code._mach.defaultOpSize()*2; - CFGNode bb = cfg.at(cfgidx); - if( bb != fun && !(bb instanceof IfNode) && !(bb instanceof CallEndNode) && !(bb instanceof CallNode) && !(bb instanceof CProjNode && bb.in(0) instanceof CallEndNode )) - sb.p(label(bb)).p(":").nl(); - if( bb instanceof CallNode ) return iadr; - final boolean postEncode= code._phase.ordinal() >=CodeGen.Phase.Encoding.ordinal(); - final boolean postAlloc = code._phase.ordinal() > CodeGen.Phase.RegAlloc.ordinal() || - (code._phase.ordinal() == CodeGen.Phase.RegAlloc.ordinal() && code._regAlloc.done()); - - boolean once=false; - for( Node n : bb.outs() ) { - if( !(n instanceof PhiNode phi) ) continue; - if( phi._type instanceof TypeMem || phi._type instanceof TypeRPC ) continue; // Nothing for the hidden ones - // Post-RegAlloc phi prints all on one line - if( postAlloc ) { - if( !once ) { once=true; sb.fix(4," ").p(" ").fix(encWidth,"").p(" "); } - sb.p(phi._label).p(':').p(code.reg(phi)).p(','); - } else { - // Pre-RegAlloc phi prints one line per - sb.fix(4," ").p(" ").fix(encWidth,"").p(" ").fix(opWidth,phi._label).p(" ").p(code.reg(phi)); - if( phi.getClass() == PhiNode.class ) { - sb.p(" = phi( "); - for( int i=1; i blocks = enc == null ? code._cfg : enc._cfg; - while( cfgidx < blocks._len-1 ) { - CFGNode next = blocks.at(++cfgidx); - if( next == n ) return iadr; // Fall-through, no branch - if( next.nOuts()>1 ) - break; // Has code in the block, need to jump around - // No code in the block, can fall through it - } - sb.hex2(iadr++).p(" ").fix(encWidth,"??").p(" ").fix(opWidth,"JMP").p(" ").fix(argWidth,label(cfg)).nl(); - return iadr; + @Override public boolean postAlloc() { return _code._phase.ordinal()>CodeGen.Phase.RegAlloc.ordinal() || + (_code._phase==CodeGen.Phase.RegAlloc && _code._regAlloc!=null && _code._regAlloc.done()); } + @Override public boolean encoded() { return _enc!=null && _code._phase.ordinal()>=CodeGen.Phase.Encoding.ordinal(); } + @Override public int defaultSize() { return _code._mach==null ? 2 : _code._mach.defaultOpSize(); } + @Override public boolean littleEndian() { return _code._asmLittle; } + @Override public boolean prologue(Node n) { return ((FunNode)n)._frameAdjust!=0; } + @Override public byte[] bytes() { return encoded() ? _enc._bits.buf() : null; } + @Override public int offset(Node n) { return encoded() ? _enc.opStart(n) : -1; } + @Override public int size(Node n) { return encoded() ? _enc.opLen(n)&255 : 0; } + private static ArrayList entries(Iterable relos, boolean ro) { + var data=new ArrayList(); + for( Encoding.Relo r : relos ) { + if( r.readOnly()!=ro ) continue; + int align=1<