summaryrefslogtreecommitdiff
path: root/chapter25/src/main/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'chapter25/src/main/java/com')
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java15
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/AndNode.java2
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/ArithNode.java1
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/BoolNode.java6
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/ConFldOffNode.java1
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/ConstantNode.java1
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/ExternNode.java1
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/FldOffNode.java1
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/FunPtrNode.java1
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/LoadNode.java5
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/MinusNode.java1
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/NewNode.java5
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/Node.java8
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/NotNode.java2
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/OrNode.java3
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/ParmNode.java2
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/PhiNode.java2
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/PtrToIntNode.java1
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/RoundF32Node.java2
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/SarNode.java2
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/ShlNode.java2
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/ShrNode.java2
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/StoreNode.java4
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/ToFloatNode.java2
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/node/XorNode.java2
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/print/GraphVisualizer.java288
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/print/JSViewer.java26
-rw-r--r--chapter25/src/main/java/com/seaofnodes/simple/print/SimpleGraphObserver.java21
28 files changed, 26 insertions, 383 deletions
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java b/chapter25/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java
index f8674d64..87aa96c4 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java
@@ -275,14 +275,7 @@ public class CodeGen {
private int dump(int dump) {
int p2 = _phase.ordinal();
if( (dump & (1<<p2)) == 0 ) return p2;
- if( (dump & (1<<29)) != 0 ) {
- String fn = ""+p2+"-"+_phase+".dot";
- try {
- Files.writeString(Path.of(fn),
- new GraphVisualizer().generateDotOutput(compunit(), null, null));
- } catch(IOException e) { throw Utils.TODO("Cannot write DOT file"); }
- return p2;
- }
+
if( (dump & (1<<30)) != 0 )
System.err.println("After "+_phase+":");
@@ -866,16 +859,14 @@ public class CodeGen {
public Ary<CFGNode> _cfg = new Ary<>(CFGNode.class);
// Global schedule (code motion) nodes
- public CodeGen GCM() { return GCM(false); }
- public CodeGen GCM( boolean show) {
+ public CodeGen GCM() {
assert _phase.ordinal() <= Phase.Select.ordinal();
_phase = Phase.Schedule;
long t0 = System.currentTimeMillis();
GlobalCodeMotion.buildCFG(this);
_times[Phase.Schedule.ordinal()] = System.currentTimeMillis() - t0;
- if( show )
- System.out.println(new GraphVisualizer().generateDotOutput(compunit(),null,null));
+
return this;
}
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/AndNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/AndNode.java
index 95095ac3..f02007bc 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/AndNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/AndNode.java
@@ -9,8 +9,6 @@ public class AndNode extends ArithNode {
@Override public Tag serialTag() { return Tag.And; }
@Override public String op() { return "&"; }
- @Override public String glabel() { return "&"; }
-
@Override long doOp( long x, long y ) { return x & y; }
@Override TypeInteger doOp(TypeInteger x, TypeInteger y) {
// Sharpen allowed bits if either value is narrowed
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 dfd81504..60f00854 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/ArithNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ArithNode.java
@@ -21,7 +21,6 @@ public abstract class ArithNode extends Node implements ModeNode {
@Override public void packed(BAOS baos, HashMap<String,Integer> strs, HashMap<Type,Integer> types, IdentityHashMap<Node,Integer> anodes) {
baos.packed1(_mode);
}
- @Override public String glabel() { return op(); }
abstract String op();
@Override
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 ac3b0bc0..f720d02d 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/BoolNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/BoolNode.java
@@ -24,9 +24,6 @@ abstract public class BoolNode extends Node implements ModeNode {
abstract public String op(); // String opcode name
@Override
- public String glabel() { return op(); }
-
- @Override
public StringBuilder _print1(StringBuilder sb, BitSet visited) {
in(1)._print0(sb.append("("), visited);
in(2)._print0(sb.append(op()), visited);
@@ -154,7 +151,6 @@ abstract public class BoolNode extends Node implements ModeNode {
public LT(Node lhs, Node rhs, byte mode) { super(lhs,rhs, mode); }
@Override public Tag serialTag() { return Tag.LT; }
public String op() { return "<" ; }
- public String glabel() { return "&lt;"; }
TypeInteger doOp(TypeInteger i1, TypeInteger i2) {
if( i1._max < i2._min ) return TRUE;
if( i1._min >= i2._max ) return FALSE;
@@ -169,7 +165,6 @@ abstract public class BoolNode extends Node implements ModeNode {
public LE(Node lhs, Node rhs, byte mode) { super(lhs,rhs,mode); }
@Override public Tag serialTag() { return Tag.LE; }
public String op() { return "<="; }
- public String glabel() { return "&lt;="; }
TypeInteger doOp(TypeInteger i1, TypeInteger i2) {
if( i1._max <= i2._min ) return TRUE;
if( i1._min > i2._max ) return FALSE;
@@ -188,7 +183,6 @@ abstract public class BoolNode extends Node implements ModeNode {
}
@Override public Tag serialTag() { return Tag.ULT; }
public String op() { return "u<" ; }
- public String glabel() { return "u&lt;"; }
TypeInteger doOp(TypeInteger i1, TypeInteger i2) {
if( Long.compareUnsigned(i1._max,i2._min) < 0 ) return TRUE;
if( Long.compareUnsigned(i1._min,i2._max) >= 0 ) return FALSE;
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/ConFldOffNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/ConFldOffNode.java
index 11a16d28..c7ee1359 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/ConFldOffNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ConFldOffNode.java
@@ -25,7 +25,6 @@ public class ConFldOffNode extends ConstantNode {
@Override public String label() {
return _fname == " len" ? "sizeof("+_ts._name+")" : "#"+_fname;
}
- @Override public String glabel() { return label(); }
@Override public String uniqueName() { return "Off_" + _nid; }
@Override
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 df2dc27b..1dc369d3 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/ConstantNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ConstantNode.java
@@ -67,7 +67,6 @@ public class ConstantNode extends TypeNode {
public static ConstantNode seed( Type type ) { return new ConstantNode(type,true); }
@Override public String label() { return "#"+_con; }
- @Override public String glabel() { return "#"+_con.gprint(); }
@Override public String uniqueName() { return "Con_" + _nid; }
@Override public Node copy() { return raw(this); }
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 9768f41f..58d96745 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 glabel() { return _con.print(new SB().p("#"), new BitSet(), true).p(":").p(_extern).toString(); }
@Override public String uniqueName() { return "Extern_" + _nid; }
@Override public boolean eq(Node n) { return this==n; }
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 3a44f588..e34799c9 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/FldOffNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/FldOffNode.java
@@ -23,7 +23,6 @@ public class FldOffNode extends TypeNode {
@Override public String label() {
return _fname == " len" ? "sizeof()" : "#"+_fname;
}
- @Override public String glabel() { return label(); }
@Override public String uniqueName() { return "Off_" + _nid; }
@Override
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 6e9b0a70..141fc357 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/FunPtrNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/FunPtrNode.java
@@ -25,7 +25,6 @@ public class FunPtrNode extends TypeNode {
public FunNode fun() { return ret().fun(); }
@Override public String label() { return "#"+_con; }
- @Override public String glabel() { return "#"+_con.gprint(); }
@Override public String uniqueName() { return "FunPtr_" + _nid; }
@Override public Node copy() {
FunPtrNode fptr = new FunPtrNode((TypeFunPtr)_con,null,null);
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 fb93964a..d37655b6 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/LoadNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/LoadNode.java
@@ -31,11 +31,8 @@ public class LoadNode extends MemOpNode {
}
@Override public Tag serialTag() { return Tag.Load; }
- // GraphVis DOT code (must be valid Java identifiers) and debugger labels
+ // Debugger label
@Override public String label() { return "ld_"+mlabel(); }
- // GraphVis node-internal labels
- @Override public String glabel() { return "." +_name; }
-
@Override
public StringBuilder _print1(StringBuilder sb, BitSet visited) { return sb.append(".").append(_name); }
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 2261adab..7c3d49f2 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/MinusNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/MinusNode.java
@@ -20,7 +20,6 @@ public class MinusNode extends Node implements ModeNode {
}
@Override public Tag serialTag() { return Tag.Minus; }
- @Override public String glabel() { return "-"; }
@Override public byte mode() { return _mode; }
@Override public Node setMode(byte mode) {
assert _mode==0 && (mode==1 || mode==2);
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 26a9c0fd..3e1d78dc 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/NewNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/NewNode.java
@@ -32,10 +32,7 @@ public class NewNode extends Node implements MultiNode {
return new NewNode(ts,null,null);
}
- @Override public String glabel() {
- return _ts.isAry() ? "ary_"+_ts._fields[1]._t.str() : _ts.str();
- }
- @Override public String label() { return "new_"+glabel(); }
+ @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 ");
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 d113a02a..e2148244 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/Node.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/Node.java
@@ -151,14 +151,12 @@ 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 graph visualization, e.g. "Add12" or "Region30" or "EQ99"
+ // Unique label for debugging, e.g. "Add12" or "Region30" or "EQ99"
public String uniqueName() {
- // Get rid of $ as graphviz doesn't like it
- String label = label().replaceAll("\\$", "");
- return label + _nid;
+ return label() + _nid;
}
- // Graphical label, e.g. "+" or "Region" or "=="
+ // Operator symbol used by assembly/debug printing.
public String glabel() { return label(); }
// Extra fun stuff, for assembly printing. Jump labels, parser locations,
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 22b5bffe..ed6091fe 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/NotNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/NotNode.java
@@ -8,8 +8,6 @@ public class NotNode extends Node {
public NotNode(Node in) { super(null, in); }
@Override public Tag serialTag() { return Tag.Not; }
- @Override public String glabel() { return "!"; }
-
@Override
public StringBuilder _print1(StringBuilder sb, BitSet visited) {
in(1)._print0(sb.append("(!"), visited);
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/OrNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/OrNode.java
index 31d0565b..9d50d1a9 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/OrNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/OrNode.java
@@ -10,9 +10,6 @@ public class OrNode extends ArithNode {
@Override public String label() { return "Or"; }
@Override public String op() { return "|"; }
- @Override public String glabel() { return "|"; }
-
-
@Override long doOp( long x, long y ) { return x | y; }
@Override TypeInteger doOp(TypeInteger x, TypeInteger y) {
return TypeInteger.BOT;
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 04949a53..be36e8d9 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/ParmNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ParmNode.java
@@ -36,8 +36,6 @@ public class ParmNode extends PhiNode {
@Override public String label() { return MemOpNode.mlabel(_label); }
- @Override public String glabel() { return _label; }
-
@Override boolean _upgradeType( HashMap<String,Type> TYPES) {
Type t = _declaredType.upgradeType(TYPES);
if( t == _declaredType ) return false;
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 54cfc3ad..09c55cde 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/PhiNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/PhiNode.java
@@ -47,8 +47,6 @@ public class PhiNode extends Node {
@Override public String label() { return "Phi_"+MemOpNode.mlabel(_label); }
- @Override public String glabel() { return "&phi;_"+_label; }
-
@Override
public StringBuilder _print1(StringBuilder sb, BitSet visited) {
if( !(region() instanceof RegionNode r) || r.inProgress() )
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 02f77f36..f0e7ae95 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/PtrToIntNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/PtrToIntNode.java
@@ -19,7 +19,6 @@ public class PtrToIntNode extends Node {
public PtrToIntNode(PtrToIntNode ptr) { super(ptr); }
@Override public Tag serialTag() { return Tag.PtrToInt; }
- @Override public String glabel() { return "(i64*)"; }
@Override public StringBuilder _print1(StringBuilder sb, BitSet visited) {
return in(1)._print0(sb.append("(i64*)"),visited);
}
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 322a6bc0..61809fe3 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/RoundF32Node.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/RoundF32Node.java
@@ -9,8 +9,6 @@ public class RoundF32Node extends Node {
public RoundF32Node(Node lhs) { super(null, lhs); }
@Override public Tag serialTag() { return Tag.RoundF32; }
- @Override public String glabel() { return "(f32)"; }
-
@Override
public StringBuilder _print1(StringBuilder sb, BitSet visited) {
return in(1)._print0(sb.append("((f32)"), visited).append(")");
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/SarNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/SarNode.java
index e3f99ed4..79b7d0e4 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/SarNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/SarNode.java
@@ -9,8 +9,6 @@ public class SarNode extends ArithNode {
@Override public Tag serialTag() { return Tag.Sar; }
@Override public String op() { return ">>"; }
- @Override public String glabel() { return "&gt;&gt;"; }
-
@Override long doOp( long x, long y ) { return x >> y; }
@Override TypeInteger doOp( TypeInteger x, TypeInteger y ) {
if( y.isConstant() ) {
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/ShlNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/ShlNode.java
index 24d9bdb4..1ca0ba3a 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/ShlNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ShlNode.java
@@ -10,8 +10,6 @@ public class ShlNode extends ArithNode {
@Override public Tag serialTag() { return Tag.Shl; }
@Override public String op() { return "<<"; }
- @Override public String glabel() { return "&lt;&lt;"; }
-
@Override long doOp( long x, long y ) { return x << y; }
@Override TypeInteger doOp( TypeInteger x, TypeInteger y ) {
if( x == TypeInteger.ZERO )
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/ShrNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/ShrNode.java
index 1bf7d118..7fad6275 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/ShrNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ShrNode.java
@@ -9,8 +9,6 @@ public class ShrNode extends ArithNode {
@Override public Tag serialTag() { return Tag.Shr; }
@Override public String op() { return ">>>"; }
- @Override public String glabel() { return "&gt;&gt;&gt;"; }
-
@Override long doOp( long x, long y ) { return x >>> y; }
@Override TypeInteger doOp( TypeInteger x, TypeInteger y ) {
return x == TypeInteger.ZERO ? x : TypeInteger.BOT;
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 faa3d17b..12a94906 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/StoreNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/StoreNode.java
@@ -49,10 +49,8 @@ public class StoreNode extends MemOpNode {
baos.write(_size);
}
- // GraphVis DOT code and debugger labels
+ // Debugger label
@Override public String label() { return "st_"+mlabel(); }
- // GraphVis node-internal labels
- @Override public String glabel() { return "." +_name+"="; }
@Override public boolean isMem() { return true; }
public Node nnptr() {
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 2d8cc788..15350afb 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/ToFloatNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/ToFloatNode.java
@@ -10,8 +10,6 @@ public class ToFloatNode extends Node {
public ToFloatNode(Node lhs) { super(null, lhs); }
@Override public Tag serialTag() { return Tag.ToFloat; }
- @Override public String glabel() { return "(flt)"; }
-
@Override
public StringBuilder _print1(StringBuilder sb, BitSet visited) {
return in(1)._print0(sb.append("(flt)"), visited);
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/node/XorNode.java b/chapter25/src/main/java/com/seaofnodes/simple/node/XorNode.java
index 27ebc3dc..2ee816fa 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/node/XorNode.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/node/XorNode.java
@@ -9,8 +9,6 @@ public class XorNode extends ArithNode {
@Override public Tag serialTag() { return Tag.Xor; }
@Override public String op() { return "^"; }
- @Override public String glabel() { return "^"; }
-
@Override long doOp( long x, long y ) { return x ^ y; }
@Override TypeInteger doOp( TypeInteger x, TypeInteger y ) {
return TypeInteger.BOT;
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/print/GraphVisualizer.java b/chapter25/src/main/java/com/seaofnodes/simple/print/GraphVisualizer.java
deleted file mode 100644
index ad2df8b6..00000000
--- a/chapter25/src/main/java/com/seaofnodes/simple/print/GraphVisualizer.java
+++ /dev/null
@@ -1,288 +0,0 @@
-package com.seaofnodes.simple.print;
-
-import com.seaofnodes.simple.Parser;
-import com.seaofnodes.simple.codegen.CompUnit;
-import com.seaofnodes.simple.node.*;
-import java.util.*;
-import static com.seaofnodes.simple.util.Utils.TODO;
-
-/**
- * Simple visualizer that outputs GraphViz dot format.
- * The dot output must be saved to a file and run manually via dot to generate the SVG output.
- * Currently, this is done manually.
- */
-public class GraphVisualizer {
-
- /**
- * If set to true we put the control nodes in a separate cluster from
- * data nodes.
- */
- boolean _separateControlCluster = false;
-
- public GraphVisualizer(boolean separateControlCluster) { this._separateControlCluster = separateControlCluster; }
- public GraphVisualizer() { this(false); }
-
- public String generateDotOutput(Parser parse) { return generateDotOutput(parse._ref,parse._scope,parse._xScopes); }
- public String generateDotOutput(CompUnit cu, Node scope, Stack<ScopeNode> xScopes) {
-
- // Since the graph has cycles, we need to create a flat list of all the
- // nodes in the graph.
- Collection<Node> all = findAll(xScopes, cu._stop, scope);
- StringBuilder sb = new StringBuilder();
- sb.append("digraph chapter18 {\n");
- sb.append("/*\n");
- sb.append(cu._src);
- sb.append("\n*/\n");
-
- // To keep the Scopes below the graph and pointing up into the graph we
- // need to group the Nodes in a subgraph cluster, and the scopes into a
- // different subgraph cluster. THEN we can draw edges between the
- // scopes and nodes. If we try to cross subgraph cluster borders while
- // still making the subgraphs DOT gets confused.
- sb.append("\trankdir=BT;\n"); // Force Nodes before Scopes
-
- // CNC - turned off Apr/8/2024, gives more flex in the layout and
- // removes some of the more ludicrous layout choices.
- // 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");
-
- // Force nested scopes to order
- sb.append("\tcompound=\"true\";\n");
-
- // Just the Nodes first, in a cluster no edges
- nodes(sb, all);
-
- // Now the scopes, in a cluster no edges
- if( xScopes != null )
- for( ScopeNode xscope : xScopes )
- if( !xscope.isDead() )
- scope( sb, xscope );
-
- // Walk the Node edges
- nodeEdges(sb, all);
-
- // Walk the active Scope edges
- if( xScopes != null )
- for( ScopeNode xscope : xScopes )
- if( !xscope.isDead() )
- scopeEdges( sb, xscope );
-
- sb.append("}\n");
- return sb.toString();
- }
-
- private void nodesByCluster(StringBuilder sb, boolean doCtrl, Collection<Node> all) {
- if (!_separateControlCluster && doCtrl) // all nodes in 1 cluster
- return;
- // Just the Nodes first, in a cluster no edges
- sb.append(doCtrl ? "\tsubgraph cluster_Controls {\n" : "\tsubgraph cluster_Nodes {\n"); // Magic "cluster_" in the subgraph name
- for (Node n : all) {
- if( n instanceof ProjNode || n instanceof CProjNode || n instanceof MemMergeNode || n instanceof XCtrlNode )
- continue; // Do not emit, rolled into MultiNode or Scope cluster already
- if( _separateControlCluster && doCtrl && !(n instanceof CFGNode) ) continue;
- if( _separateControlCluster && !doCtrl && (n instanceof CFGNode) ) continue;
- sb.append("\t\t").append(n.uniqueName()).append(" [ ");
- 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");
- sb.append("\t\t\t<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\" CELLPADDING=\"4\">\n");
- sb.append("\t\t\t<TR><TD BGCOLOR=\"yellow\">").append(lab).append("</TD></TR>\n");
- sb.append("\t\t\t<TR>");
- boolean doProjTable = false;
- n._outputs.sort((x,y) -> x instanceof ProjNode xp && y instanceof ProjNode yp ? (xp._idx - yp._idx) : (x._nid - y._nid));
- for (Node use : n._outputs) {
- if (use instanceof ProjNode proj) {
- if (!doProjTable) {
- doProjTable = true;
- sb.append("<TD>").append("\n");
- sb.append("\t\t\t\t<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\">").append("\n");
- sb.append("\t\t\t\t<TR>");
- }
- sb.append("<TD PORT=\"p").append(proj._idx).append("\">").append(proj.glabel()).append("</TD>");
- }
- if (use instanceof CProjNode proj) {
- if (!doProjTable) {
- doProjTable = true;
- sb.append("<TD>").append("\n");
- sb.append("\t\t\t\t<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\">").append("\n");
- sb.append("\t\t\t\t<TR>");
- }
- sb.append("<TD PORT=\"p").append(proj._idx).append("\" BGCOLOR=\"yellow\">").append(proj.glabel()).append("</TD>");
- }
- }
- if (doProjTable) {
- sb.append("</TR>").append("\n");
- sb.append("\t\t\t\t</TABLE>").append("\n");
- sb.append("\t\t\t</TD>");
- }
- sb.append("</TR>\n");
- sb.append("\t\t\t</TABLE>>\n\t\t");
-
- } else {
- // control nodes have box shape
- // other nodes are ellipses, i.e. default shape
- if( n instanceof CFGNode ) sb.append("shape=box style=filled fillcolor=yellow ");
- else if (n instanceof PhiNode) sb.append("style=filled fillcolor=lightyellow ");
- sb.append("label=\"").append(lab).append("\" ");
- }
- sb.append("];\n");
- }
- if (!_separateControlCluster) {
- // Force Region & Phis to line up
- for (Node n : all) {
- if (n instanceof RegionNode region) {
- sb.append("\t\t{ rank=same; ");
- sb.append(region.uniqueName()).append(";");
- for (Node phi : region._outputs)
- if (phi instanceof PhiNode) sb.append(phi.uniqueName()).append(";");
- sb.append("}\n");
- }
- }
- }
- sb.append("\t}\n"); // End Node cluster
- }
-
- private void nodes(StringBuilder sb, Collection<Node> all) {
- nodesByCluster(sb, true, all);
- nodesByCluster(sb, false, all);
- }
-
- // Build a nested scope display, walking the _prev edge
- private void scope( StringBuilder sb, ScopeNode scope ) {
- sb.append("\tnode [shape=plaintext];\n");
- int last = scope.nIns();
- int max = scope.depth();
- for( int i = 0; i < max; i++ ) {
- int level = max-i-1;
- String scopeName = makeScopeName(scope, level);
- sb.append("\tsubgraph cluster_").append(scopeName).append(" {\n"); // Magic "cluster_" in the subgraph name
- // Special for memory ScopeMinNode
- if( level==0 ) {
- Node n = scope.mem();
- sb.append("\t\t").append(n.uniqueName()).append(" [label=\"").append(n.glabel()).append("\"];\n");
- }
- sb.append("\t\t").append(scopeName).append(" [label=<\n");
- sb.append("\t\t\t<TABLE BORDER=\"0\" CELLBORDER=\"1\" CELLSPACING=\"0\">\n");
- // Add the scope level
- sb.append("\t\t\t<TR><TD BGCOLOR=\"cyan\">").append(level).append("</TD>");
- int lexStart = scope._kinds.at(level)._lexSize;
- for( int j=lexStart; j<last; j++ ) {
- var v = scope._vars.at(j);
- sb.append("<TD PORT=\"").append(makePortName(scopeName, v._name)).append("\">").append(v._name).append("</TD>");
- }
- last = lexStart;
- sb.append("</TR>\n");
- sb.append("\t\t\t</TABLE>>];\n");
- }
- // Scope clusters nest, so the graphics shows the nested scopes, so
- // they are not closed as they are printed; so they just keep nesting.
- // We close them all at once here.
- sb.append( "\t}\n".repeat( max ) ); // End all Scope clusters
- }
-
- private String makeScopeName(ScopeNode sn, int level) { return sn.uniqueName() + "_" + level; }
- private String makePortName(String scopeName, String varName) { return scopeName + "_" + varName; }
-
- // Walk the node edges
- private void nodeEdges(StringBuilder sb, Collection<Node> all) {
- // All them edge labels
- sb.append("\tedge [ fontname=Helvetica, fontsize=8 ];\n");
- for( Node n : all ) {
- // Do not display the Constant->Start edge;
- // ProjNodes handled by Multi;
- // ScopeNodes are done separately
- if( n instanceof ConstantNode || n instanceof ProjNode || n instanceof CProjNode || n instanceof ScopeNode || n instanceof XCtrlNode )
- continue;
- for( int i=0; i<n.nIns(); i++ ) {
- Node def = n.in(i);
- if( n instanceof PhiNode && def instanceof RegionNode ) {
- // Draw a dotted use->def edge from Phi to Region.
- sb.append('\t').append(n.uniqueName());
- sb.append(" -> ");
- sb.append(def.uniqueName());
- sb.append(" [style=dotted taillabel=").append(i).append("];\n");
- } else if( def != null ) {
- // Most edges land here use->def
- sb.append('\t').append(n.uniqueName()).append(" -> ");
- if( def instanceof CProjNode proj ) {
- String mname = proj.ctrl().uniqueName();
- sb.append(mname).append(":p").append(proj._idx);
- } else if( def instanceof ProjNode proj ) {
- String mname = proj.in(0).uniqueName();
- sb.append(mname).append(":p").append(proj._idx);
- } else sb.append(def.uniqueName());
- // Number edges, so we can see how they track
- sb.append("[taillabel=").append(i);
- // The edge from New to ctrl is just for anchoring the New
- if ( n instanceof NewNode )
- sb.append(" color=green");
- // control edges are colored red
- else if( def instanceof CFGNode )
- sb.append(" color=red");
- else if( def.isMem() )
- sb.append(" color=blue");
- // Backedges do not add a ranking constraint
- if( i==2 && (n instanceof PhiNode || n instanceof LoopNode) )
- sb.append(" constraint=false");
- sb.append("];\n");
- }
- }
- }
- }
-
- // Walk the scope edges
- private void scopeEdges( StringBuilder sb, ScopeNode scope ) {
- sb.append("\tedge [style=dashed color=cornflowerblue];\n");
- int level=0;
- for( var v : scope._vars ) {
- Node def = scope.in(v._idx);
- while( def instanceof ScopeNode lazy )
- def = lazy.in(v._idx);
- if( def==null ) continue;
- while( level < scope.depth() && v._idx >= scope._kinds.at(level)._lexSize )
- level++;
- String scopeName = makeScopeName(scope, level-1);
- sb.append("\t")
- .append(scopeName).append(":")
- .append('"').append(makePortName(scopeName, v._name)).append('"') // wrap port name with quotes because $ctrl is not valid unquoted
- .append(" -> ");
- if( def instanceof CProjNode proj ) {
- sb.append(def.in(0).uniqueName()).append(":p").append(proj._idx);
- } else if( def instanceof ProjNode proj ) {
- sb.append(def.in(0).uniqueName()).append(":p").append(proj._idx);
- } else sb.append(def.uniqueName());
- sb.append(";\n");
- }
- }
-
- /**
- * Finds all nodes in the graph.
- */
- public static Collection<Node> findAll(Stack<ScopeNode> ss, Node... ns) {
- final HashMap<Integer, Node> all = new HashMap<>();
- for( Node n : ns )
- walk(all, n);
- if( ss != null )
- for( Node n : ss )
- walk(all, n);
- return all.values();
- }
-
- /**
- * Walk a subgraph and populate distinct nodes in the all list.
- */
- private static void walk(HashMap<Integer,Node> all, Node n) {
- if(n == null ) return;
- if (all.get(n._nid) != null) return; // Been there, done that
- all.put(n._nid, n);
- for (Node c : n._inputs)
- walk(all, c);
- for( Node c : n._outputs )
- walk(all, c);
- }
-}
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/print/JSViewer.java b/chapter25/src/main/java/com/seaofnodes/simple/print/JSViewer.java
deleted file mode 100644
index 03842119..00000000
--- a/chapter25/src/main/java/com/seaofnodes/simple/print/JSViewer.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.seaofnodes.simple.print;
-
-import com.seaofnodes.graph.*;
-import com.seaofnodes.simple.codegen.CodeGen;
-import java.io.IOException;
-
-public class JSViewer extends GraphViewer {
- public static void main(String[] args) throws IOException {
- try( var view = new JSViewer() ) { view.run(); }
- }
- JSViewer() throws IOException {}
-
- @Override protected void compile(String src) {
- CodeGen code = new CodeGen(src);
- code._obs = new SimpleGraphObserver(code) {
- @Override protected void frame(GraphSnapshot snap, int pos, GraphEvent evt) throws IOException {
- JSViewer.this.frame(snap, pos, evt);
- }
- };
- try {
- code.parse().opto();
- } finally {
- code._obs = null;
- }
- }
-}
diff --git a/chapter25/src/main/java/com/seaofnodes/simple/print/SimpleGraphObserver.java b/chapter25/src/main/java/com/seaofnodes/simple/print/SimpleGraphObserver.java
index 0318b793..7af718ac 100644
--- a/chapter25/src/main/java/com/seaofnodes/simple/print/SimpleGraphObserver.java
+++ b/chapter25/src/main/java/com/seaofnodes/simple/print/SimpleGraphObserver.java
@@ -1,17 +1,30 @@
package com.seaofnodes.simple.print;
import com.seaofnodes.graph.GraphCapture;
+import com.seaofnodes.graph.GraphViewer;
import com.seaofnodes.simple.codegen.CodeGen;
import com.seaofnodes.simple.node.Node;
import java.util.ArrayList;
+import java.io.IOException;
/** Chapter 25's compilation context; capture and event bookkeeping are shared. */
-public abstract class SimpleGraphObserver extends GraphCapture<Node> {
- private final CodeGen _code;
- protected SimpleGraphObserver(CodeGen code) { super(new SimpleGraphAdapter()); _code = code; }
+public class SimpleGraphObserver extends GraphCapture<Node> {
+ private CodeGen _code;
+ public SimpleGraphObserver() { super(new SimpleGraphAdapter()); }
+ public static void main(String[] args) throws IOException {
+ GraphViewer.run(new SimpleGraphObserver());
+ }
+ @Override protected void compile(String src) {
+ _code = new CodeGen(src);
+ _code._obs = this;
+ _code.parse().opto();
+ }
@Override protected String phase() { return _code._phase.name(); }
@Override protected int pos() { return _code._phase == CodeGen.Phase.Parse ? _code.P.pos() : -1; }
- @Override protected void detach() { _code._obs = null; }
+ @Override protected void detach() {
+ if( _code != null ) _code._obs = null;
+ _code = null;
+ }
@Override protected void roots(ArrayList<Node> roots) {
roots.add(_code._stop);
if( _code._phase == CodeGen.Phase.Parse ) {