diff options
| author | Cliff Click <cliffc@acm.org> | 2023-10-30 10:15:49 -0700 |
|---|---|---|
| committer | Dibyendu Majumdar <dibyendumajumdar@users.noreply.github.com> | 2023-11-01 18:56:50 +0000 |
| commit | 7aca34858eb886677bc179658a6fffbb5ae54f66 (patch) | |
| tree | 72b58e82eb05bbc43f8589bcfd9caf31d9c08909 /chapter05/src/main/java | |
| parent | 4410e4e3d7a4b9e0424de7678633e2a7240695cd (diff) | |
| download | Simple-7aca34858eb886677bc179658a6fffbb5ae54f66.tar.gz Simple-7aca34858eb886677bc179658a6fffbb5ae54f66.zip | |
Lots of improvements to graphviz
Merging common edges.
Phis of same Region align.
Phis use greek phi, and have a debug name. Scope carries the debug name. Phis are lightly colored.
Common math names for math prims.
Parse can optionally show the graph after closing the last scope.
Diffstat (limited to 'chapter05/src/main/java')
13 files changed, 75 insertions, 56 deletions
diff --git a/chapter05/src/main/java/com/seaofnodes/simple/GraphVisualizer.java b/chapter05/src/main/java/com/seaofnodes/simple/GraphVisualizer.java index 79d98792..903a0684 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/GraphVisualizer.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/GraphVisualizer.java @@ -32,6 +32,10 @@ public class GraphVisualizer { // Preserve node input order sb.append("\tordering=\"in\";\n"); + + // Merge multiple edges hitting the same node. Makes common shared + // nodes much prettier to look at. + sb.append("\tconcentrate=\"true\";\n"); // Just the Nodes first, in a cluster no edges nodes(sb, all); @@ -59,7 +63,7 @@ public class GraphVisualizer { if( n instanceof ProjNode || n instanceof ScopeNode ) continue; // Do not emit, rolled into MultiNode or Scope cluster already sb.append("\t\t").append(n.uniqueName()).append(" [ "); - String lab = n.label(); + String lab = n.glabel(); if( n instanceof MultiNode ) { // Make a box with the MultiNode on top, and all the projections on the bottom sb.append("shape=plaintext label=<\n"); @@ -77,7 +81,7 @@ public class GraphVisualizer { } sb.append("<TD PORT=\"p").append(proj._idx).append("\""); if( proj.isCFG() ) sb.append(" BGCOLOR=\"yellow\""); - sb.append(">").append(proj.label()).append("</TD>"); + sb.append(">").append(proj.glabel()).append("</TD>"); } } if (doProjTable) { @@ -93,10 +97,24 @@ public class GraphVisualizer { // other nodes are ellipses, i.e. default shape if( n.isCFG() ) sb.append("shape=box style=filled fillcolor=yellow "); + if( n instanceof PhiNode ) + sb.append("style=filled fillcolor=lightyellow "); sb.append("label=\"").append(lab).append("\" "); } sb.append("];\n"); } + + // Force Region & Phis to line up + for( Node n : all ) { + if( n instanceof RegionNode region ) { + sb.append("\t\t{ rank=same; "); + for( Node phi : region._outputs ) + if( phi instanceof PhiNode ) + sb.append(phi.uniqueName()).append(";"); + sb.append("}\n"); + } + } + sb.append("\t}\n"); // End Node cluster } diff --git a/chapter05/src/main/java/com/seaofnodes/simple/Parser.java b/chapter05/src/main/java/com/seaofnodes/simple/Parser.java index 92b1f0d5..9993c48c 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/Parser.java @@ -86,7 +86,8 @@ public class Parser { private Node ctrl(Node n) { return _scope.ctrl(n); } - public StopNode parse() { + public StopNode parse() { return parse(false); } + public StopNode parse(boolean show) { _allScopes.push(_scope); _scope.push(); try { @@ -98,6 +99,7 @@ public class Parser { finally { _scope.pop(); _allScopes.pop(); + if( show ) showGraph(); } } @@ -135,7 +137,7 @@ public class Parser { else if (matchx("int")) return parseDecl(); else if (match ("{" )) return parseBlock(); else if (matchx("if" )) return parseIf(); - else if (matchx("#showGraph")) return showGraph(); + else if (matchx("#showGraph")) return require(showGraph(),";"); else return parseExpressionStatement(); } @@ -203,7 +205,6 @@ public class Parser { * @return {@code null} */ private Node showGraph() { - require(";"); System.out.println(new GraphVisualizer().generateDotOutput(this)); return null; } diff --git a/chapter05/src/main/java/com/seaofnodes/simple/node/AddNode.java b/chapter05/src/main/java/com/seaofnodes/simple/node/AddNode.java index 1e9cc6c9..e4ed83a6 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/AddNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/AddNode.java @@ -3,12 +3,11 @@ package com.seaofnodes.simple.node; import com.seaofnodes.simple.type.*; public class AddNode extends Node { - public AddNode(Node lhs, Node rhs) { - super(null, lhs, rhs); - } + public AddNode(Node lhs, Node rhs) { super(null, lhs, rhs); } - @Override - public String label() { return "Add"; } + @Override public String label() { return "Add"; } + + @Override public String glabel() { return "+"; } @Override StringBuilder _print1(StringBuilder sb) { @@ -87,7 +86,8 @@ public class AddNode extends Node { // Push constant up through the phi: x + (phi con0+con0 con1+con1...) for( int i=1; i<ns.length; i++ ) ns[i] = new AddNode(phi.in(i),t2.isConstant() ? rhs : rhs.in(i)).peephole(); - return new AddNode(lhs.in(1),new PhiNode(ns).peephole()); + String label = phi._label + (rhs instanceof PhiNode rphi ? rphi._label : ""); + return new AddNode(lhs.in(1),new PhiNode(label,ns).peephole()); } // Now we sort along the spline via rotates, to gather similar things together. diff --git a/chapter05/src/main/java/com/seaofnodes/simple/node/BoolNode.java b/chapter05/src/main/java/com/seaofnodes/simple/node/BoolNode.java index 250231f9..02eb7ce9 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/BoolNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/BoolNode.java @@ -16,6 +16,9 @@ abstract public class BoolNode extends Node { public String label() { return getClass().getSimpleName(); } @Override + public String glabel() { return op(); } + + @Override StringBuilder _print1(StringBuilder sb) { in(1)._print0(sb.append("(")); in(2)._print0(sb.append(op())); diff --git a/chapter05/src/main/java/com/seaofnodes/simple/node/DivNode.java b/chapter05/src/main/java/com/seaofnodes/simple/node/DivNode.java index 1f562378..ae87deac 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/DivNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/DivNode.java @@ -5,13 +5,12 @@ import com.seaofnodes.simple.type.TypeBot; import com.seaofnodes.simple.type.TypeInteger; public class DivNode extends Node { - public DivNode(Node lhs, Node rhs) { - super(null, lhs, rhs); - } + public DivNode(Node lhs, Node rhs) { super(null, lhs, rhs); } + + @Override public String label() { return "Div"; } + + @Override public String glabel() { return "//"; } - @Override - public String label() { return "Div"; } - @Override StringBuilder _print1(StringBuilder sb) { in(1)._print0(sb.append("(")); diff --git a/chapter05/src/main/java/com/seaofnodes/simple/node/MinusNode.java b/chapter05/src/main/java/com/seaofnodes/simple/node/MinusNode.java index 04084d0f..834f4c11 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/MinusNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/MinusNode.java @@ -5,12 +5,11 @@ import com.seaofnodes.simple.type.TypeBot; import com.seaofnodes.simple.type.TypeInteger; public class MinusNode extends Node { - public MinusNode(Node in) { - super(null, in); - } + public MinusNode(Node in) { super(null, in); } - @Override - public String label() { return "Minus"; } + @Override public String label() { return "Minus"; } + + @Override public String glabel() { return "-"; } @Override StringBuilder _print1(StringBuilder sb) { diff --git a/chapter05/src/main/java/com/seaofnodes/simple/node/MulNode.java b/chapter05/src/main/java/com/seaofnodes/simple/node/MulNode.java index e3e83b38..dcc21b2e 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/MulNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/MulNode.java @@ -5,12 +5,11 @@ import com.seaofnodes.simple.type.TypeBot; import com.seaofnodes.simple.type.TypeInteger; public class MulNode extends Node { - public MulNode(Node lhs, Node rhs) { - super(null, lhs, rhs); - } + public MulNode(Node lhs, Node rhs) { super(null, lhs, rhs); } - @Override - public String label() { return "Mul"; } + @Override public String label() { return "Mul"; } + + @Override public String glabel() { return "*"; } @Override StringBuilder _print1(StringBuilder sb) { diff --git a/chapter05/src/main/java/com/seaofnodes/simple/node/MultiNode.java b/chapter05/src/main/java/com/seaofnodes/simple/node/MultiNode.java index 28d054a6..fe3fddf8 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/MultiNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/MultiNode.java @@ -4,8 +4,6 @@ import com.seaofnodes.simple.type.Type; public abstract class MultiNode extends Node { - public MultiNode(Node... inputs) { - super(inputs); - } + public MultiNode(Node... inputs) { super(inputs); } } diff --git a/chapter05/src/main/java/com/seaofnodes/simple/node/Node.java b/chapter05/src/main/java/com/seaofnodes/simple/node/Node.java index dc4d7a33..e34b4cd5 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/Node.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/Node.java @@ -62,10 +62,15 @@ public abstract class Node { n._outputs.add( this ); } + // Easy reading label for debugger, e.g. "Add" or "Region" or "EQ" public abstract String label(); + // Unique label for graph visualization, e.g. "Add12" or "Region30" or "EQ99" public String uniqueName() { return label() + _nid; } + // Graphical label, e.g. "+" or "Region" or "==" + public String glabel() { return label(); } + @Override public final String toString() { // TODO: This needs a lot of work diff --git a/chapter05/src/main/java/com/seaofnodes/simple/node/PhiNode.java b/chapter05/src/main/java/com/seaofnodes/simple/node/PhiNode.java index 8e0c9a79..5eb110e7 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/PhiNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/PhiNode.java @@ -5,14 +5,13 @@ import com.seaofnodes.simple.type.TypeBot; public class PhiNode extends Node { - public PhiNode(Node... inputs) { - super(inputs); - } + final String _label; + + public PhiNode(String label, Node... inputs) { super(inputs); _label = label; } - @Override - public String label() { - return "Phi"; - } + @Override public String label() { return "Phi_"+_label; } + + @Override public String glabel() { return "φ_"+_label; } @Override StringBuilder _print1(StringBuilder sb) { @@ -48,8 +47,8 @@ public class PhiNode extends Node { lhss[i] = in(i).in(1); rhss[i] = in(i).in(2); } - Node phi_lhs = new PhiNode(lhss).peephole(); - Node phi_rhs = new PhiNode(rhss).peephole(); + Node phi_lhs = new PhiNode(_label,lhss).peephole(); + Node phi_rhs = new PhiNode(_label,rhss).peephole(); return op.copy(phi_lhs,phi_rhs); } diff --git a/chapter05/src/main/java/com/seaofnodes/simple/node/RegionNode.java b/chapter05/src/main/java/com/seaofnodes/simple/node/RegionNode.java index d29cbd57..ae8724b9 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/RegionNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/RegionNode.java @@ -4,14 +4,10 @@ import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeControl; public class RegionNode extends Node { - public RegionNode(Node... inputs) { - super(inputs); - } + public RegionNode(Node... inputs) { super(inputs); } @Override - public String label() { - return "Region"; - } + public String label() { return "Region"; } @Override StringBuilder _print1(StringBuilder sb) { diff --git a/chapter05/src/main/java/com/seaofnodes/simple/node/ScopeNode.java b/chapter05/src/main/java/com/seaofnodes/simple/node/ScopeNode.java index b3cca3da..b854c627 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/ScopeNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/ScopeNode.java @@ -18,8 +18,10 @@ public class ScopeNode extends Node { */ public final Stack<HashMap<String, Integer>> _scopes = new Stack<>(); - @Override - public String label() { return "Scope"; } + // Reverse lookup for nicer graph printing + private final ArrayList<String> _rlabels = new ArrayList<>(); + + @Override public String label() { return "Scope"; } @Override StringBuilder _print1(StringBuilder sb) { @@ -43,8 +45,7 @@ public class ScopeNode extends Node { @Override public TypeBot compute() { return TypeBot.BOTTOM; } - @Override - public Node idealize() { return null; } + @Override public Node idealize() { return null; } // Add an empty lexical scope public HashMap<String, Integer> push() { @@ -62,6 +63,7 @@ public class ScopeNode extends Node { HashMap<String,Integer> scope = _scopes.lastElement(); if( scope.put(name,nIns()) != null ) return null; // Double define + _rlabels.add(name); return add_def(n); } @@ -105,9 +107,10 @@ public class ScopeNode extends Node { public ScopeNode dup() { ScopeNode dup = new ScopeNode(); for( HashMap<String, Integer> tab : _scopes ) - dup._scopes.push(new HashMap<String, Integer>(tab)); + dup._scopes.push(new HashMap<>(tab)); for( int i=0; i<nIns(); i++ ) dup.add_def(in(i)); + dup._rlabels.addAll(_rlabels); return dup; } @@ -115,7 +118,7 @@ public class ScopeNode extends Node { RegionNode r = (RegionNode)ctrl(new RegionNode(ctrl(), that.ctrl()).peephole()); for( int i=1; i<nIns(); i++ ) if( in(1) != that.in(i) ) // No need for redundant Phis - set_def(i,new PhiNode(r, in(i), that.in(i)).peephole()); + set_def(i,new PhiNode(_rlabels.get(i), r, in(i), that.in(i)).peephole()); that.kill(); // Kill merged scope return r; } diff --git a/chapter05/src/main/java/com/seaofnodes/simple/node/SubNode.java b/chapter05/src/main/java/com/seaofnodes/simple/node/SubNode.java index e5939e1b..42ddc1c1 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/SubNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/SubNode.java @@ -5,12 +5,11 @@ import com.seaofnodes.simple.type.TypeBot; import com.seaofnodes.simple.type.TypeInteger; public class SubNode extends Node { - public SubNode(Node lhs, Node rhs) { - super(null, lhs, rhs); - } + public SubNode(Node lhs, Node rhs) { super(null, lhs, rhs); } - @Override - public String label() { return "Sub"; } + @Override public String label() { return "Sub"; } + + @Override public String glabel() { return "-"; } @Override StringBuilder _print1(StringBuilder sb) { |
