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 --- .../com/seaofnodes/simple/codegen/CodeGen.java | 2 +- .../java/com/seaofnodes/simple/node/AddFNode.java | 9 +- .../java/com/seaofnodes/simple/node/AddNode.java | 9 +- .../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 +- .../java/com/seaofnodes/simple/node/CastNode.java | 10 +- .../com/seaofnodes/simple/node/ConstantNode.java | 17 +- .../java/com/seaofnodes/simple/node/CtrlNode.java | 5 +- .../java/com/seaofnodes/simple/node/DivFNode.java | 9 +- .../java/com/seaofnodes/simple/node/DivNode.java | 9 +- .../java/com/seaofnodes/simple/node/FRefNode.java | 8 +- .../java/com/seaofnodes/simple/node/IfNode.java | 8 +- .../java/com/seaofnodes/simple/node/LoadNode.java | 5 +- .../com/seaofnodes/simple/node/LogicalNode.java | 10 +- .../seaofnodes/simple/node/MachConcreteNode.java | 12 +- .../com/seaofnodes/simple/node/MemMergeNode.java | 12 +- .../java/com/seaofnodes/simple/node/MemOpNode.java | 6 +- .../com/seaofnodes/simple/node/MinusFNode.java | 8 +- .../java/com/seaofnodes/simple/node/MinusNode.java | 8 +- .../java/com/seaofnodes/simple/node/MulFNode.java | 9 +- .../java/com/seaofnodes/simple/node/MulNode.java | 9 +- .../java/com/seaofnodes/simple/node/NeverNode.java | 5 +- .../java/com/seaofnodes/simple/node/NewNode.java | 9 +- .../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/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/StructNode.java | 18 +- .../java/com/seaofnodes/simple/node/SubFNode.java | 9 +- .../java/com/seaofnodes/simple/node/SubNode.java | 9 +- .../com/seaofnodes/simple/node/ToFloatNode.java | 7 +- .../java/com/seaofnodes/simple/node/XCtrlNode.java | 5 +- .../seaofnodes/simple/node/cpus/arm/CallARM.java | 2 +- .../seaofnodes/simple/node/cpus/arm/MemOpARM.java | 5 +- .../simple/node/cpus/riscv/BranchRISC.java | 13 +- .../seaofnodes/simple/node/cpus/riscv/ImmRISC.java | 8 +- .../simple/node/cpus/riscv/MemOpRISC.java | 5 +- .../simple/node/cpus/x86_64_v2/MemOpX86.java | 7 +- .../simple/node/cpus/x86_64_v2/StoreX86.java | 13 +- .../com/seaofnodes/simple/print/ASMPrinter.java | 192 +++------- .../com/seaofnodes/simple/print/IRPrinter.java | 396 +++------------------ .../simple/print/SimpleGraphAdapter.java | 38 +- 54 files changed, 324 insertions(+), 857 deletions(-) (limited to 'chapter20/src/main/java') diff --git a/chapter20/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java b/chapter20/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java index 93362799..78cf4c06 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java @@ -347,7 +347,7 @@ public class CodeGen { @Override public String toString() { return _phase.ordinal() > Phase.Schedule.ordinal() ? IRPrinter._prettyPrint( this ) - : _stop.p(9999); + : IRPrinter.prettyPrint(this); } // Debugging helper diff --git a/chapter20/src/main/java/com/seaofnodes/simple/node/AddFNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/AddFNode.java index 5d0a473a..fd713156 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/AddFNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/AddFNode.java @@ -1,21 +1,16 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeFloat; -import java.util.BitSet; public class AddFNode extends Node { public AddFNode(Node lhs, Node rhs) { super(null, lhs, rhs); } @Override public String label() { return "AddF"; } - @Override - StringBuilder _print1(StringBuilder sb, BitSet visited) { - in(1)._print0(sb.append("("), visited); - in(2)._print0(sb.append("+"), visited); - return sb.append(")"); - } + @Override protected String format() { return "(%1+%2)"; } @Override public Type compute() { diff --git a/chapter20/src/main/java/com/seaofnodes/simple/node/AddNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/AddNode.java index e1d16cf3..01cb6bb7 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/AddNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/AddNode.java @@ -1,9 +1,9 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.type.*; -import java.util.BitSet; import static com.seaofnodes.simple.Parser.con; @@ -12,12 +12,7 @@ public class AddNode extends Node { @Override public String label() { return "Add"; } - @Override - StringBuilder _print1(StringBuilder sb, BitSet visited) { - in(1)._print0(sb.append("("), visited); - in(2)._print0(sb.append("+"), visited); - return sb.append(")"); - } + @Override protected String format() { return "(%1+%2)"; } @Override diff --git a/chapter20/src/main/java/com/seaofnodes/simple/node/BoolNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/BoolNode.java index 9faa5181..85bcae0f 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/BoolNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/BoolNode.java @@ -1,9 +1,10 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.type.*; -import java.util.BitSet; import static com.seaofnodes.simple.type.TypeInteger.*; abstract public class BoolNode extends Node { @@ -17,11 +18,8 @@ abstract public class BoolNode extends Node { @Override public String label() { return getClass().getSimpleName(); } - @Override - 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/chapter20/src/main/java/com/seaofnodes/simple/node/CProjNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/CProjNode.java index adc4e66f..bfdcb04b 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/CProjNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/CProjNode.java @@ -1,11 +1,12 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeMem; import com.seaofnodes.simple.type.TypeTuple; -import java.util.BitSet; public class CProjNode extends CFGNode { @@ -24,7 +25,7 @@ public class CProjNode extends CFGNode { @Override public String label() { return _label; } - @Override 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/chapter20/src/main/java/com/seaofnodes/simple/node/CallEndNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/CallEndNode.java index c90e0530..ba04922b 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/CallEndNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/CallEndNode.java @@ -1,9 +1,10 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.*; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.type.*; -import java.util.BitSet; /** * CallEnd @@ -24,13 +25,12 @@ public class CallEndNode extends CFGNode implements MultiNode { public CallNode call() { return (CallNode)in(0); } @Override - 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 _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()).n(in(1)); } @Override diff --git a/chapter20/src/main/java/com/seaofnodes/simple/node/ConstantNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/ConstantNode.java index 5ddf47a1..cadb6511 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/ConstantNode.java +++ b/chapter20/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.Parser; import com.seaofnodes.simple.SB; import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeFunPtr; -import java.util.BitSet; /** * A Constant node represents a constant value. At present, the only constants @@ -35,18 +36,20 @@ public class ConstantNode extends Node { return new ConstantNode(type); } - @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 - 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.print(new SB())); + return p.p(_con.print(new SB())); } @Override public boolean isConst() { return true; } diff --git a/chapter20/src/main/java/com/seaofnodes/simple/node/CtrlNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/CtrlNode.java index 61d9c310..cf630ad4 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/CtrlNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/CtrlNode.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 CtrlNode extends CFGNode { public CtrlNode() { super(CodeGen.CODE._start); } @Override public String label() { return "Ctrl"; } - @Override 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/chapter20/src/main/java/com/seaofnodes/simple/node/DivFNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/DivFNode.java index 258720c8..149499f9 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/DivFNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/DivFNode.java @@ -1,21 +1,16 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeFloat; -import java.util.BitSet; public class DivFNode extends Node { public DivFNode(Node lhs, Node rhs) { super(null, lhs, rhs); } @Override public String label() { return "DivF"; } - @Override - StringBuilder _print1(StringBuilder sb, BitSet visited) { - in(1)._print0(sb.append("("), visited); - in(2)._print0(sb.append("/"), visited); - return sb.append(")"); - } + @Override protected String format() { return "(%1/%2)"; } @Override public Type compute() { diff --git a/chapter20/src/main/java/com/seaofnodes/simple/node/DivNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/DivNode.java index 69b151cd..f0ee21e1 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/DivNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/DivNode.java @@ -1,20 +1,15 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeInteger; -import java.util.BitSet; public class DivNode extends Node { public DivNode(Node lhs, Node rhs) { super(null, lhs, rhs); } @Override public String label() { return "Div"; } - @Override - StringBuilder _print1(StringBuilder sb, BitSet visited) { - in(1)._print0(sb.append("("), visited); - in(2)._print0(sb.append("/"), visited); - return sb.append(")"); - } + @Override protected String format() { return "(%1/%2)"; } @Override public Type compute() { diff --git a/chapter20/src/main/java/com/seaofnodes/simple/node/FRefNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/FRefNode.java index f0c4045d..bf1c5a00 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/FRefNode.java +++ b/chapter20/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 @@ -17,10 +18,9 @@ public class FRefNode extends ConstantNode { @Override public String label() { return "FRef"+_n; } - @Override public String uniqueName() { return "FRef_" + _nid; } - @Override StringBuilder _print1(StringBuilder sb, BitSet visited) { - return sb.append("FRef_").append(_n); + @Override protected ExprPrinter _print1(ExprPrinter p) { + return p.p("FRef_").p(_n); } @Override public Node idealize() { diff --git a/chapter20/src/main/java/com/seaofnodes/simple/node/IfNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/IfNode.java index e04522b0..2c4cad70 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/IfNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/IfNode.java @@ -1,9 +1,9 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.IterPeeps; import com.seaofnodes.simple.type.*; -import java.util.BitSet; import java.util.HashSet; public class IfNode extends CFGNode implements MultiNode { @@ -17,11 +17,7 @@ public class IfNode extends CFGNode implements MultiNode { @Override public String label() { return "If"; } - @Override - public StringBuilder _print1(StringBuilder sb, BitSet visited) { - sb.append("if( "); - return in(1)._print0(sb, visited).append(" )"); - } + @Override protected String format() { return "if( %1 )"; } public Node ctrl() { return in(0); } public Node pred() { return in(1); } diff --git a/chapter20/src/main/java/com/seaofnodes/simple/node/LoadNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/LoadNode.java index 76125e39..339e4460 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/LoadNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/LoadNode.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.Parser; import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.type.*; -import java.util.BitSet; /** * Load represents extracting a value from inside a memory object, @@ -46,7 +47,7 @@ public class LoadNode extends MemOpNode { // Debugger label @Override public String label() { return "ld_"+mlabel(); } @Override - 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/chapter20/src/main/java/com/seaofnodes/simple/node/LogicalNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/LogicalNode.java index 8c3452bf..6ac16d31 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/LogicalNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/LogicalNode.java @@ -1,9 +1,10 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeInteger; -import java.util.BitSet; public abstract class LogicalNode extends Node { // Source location for late reported errors @@ -12,11 +13,8 @@ public abstract class LogicalNode extends Node { public LogicalNode(Parser.Lexer loc, Node lhs, Node rhs) { super(null, lhs, rhs); _loc = loc; } abstract String op(); - @Override - 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(); } diff --git a/chapter20/src/main/java/com/seaofnodes/simple/node/MachConcreteNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/MachConcreteNode.java index b01b3308..4f5d9151 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/MachConcreteNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/MachConcreteNode.java @@ -1,9 +1,10 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.Utils; 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. @@ -16,12 +17,11 @@ public abstract class MachConcreteNode extends Node implements MachNode { @Override public Type compute () { throw Utils.TODO(); } @Override public Node idealize() { throw Utils.TODO(); } - @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 i=1; i _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/chapter20/src/main/java/com/seaofnodes/simple/node/MinusFNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/MinusFNode.java index 129963c2..852e646d 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/MinusFNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/MinusFNode.java @@ -1,20 +1,16 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeFloat; -import java.util.BitSet; public class MinusFNode extends Node { public MinusFNode(Node in) { super(null, in); } @Override public String label() { return "MinusF"; } - @Override - 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/chapter20/src/main/java/com/seaofnodes/simple/node/MinusNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/MinusNode.java index dad245fd..20220915 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/MinusNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/MinusNode.java @@ -1,21 +1,17 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeInteger; import com.seaofnodes.simple.Utils; -import java.util.BitSet; public class MinusNode extends Node { public MinusNode(Node in) { super(null, in); } @Override public String label() { return "Minus"; } - @Override - 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/chapter20/src/main/java/com/seaofnodes/simple/node/MulFNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/MulFNode.java index 4b753ba7..6a57f3c5 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/MulFNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/MulFNode.java @@ -1,21 +1,16 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeFloat; -import java.util.BitSet; public class MulFNode extends Node { public MulFNode(Node lhs, Node rhs) { super(null, lhs, rhs); } @Override public String label() { return "MulF"; } - @Override - StringBuilder _print1(StringBuilder sb, BitSet visited) { - in(1)._print0(sb.append("("), visited); - in(2)._print0(sb.append("*"), visited); - return sb.append(")"); - } + @Override protected String format() { return "(%1*%2)"; } @Override public Type compute() { diff --git a/chapter20/src/main/java/com/seaofnodes/simple/node/MulNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/MulNode.java index c7fb620c..e9dc6887 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/MulNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/MulNode.java @@ -1,21 +1,16 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeInteger; -import java.util.BitSet; public class MulNode extends Node { public MulNode(Node lhs, Node rhs) { super(null, lhs, rhs); } @Override public String label() { return "Mul"; } - @Override - StringBuilder _print1(StringBuilder sb, BitSet visited) { - in(1)._print0(sb.append("("), visited); - in(2)._print0(sb.append("*"), visited); - return sb.append(")"); - } + @Override protected String format() { return "(%1*%2)"; } @Override public Type compute() { diff --git a/chapter20/src/main/java/com/seaofnodes/simple/node/NeverNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/NeverNode.java index 26198500..7e42ccf9 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/NeverNode.java +++ b/chapter20/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 { @@ -13,7 +14,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/chapter20/src/main/java/com/seaofnodes/simple/node/NewNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/NewNode.java index b9c9de71..68871918 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/NewNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/NewNode.java @@ -1,7 +1,8 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.type.*; -import java.util.BitSet; /** Allocate a zeroed object. Inputs {ctrl, $mem, size}; * results {ptr, $mem}. @@ -34,10 +35,8 @@ public class NewNode extends Node implements MultiNode { @Override public String label() { return "new_"+(_ptr._obj.isAry() ? "ary_"+_ptr._obj._fields[1]._type.str() : _ptr._obj.str()); } - @Override - StringBuilder _print1(StringBuilder sb, BitSet visited) { - sb.append("new "); - return sb.append(_ptr._obj.str()); + @Override protected ExprPrinter _print1(ExprPrinter p) { + return p.p("new ").p(_ptr._obj.str()); } diff --git a/chapter20/src/main/java/com/seaofnodes/simple/node/Node.java b/chapter20/src/main/java/com/seaofnodes/simple/node/Node.java index aecac75c..e038d351 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/Node.java +++ b/chapter20/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.*; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.print.IRPrinter; @@ -15,14 +17,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. @@ -44,16 +39,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); @@ -65,8 +58,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.InstSelect.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; @@ -77,48 +70,6 @@ public abstract class Node implements Cloneable { // Easy reading label for debugger, e.g. "Add" or "Region" or "EQ" public abstract String label(); - // 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 StringBuilder _print1(StringBuilder sb, BitSet visited); - public String p(int depth) { return IRPrinter.prettyPrint(this,depth); } public boolean isConst() { return false; } @@ -126,6 +77,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 @@ -204,7 +157,6 @@ public abstract class Node implements Cloneable { return setDef(idx,new_def); } - /** * Add a new def to an existing Node. Keep the edges correct by * adding the corresponding def->use edge. @@ -280,7 +232,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; @@ -525,7 +476,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 @@ -570,7 +520,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 ) { @@ -588,7 +537,6 @@ public abstract class Node implements Cloneable { // and can assume "this!=n" and has the same Java class. 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 @@ -604,7 +552,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; @@ -624,7 +571,6 @@ public abstract class Node implements Cloneable { /** Is this Node Memory related */ public boolean isMem() { return false; } - // Semantic change to the graph (so NOT a peephole), used by the Parser. // If any input is a float, flip to a float-flavored opcode and widen any // non-float input. @@ -645,7 +591,6 @@ public abstract class Node implements Cloneable { } Node copyF() { return null; } - // ------------------------------------------------------------------------ // Peephole utilities @@ -672,7 +617,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/chapter20/src/main/java/com/seaofnodes/simple/node/NotNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/NotNode.java index 5e631b78..57fa9301 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/NotNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/NotNode.java @@ -1,19 +1,15 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.type.*; -import java.util.BitSet; public class NotNode extends Node { public NotNode(Node in) { super(null, in); } @Override public String label() { return "Not"; } - @Override - 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/chapter20/src/main/java/com/seaofnodes/simple/node/ParmNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/ParmNode.java index c7c21171..c3a0cf21 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/ParmNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/ParmNode.java @@ -1,8 +1,9 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.type.Type; -import java.util.BitSet; public class ParmNode extends PhiNode { @@ -20,18 +21,12 @@ public class ParmNode extends PhiNode { public FunNode fun() { return (FunNode)in(0); } @Override - StringBuilder _print1(StringBuilder sb, BitSet visited) { + protected ExprPrinter _print1(ExprPrinter p) { if( "main".equals(fun()._name) && _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/chapter20/src/main/java/com/seaofnodes/simple/node/PhiNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/PhiNode.java index 52298345..a752977b 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/PhiNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/PhiNode.java @@ -1,8 +1,9 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.*; import com.seaofnodes.simple.type.*; -import java.util.BitSet; public class PhiNode extends Node { @@ -31,18 +32,12 @@ public class PhiNode extends Node { @Override public String label() { return "Phi_"+MemOpNode.mlabel(_label); } @Override - 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/chapter20/src/main/java/com/seaofnodes/simple/node/ProjNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/ProjNode.java index 83044156..da5841f6 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/ProjNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/ProjNode.java @@ -1,10 +1,11 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeMem; import com.seaofnodes.simple.type.TypeTuple; -import java.util.BitSet; public class ProjNode extends Node { @@ -24,11 +25,11 @@ public class ProjNode extends Node { @Override public String label() { return _label; } @Override - 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/chapter20/src/main/java/com/seaofnodes/simple/node/ReadOnlyNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/ReadOnlyNode.java index b755af3f..d79f2815 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/ReadOnlyNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/ReadOnlyNode.java @@ -1,9 +1,9 @@ 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 @@ -13,10 +13,7 @@ public class ReadOnlyNode extends Node { public ReadOnlyNode( ReadOnlyNode n ) { super(n); } @Override public String label() { return "ReadOnly"; } - @Override - 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/chapter20/src/main/java/com/seaofnodes/simple/node/RegionNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/RegionNode.java index f28952e0..8993a49f 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/RegionNode.java +++ b/chapter20/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.*; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.type.Type; @@ -16,9 +18,8 @@ public class RegionNode extends CFGNode { @Override public String label() { return "Region"; } - @Override - 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/chapter20/src/main/java/com/seaofnodes/simple/node/ReturnNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/ReturnNode.java index 7858671c..e101ee09 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/ReturnNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/ReturnNode.java @@ -1,10 +1,11 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.SB; import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.type.*; -import java.util.BitSet; /** Keeps all preceding memory effects and the return value alive: {ctrl, $mem, value, rpc}. */ public class ReturnNode extends CFGNode { @@ -27,11 +28,11 @@ public class ReturnNode extends CFGNode { public String label() { return "Return"; } @Override - 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/chapter20/src/main/java/com/seaofnodes/simple/node/RoundF32Node.java b/chapter20/src/main/java/com/seaofnodes/simple/node/RoundF32Node.java index 3dd7cbf0..78e7698c 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/RoundF32Node.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/RoundF32Node.java @@ -1,19 +1,16 @@ 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 String label() { return "RoundF32"; } - @Override - 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/chapter20/src/main/java/com/seaofnodes/simple/node/ScopeNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/ScopeNode.java index 406be11f..2724d0a6 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/ScopeNode.java +++ b/chapter20/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.*; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.type.*; @@ -49,28 +51,26 @@ public class ScopeNode extends Node { @Override public String label() { return "Scope"; } @Override - 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(); } @Override public Type compute() { return in(0)._type; } @Override public Node idealize() { return null; } diff --git a/chapter20/src/main/java/com/seaofnodes/simple/node/StartNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/StartNode.java index 2783ab93..cbaefa6a 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/StartNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/StartNode.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.Parser; import com.seaofnodes.simple.type.*; -import java.util.BitSet; import java.util.HashSet; import static com.seaofnodes.simple.Utils.TODO; @@ -17,9 +18,8 @@ public class StartNode extends LoopNode implements MultiNode { @Override public String label() { return "Start"; } - @Override - 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/chapter20/src/main/java/com/seaofnodes/simple/node/StopNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/StopNode.java index 80c911ca..524c6a9e 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/StopNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/StopNode.java @@ -1,8 +1,9 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.type.Type; -import java.util.BitSet; public class StopNode extends CFGNode { @@ -21,13 +22,13 @@ public class StopNode extends CFGNode { } @Override - 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" - if( ret()!=null ) return ret()._print0(sb,visited); - sb.append("Stop[ "); + if( ret()!=null ) return p.n(ret()); + p.p("Stop[ "); for( Node ret : _inputs ) - ret._print0(sb, visited).append(" "); - return sb.append("]"); + p.n(ret).p(" "); + return p.p("]"); } @Override public boolean blockHead() { return true; } diff --git a/chapter20/src/main/java/com/seaofnodes/simple/node/StoreNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/StoreNode.java index 4833df39..e9a35a0d 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/StoreNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/StoreNode.java @@ -1,9 +1,10 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.codegen.*; import com.seaofnodes.simple.*; import com.seaofnodes.simple.type.*; -import java.util.BitSet; /** * Store represents setting a value to a memory based object, in chapter 10 @@ -36,8 +37,8 @@ public class StoreNode extends MemOpNode { public Node val() { return in(4); } @Override - 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/chapter20/src/main/java/com/seaofnodes/simple/node/StructNode.java b/chapter20/src/main/java/com/seaofnodes/simple/node/StructNode.java index 076b342a..b9801f63 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/StructNode.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/StructNode.java @@ -1,8 +1,9 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.SB; import com.seaofnodes.simple.type.*; -import java.util.BitSet; /** * Build a compound object @@ -14,16 +15,15 @@ public class StructNode extends Node { @Override public String label() { return _ts==null ? "STRUCT?" : _ts.str(); } @Override - StringBuilder _print1(StringBuilder sb, BitSet visited) { - if( _ts==null ) return sb.append("STRUCT?"); - sb.append(_ts._name).append(" {"); + protected ExprPrinter _print1(ExprPrinter p) { + if( _ts==null ) return p.p("STRUCT?"); + p.p(_ts._name).p(" {"); for( int i=0; i _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/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java b/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java index 4359c045..0f883847 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java @@ -34,7 +34,7 @@ public class CallARM extends CallNode implements MachNode { } @Override public void asm(CodeGen code, SB sb) { - sb.p(_name); + sb.p(_name).p(" "); for( int i=0; i _printMach(ExprPrinter p) { return p.p(".").p(_name); } @Override public boolean isMem() { return _type instanceof TypeMem; } diff --git a/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java b/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java index 6a1cf7dc..30dfd7fe 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java @@ -1,11 +1,12 @@ package com.seaofnodes.simple.node.cpus.riscv; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.*; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.codegen.RegMask; import com.seaofnodes.simple.node.*; import java.io.ByteArrayOutputStream; -import java.util.BitSet; // Conditional branch such as: BEQ public class BranchRISC extends IfNode implements MachNode { @@ -23,11 +24,11 @@ public class BranchRISC extends IfNode implements MachNode { @Override public RegMask regmap(int i) { return riscv.RMASK; } @Override public RegMask outregmap() { return null; } - @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { - in(1)._print0(sb.append("if( "),visited).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( ").n(in(1)).p(_bop); + if( in(2)==null ) p.p("0"); + else p.n(in(2)); + return p.p(" )"); } // Encoding is appended into the byte array; size is returned diff --git a/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java b/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java index 02191d05..330de299 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java @@ -1,11 +1,12 @@ package com.seaofnodes.simple.node.cpus.riscv; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.*; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.codegen.RegMask; import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.type.TypeInteger; -import java.util.BitSet; import java.io.ByteArrayOutputStream; public abstract class ImmRISC extends MachConcreteNode implements MachNode { @@ -21,9 +22,8 @@ public abstract class ImmRISC extends MachConcreteNode implements MachNode { // Register mask allowed as a result. 0 for no register. @Override public RegMask outregmap() { return riscv.WMASK; } - @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { - in(1)._print0(sb.append("( "), visited); - return sb.append(String.format(" %s #%d )",glabel(),_imm)); + @Override protected ExprPrinter _print1(ExprPrinter p) { + return p.p("( ").n(in(1)).p(String.format(" %s #%d )",glabel(),_imm)); } abstract int opcode(); diff --git a/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java b/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java index 01f51b57..19869285 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java @@ -1,5 +1,7 @@ package com.seaofnodes.simple.node.cpus.riscv; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.*; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.codegen.RegMask; @@ -7,7 +9,6 @@ import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.type.*; import java.io.ByteArrayOutputStream; import java.lang.StringBuilder; -import java.util.BitSet; public class MemOpRISC extends MemOpNode implements MachNode { @@ -31,7 +32,7 @@ public class MemOpRISC 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 boolean isMem() { return _type instanceof TypeMem; } diff --git a/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemOpX86.java b/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemOpX86.java index 1a771081..e74de677 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemOpX86.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemOpX86.java @@ -1,5 +1,7 @@ package com.seaofnodes.simple.node.cpus.x86_64_v2; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.*; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.codegen.RegMask; @@ -7,7 +9,6 @@ import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.type.*; import java.io.ByteArrayOutputStream; 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 boolean isMem() { return _type instanceof TypeMem; } diff --git a/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java b/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java index 024ef904..08d481fa 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/StoreX86.java @@ -1,11 +1,12 @@ package com.seaofnodes.simple.node.cpus.x86_64_v2; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.SB; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.codegen.RegMask; import com.seaofnodes.simple.node.Node; import com.seaofnodes.simple.node.StoreNode; -import java.util.BitSet; public class StoreX86 extends MemOpX86 { StoreX86( StoreNode st, Node base, Node idx, int off, int scale, int imm, Node val ) { @@ -14,12 +15,12 @@ public class StoreX86 extends MemOpX86 { @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. diff --git a/chapter20/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java b/chapter20/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java index 1a233aa2..a4f768c5 100644 --- a/chapter20/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java +++ b/chapter20/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java @@ -1,163 +1,53 @@ package com.seaofnodes.simple.print; +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.SB; import com.seaofnodes.simple.node.*; -import com.seaofnodes.simple.type.TypeFunPtr; -import com.seaofnodes.simple.type.TypeMem; -import com.seaofnodes.simple.type.TypeRPC; - -public abstract class ASMPrinter { - +import com.seaofnodes.simple.type.*; +import java.util.ArrayList; + +/** Machine-specific facts; traversal, columns and byte display live in print/. */ +public final class ASMPrinter extends AssemblyAdapter { + private final CodeGen _code; + private ASMPrinter(CodeGen code) { + super(new IRPrinter()); + _code=code; + } public static SB print(SB sb, CodeGen code) { - if( code._cfg==null ) - return sb.p("Need _cfg set, run after GCM"); - - // instruction address - int iadr = 0; - for( int i=0; i(new ASMPrinter(code)).print()); } - - private static int print(int iadr, SB sb, CodeGen code, 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(); - - - while( !(code._cfg.at(cfgidx) instanceof ReturnNode) ) - iadr = doBlock(iadr,sb,code,fun,cfgidx++); - - // Function separator - sb.p("---"); - fun.sig().print(sb); - sb.p("---------------------------").nl(); - return iadr; + @Override public ArrayList blocks() { + var blocks=new ArrayList(); + var cfg=_code._cfg; + if( cfg!=null ) for( Node n : cfg ) blocks.add(n); + return blocks; } - - static private final int encWidth = 8; - static private final int opWidth = 5; - static private final int argWidth = 30; - static int doBlock(int iadr, SB sb, CodeGen code, FunNode fun, int cfgidx) { - CFGNode bb = code._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(bb instanceof LoopNode ? "LOOP" : "L").p(bb._nid).p(":").nl(); - if( bb instanceof CallNode ) return iadr; - final boolean postAlloc = code._phase.ordinal() > CodeGen.Phase.RegAlloc.ordinal(); - - // Count Phis - int nPhi=0; - for( ; nPhi0 ) { - // Post-alloc phi prints all on one line - if( postAlloc ) { - sb.fix(4," ").p(" ").fix(encWidth,"").p(" "); - for( int i=0; i