diff options
| author | Cliff Click <cliffc@acm.org> | 2026-10-01 12:01:57 -0700 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2026-10-01 12:01:57 -0700 |
| commit | 5ea32e69433d0c850d02bbc1e6c4a260bc095fec (patch) | |
| tree | ba4917ded278097332ee8f9f33227be74d3ac104 /chapter04 | |
| parent | bf7f603dd4e8ec781fe578243cdc18180322420b (diff) | |
| download | Simple-5ea32e69433d0c850d02bbc1e6c4a260bc095fec.tar.gz Simple-5ea32e69433d0c850d02bbc1e6c4a260bc095fec.zip | |
Move debug printing into shared space
Same as the graph viewer, moves a lot of code out of all Nodes
Diffstat (limited to 'chapter04')
16 files changed, 63 insertions, 129 deletions
diff --git a/chapter04/Makefile b/chapter04/Makefile index 060e0cfd..9648e939 100644 --- a/chapter04/Makefile +++ b/chapter04/Makefile @@ -37,6 +37,7 @@ main_javas := $(wildcard $(SRC)/$(SIMPLE)/*java $(SRC)/$(SIMPLE)/*/*java) test_javas := $(wildcard $(TST)/$(SIMPLE)/*java $(TST)/$(SIMPLE)/*/*java) main_classes := $(patsubst $(SRC)/%java,$(CLZDIR)/main/%class,$(main_javas)) include $(firstword $(wildcard ../graph/graph.mk graph/graph.mk)) +include $(firstword $(wildcard ../print/print.mk print/print.mk)) test_classes := $(patsubst $(TST)/%java,$(CLZDIR)/test/%class,$(test_javas)) test_cp := $(patsubst $(TST)/$(SIMPLE)/%.java,com.seaofnodes.simple.%,$(wildcard $(TST)/$(SIMPLE)/*Test.java)) classes = $(main_classes) $(test_classes) @@ -57,7 +58,7 @@ default: $(default_targets) build: $(main_classes) # Compile just the out-of-date files -$(main_classes): $(CLZDIR)/main/%class: $(SRC)/%java $(graph_javas) +$(main_classes): $(CLZDIR)/main/%class: $(SRC)/%java $(graph_javas) $(print_javas) @echo "compiling " $@ " because " $? @[ -d $(CLZDIR)/main ] || mkdir -p $(CLZDIR)/main @javac $(JAVAC_ARGS) -cp "$(CLZDIR)/main$(SEP)$(jars)" -sourcepath $(SRC) -d $(CLZDIR)/main $(main_javas) diff --git a/chapter04/pom.xml b/chapter04/pom.xml index 5b9c7c6e..a2f3b26a 100644 --- a/chapter04/pom.xml +++ b/chapter04/pom.xml @@ -13,5 +13,6 @@ <name>Chapter 4</name> <properties> <simple.graph.directory>${project.basedir}/../graph</simple.graph.directory> + <simple.print.directory>${project.basedir}/../print</simple.print.directory> </properties> </project> diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/AddNode.java b/chapter04/src/main/java/com/seaofnodes/simple/node/AddNode.java index 0291a900..2fa4514e 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/AddNode.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/node/AddNode.java @@ -1,5 +1,6 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.type.*; public class AddNode extends Node { @@ -7,12 +8,7 @@ public class AddNode extends Node { @Override public String label() { return "Add"; } - @Override - StringBuilder _print1(StringBuilder sb) { - in(1)._print0(sb.append("(")); - in(2)._print0(sb.append("+")); - return sb.append(")"); - } + @Override protected String format() { return "(%1+%2)"; } @Override diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/BoolNode.java b/chapter04/src/main/java/com/seaofnodes/simple/node/BoolNode.java index 143a6fde..4c79fa0b 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/BoolNode.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/node/BoolNode.java @@ -1,5 +1,7 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeInteger; @@ -14,11 +16,8 @@ abstract public class BoolNode extends Node { @Override public String label() { return getClass().getSimpleName(); } - @Override - StringBuilder _print1(StringBuilder sb) { - in(1)._print0(sb.append("(")); - in(2)._print0(sb.append(op())); - return sb.append(")"); + @Override protected ExprPrinter<Node> _print1(ExprPrinter<Node> p) { + return p.open().n(in(1)).p(op()).n(in(2)).close(); } @Override diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/ConstantNode.java b/chapter04/src/main/java/com/seaofnodes/simple/node/ConstantNode.java index 85277d82..5efe29b7 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/ConstantNode.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/node/ConstantNode.java @@ -1,5 +1,7 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.type.Type; @@ -22,15 +24,16 @@ public class ConstantNode extends Node { _con = type; } - @Override - public String label() { return ""+_con; } + @Override protected String repeatName() { + return _con==null || _con.toString().length()<=32 ? null : uniqueName(); + } @Override - public String uniqueName() { return "Con_" + _nid; } + public String label() { return "Con"; } - @Override - StringBuilder _print1(StringBuilder sb) { - return _con.print(sb); + + @Override protected ExprPrinter<Node> _print1(ExprPrinter<Node> p) { + return p.p(_con); } @Override diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/DivNode.java b/chapter04/src/main/java/com/seaofnodes/simple/node/DivNode.java index bffa4b44..08dea003 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/DivNode.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/node/DivNode.java @@ -1,5 +1,6 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeInteger; @@ -8,12 +9,7 @@ public class DivNode extends Node { @Override public String label() { return "Div"; } - @Override - StringBuilder _print1(StringBuilder sb) { - in(1)._print0(sb.append("(")); - in(2)._print0(sb.append("/")); - return sb.append(")"); - } + @Override protected String format() { return "(%1/%2)"; } @Override public Type compute() { diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/MinusNode.java b/chapter04/src/main/java/com/seaofnodes/simple/node/MinusNode.java index ad6e513a..bb5f155d 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/MinusNode.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/node/MinusNode.java @@ -1,5 +1,6 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeInteger; @@ -8,11 +9,7 @@ public class MinusNode extends Node { @Override public String label() { return "Minus"; } - @Override - StringBuilder _print1(StringBuilder sb) { - in(1)._print0(sb.append("(-")); - return sb.append(")"); - } + @Override protected String format() { return "(-%1)"; } @Override public Type compute() { diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/MulNode.java b/chapter04/src/main/java/com/seaofnodes/simple/node/MulNode.java index 60103b8b..e866cf24 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/MulNode.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/node/MulNode.java @@ -1,5 +1,6 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeInteger; @@ -8,12 +9,7 @@ public class MulNode extends Node { @Override public String label() { return "Mul"; } - @Override - StringBuilder _print1(StringBuilder sb) { - in(1)._print0(sb.append("(")); - in(2)._print0(sb.append("*")); - return sb.append(")"); - } + @Override protected String format() { return "(%1*%2)"; } @Override public Type compute() { diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/Node.java b/chapter04/src/main/java/com/seaofnodes/simple/node/Node.java index fdde869b..bd72c8e4 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/Node.java +++ b/chapter04/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.Parser; import com.seaofnodes.simple.Utils; import com.seaofnodes.simple.type.Type; @@ -10,14 +12,7 @@ import java.util.*; * The Node class provides common functionality used by all subtypes. * Subtypes of Node specialize by overriding methods. */ -public abstract class Node { - - /** - * 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 final int _nid; +public abstract class Node extends BaseNode<Node> { /** * Inputs to the node. These are use-def references to Nodes. @@ -39,7 +34,6 @@ public abstract class Node { */ public final ArrayList<Node> _outputs; - /** * Current computed type for this Node. This value changes as the graph * changes and more knowledge is gained about the program. @@ -54,7 +48,7 @@ public abstract class Node { private static int UNIQUE_ID = 1; protected Node(Node... inputs) { - _nid = UNIQUE_ID++; // allocate unique dense ID + super(UNIQUE_ID++); // allocate unique dense ID _inputs = new ArrayList<>(); Collections.addAll(_inputs,inputs); _outputs = new ArrayList<>(); @@ -66,36 +60,7 @@ public abstract class Node { // 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; } - - // ------------------------------------------------------------------------ - - // 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. This version will fail on cycles, which we will - // correct later when we can parse programs with loops. We print with a - // tik-tok style; the common _print0 calls the per-Node _print1, which - // calls back to _print0; - public final String print() { - return _print0(new StringBuilder()).toString(); - } - // This is the common print: check for DEAD and print "DEAD" else call the - // per-Node print1. - final StringBuilder _print0(StringBuilder sb) { - return isDead() - ? sb.append(uniqueName()).append(":DEAD") - : _print1(sb); - } - // Every Node implements this. - abstract StringBuilder _print1(StringBuilder sb); - + @Override public String typeName() { return _type==null ? null : _type.toString(); } /** * Gets the ith input node @@ -112,8 +77,6 @@ public abstract class Node { public boolean isUnused() { return nOuts() == 0; } - public boolean isCFG() { return false; } - /** * Change a <em>def</em> into a Node. Keeps the edges correct, by removing * the corresponding <em>use->def</em> edge. This may make the original @@ -334,7 +297,6 @@ public abstract class Node { */ public abstract Node idealize(); - // ------------------------------------------------------------------------ // Peephole utilities diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/NotNode.java b/chapter04/src/main/java/com/seaofnodes/simple/node/NotNode.java index 6a56ff64..a9781ce1 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/NotNode.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/node/NotNode.java @@ -1,5 +1,6 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeInteger; @@ -8,11 +9,7 @@ public class NotNode extends Node { @Override public String label() { return "Not"; } - @Override - StringBuilder _print1(StringBuilder sb) { - in(1)._print0(sb.append("(!")); - return sb.append(")"); - } + @Override protected String format() { return "(!%1)"; } @Override public Type compute() { diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/ProjNode.java b/chapter04/src/main/java/com/seaofnodes/simple/node/ProjNode.java index 2f49fe91..063f9edc 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/ProjNode.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/node/ProjNode.java @@ -1,5 +1,7 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeTuple; @@ -21,7 +23,7 @@ public class ProjNode extends Node { public String label() { return _label; } @Override - StringBuilder _print1(StringBuilder sb) { return sb.append(_label); } + protected ExprPrinter<Node> _print1(ExprPrinter<Node> p) { return p.p(_label); } @Override public boolean isCFG() { return _idx==0; } diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/ReturnNode.java b/chapter04/src/main/java/com/seaofnodes/simple/node/ReturnNode.java index c9d6c9c8..c5dc532d 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/ReturnNode.java +++ b/chapter04/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.type.*; /** @@ -24,8 +26,8 @@ public class ReturnNode extends Node { public String label() { return "Return"; } @Override - StringBuilder _print1(StringBuilder sb) { - return expr()._print0(sb.append("return ")).append(";"); + protected ExprPrinter<Node> _print1(ExprPrinter<Node> p) { + return p.p("return ").n(expr()).p(";"); } @Override public boolean isCFG() { return true; } diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/ScopeNode.java b/chapter04/src/main/java/com/seaofnodes/simple/node/ScopeNode.java index 8ffeac64..6ffa8939 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/ScopeNode.java +++ b/chapter04/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.type.Type; import java.util.*; @@ -33,22 +35,22 @@ public class ScopeNode extends Node { @Override public String label() { return "Scope"; } @Override - StringBuilder _print1(StringBuilder sb) { - sb.append(label()); + protected ExprPrinter<Node> _print1(ExprPrinter<Node> p) { + p.p(label()); for( HashMap<String,Integer> scope : _scopes ) { - sb.append("["); + p.p("["); boolean first=true; for( String name : scope.keySet() ) { - if( !first ) sb.append(", "); + if( !first ) p.p(", "); first=false; - sb.append(name).append(":"); + p.p(name).p(":"); Node n = in(scope.get(name)); - if( n==null ) sb.append("null"); - else n._print0(sb); + if( n==null ) p.p("null"); + else p.n(n); } - sb.append("]"); + p.p("]"); } - return sb; + return p; } /** diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/StartNode.java b/chapter04/src/main/java/com/seaofnodes/simple/node/StartNode.java index 022e276d..c9f53abd 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/StartNode.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/node/StartNode.java @@ -1,5 +1,7 @@ package com.seaofnodes.simple.node; +import com.seaofnodes.print.ExprPrinter; + import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeTuple; @@ -23,9 +25,8 @@ public class StartNode extends MultiNode { @Override public String label() { return "Start"; } - @Override - StringBuilder _print1(StringBuilder sb) { - return sb.append(label()); + @Override protected ExprPrinter<Node> _print1(ExprPrinter<Node> p) { + return p.p(label()); } @Override public boolean isCFG() { return true; } diff --git a/chapter04/src/main/java/com/seaofnodes/simple/node/SubNode.java b/chapter04/src/main/java/com/seaofnodes/simple/node/SubNode.java index c831a798..43e684a1 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/node/SubNode.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/node/SubNode.java @@ -1,5 +1,6 @@ package com.seaofnodes.simple.node; + import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeInteger; @@ -8,12 +9,7 @@ public class SubNode extends Node { @Override public String label() { return "Sub"; } - @Override - StringBuilder _print1(StringBuilder sb) { - in(1)._print0(sb.append("(")); - in(2)._print0(sb.append("-")); - return sb.append(")"); - } + @Override protected String format() { return "(%1-%2)"; } @Override public Type compute() { diff --git a/chapter04/src/main/java/com/seaofnodes/simple/print/SimpleGraphAdapter.java b/chapter04/src/main/java/com/seaofnodes/simple/print/SimpleGraphAdapter.java index a0ad7be0..b68012dc 100644 --- a/chapter04/src/main/java/com/seaofnodes/simple/print/SimpleGraphAdapter.java +++ b/chapter04/src/main/java/com/seaofnodes/simple/print/SimpleGraphAdapter.java @@ -1,39 +1,22 @@ package com.seaofnodes.simple.print; import com.seaofnodes.graph.GraphAdapter; -import com.seaofnodes.graph.GraphSnapshot; import com.seaofnodes.graph.GraphSnapshot.*; import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.node.Node; -import java.util.ArrayList; /** Chapter 4's view of the IR; no knowledge of browser, transport or layout. */ public class SimpleGraphAdapter extends GraphAdapter<Node> { - @Override protected boolean dead(Node n) { return n.isDead(); } - @Override protected int id(Node n) { return n._nid; } - @Override protected int nIns(Node n) { return n.nIns(); } - @Override protected Node in(Node n, int idx) { return n.in(idx); } - @Override protected int nOuts(Node n) { return n.nOuts(); } - @Override protected Node out(Node n, int idx) { return n.out(idx); } - private ArrayList<Edge> edges(Node n) { - String[] names = n instanceof ScopeNode scope && n.nIns() != 0 ? scope.reverseNames() : null; - var edges = new ArrayList<Edge>(); - for( int i = 0; i < n.nIns(); i++ ) { - Role role = n instanceof ScopeNode || n instanceof ConstantNode ? Role.ASSOC - : n instanceof ProjNode ? (n.isCFG() ? Role.CTRL : Role.DATA) - : i == 0 ? Role.CTRL : Role.DATA; - edges.add(new Edge(i, ref(n.in(i)), role, names == null ? null : names[i])); - } - return edges; + @Override protected String[] edgeNames(Node n) { + return n instanceof ScopeNode scope && n.nIns()!=0 ? scope.reverseNames() : null; } + @Override protected int projectionIndex(Node n) { return n instanceof ProjNode p ? p._idx : -1; } - @Override protected GraphSnapshot.Node desc(Node n) { - Projection proj = n instanceof ProjNode p - ? new Projection(n.nIns() == 0 ? 0 : ref(n.in(0)), p._idx) : null; - Kind kind = n instanceof ScopeNode ? Kind.SCOPE : n.isCFG() ? Kind.CTRL : Kind.DATA; - String label = n.label(); - return new GraphSnapshot.Node(n._nid, label == null ? n.getClass().getSimpleName() : label, - n._type == null ? null : n._type.toString(), kind, edges(n), proj); + @Override protected Kind kind(Node n) { return n instanceof ScopeNode ? Kind.SCOPE : n.isCFG() ? Kind.CTRL : Kind.DATA; } + @Override protected Role role(Node n, int i) { + return n instanceof ScopeNode || n instanceof ConstantNode ? Role.ASSOC + : n instanceof ProjNode ? (n.isCFG() ? Role.CTRL : Role.DATA) + : i==0 ? Role.CTRL : Role.DATA; } } |
