diff options
| author | Cliff Click <cliffc@acm.org> | 2024-09-23 14:33:13 -0700 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2024-10-06 08:56:22 -0700 |
| commit | 2185153ea9764090b1e7bd1511b448768a28d6ea (patch) | |
| tree | 0e3a14b947f48323467a4fe9d3d1a9e144de6e63 /chapter15/src/main/java | |
| parent | df41f1d6d4c1f964e2488705f46e433c59a77d5c (diff) | |
| download | Simple-2185153ea9764090b1e7bd1511b448768a28d6ea.tar.gz Simple-2185153ea9764090b1e7bd1511b448768a28d6ea.zip | |
Scope renames _scopes and _types as _idxs and _decls.
Drop isCFG and use instanceof instead
Diffstat (limited to 'chapter15/src/main/java')
6 files changed, 54 insertions, 62 deletions
diff --git a/chapter15/src/main/java/com/seaofnodes/simple/GraphVisualizer.java b/chapter15/src/main/java/com/seaofnodes/simple/GraphVisualizer.java index 604770a4..f5fa1350 100644 --- a/chapter15/src/main/java/com/seaofnodes/simple/GraphVisualizer.java +++ b/chapter15/src/main/java/com/seaofnodes/simple/GraphVisualizer.java @@ -82,8 +82,8 @@ public class GraphVisualizer { for (Node n : all) { if (n instanceof ProjNode || n instanceof CProjNode || n instanceof ScopeNode || n==Parser.XCTRL) continue; // Do not emit, rolled into MultiNode or Scope cluster already - if (_separateControlCluster && doCtrl && !n.isCFG()) continue; - if (_separateControlCluster && !doCtrl && n.isCFG()) continue; + 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) { @@ -93,6 +93,7 @@ public class GraphVisualizer { 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) { @@ -124,7 +125,7 @@ public class GraphVisualizer { } else { // control nodes have box shape // other nodes are ellipses, i.e. default shape - if (n.isCFG()) sb.append("shape=box style=filled fillcolor=yellow "); + 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("\" "); } @@ -154,14 +155,14 @@ public class GraphVisualizer { private void scope( StringBuilder sb, ScopeNode scope ) { sb.append("\tnode [shape=plaintext];\n"); int level=1; - for( int idx = scope._scopes.size()-1; idx>=0; idx-- ) { - var syms = scope._scopes.get(idx); + for( int idx = scope._idxs.size()-1; idx>=0; idx-- ) { + var syms = scope._idxs.get(idx); String scopeName = makeScopeName(scope, level); sb.append("\tsubgraph cluster_").append(scopeName).append(" {\n"); // Magic "cluster_" in the subgraph name 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 - int scopeLevel = scope._scopes.size()-level; + int scopeLevel = scope._idxs.size()-level; sb.append("\t\t\t<TR><TD BGCOLOR=\"cyan\">").append(scopeLevel).append("</TD>"); for(String name: syms.keySet()) sb.append("<TD PORT=\"").append(makePortName(scopeName, name)).append("\">").append(name).append("</TD>"); @@ -212,7 +213,7 @@ public class GraphVisualizer { if ( n instanceof NewNode ) sb.append(" color=green"); // control edges are colored red - else if( def.isCFG() ) + else if( def instanceof CFGNode ) sb.append(" color=red"); else if( def.isMem() ) sb.append(" color=blue"); @@ -229,8 +230,8 @@ public class GraphVisualizer { private void scopeEdges( StringBuilder sb, ScopeNode scope ) { sb.append("\tedge [style=dashed color=cornflowerblue];\n"); int level=1; - for( int i = scope._scopes.size()-1; i>=0; i-- ) { - var syms = scope._scopes.get(i); + for( int i = scope._idxs.size()-1; i>=0; i-- ) { + var syms = scope._idxs.get(i); String scopeName = makeScopeName(scope, level); for( String name : syms.keySet() ) { int idx = syms.get(name); diff --git a/chapter15/src/main/java/com/seaofnodes/simple/node/CFGNode.java b/chapter15/src/main/java/com/seaofnodes/simple/node/CFGNode.java index 07ba0fa4..9e9d6970 100644 --- a/chapter15/src/main/java/com/seaofnodes/simple/node/CFGNode.java +++ b/chapter15/src/main/java/com/seaofnodes/simple/node/CFGNode.java @@ -23,9 +23,6 @@ public abstract class CFGNode extends Node { public CFGNode(Node... nodes) { super(nodes); } - @Override public boolean isCFG() { return true; } - @Override public boolean isPinned() { return true; } - public CFGNode cfg(int idx) { return (CFGNode)in(idx); } // Block head is Start, Region, CProj, but not e.g. If, Return, Stop diff --git a/chapter15/src/main/java/com/seaofnodes/simple/node/ConstantNode.java b/chapter15/src/main/java/com/seaofnodes/simple/node/ConstantNode.java index 016b0b9b..845b9d08 100644 --- a/chapter15/src/main/java/com/seaofnodes/simple/node/ConstantNode.java +++ b/chapter15/src/main/java/com/seaofnodes/simple/node/ConstantNode.java @@ -36,8 +36,6 @@ public class ConstantNode extends Node { } @Override public boolean isMultiTail() { return true; } - // The special forever-zero is pinned, all others can sink - @Override public boolean isPinned() { return this==Parser.ZERO; } @Override public Type compute() { return _con; } diff --git a/chapter15/src/main/java/com/seaofnodes/simple/node/Node.java b/chapter15/src/main/java/com/seaofnodes/simple/node/Node.java index 382f78ae..c3a0f20f 100644 --- a/chapter15/src/main/java/com/seaofnodes/simple/node/Node.java +++ b/chapter15/src/main/java/com/seaofnodes/simple/node/Node.java @@ -135,7 +135,7 @@ public abstract class Node implements OutNode { public boolean isUnused() { return nOuts() == 0; } - public CFGNode cfg0() { return (CFGNode)in(0); } + public CFGNode cfg0() { return (CFGNode)in(0); } /** * Change a <em>def</em> into a Node. Keeps the edges correct, by removing @@ -533,16 +533,13 @@ public abstract class Node implements OutNode { // ------------------------------------------------------------------------ // - /** Is this Node control-flow-graph related */ - public boolean isCFG() { return false; } - /** Is this Node Memory related */ public boolean isMem() { return false; } /** Return block start from a isCFG() */ public Node getBlockStart() { return null; } - /** Pinned in the schedule */ + /** Pinned in the schedule; these are data nodes whose input#0 is not allowed to change */ public boolean isPinned() { return false; } // Semantic change to the graph (so NOT a peephole), used by the Parser. diff --git a/chapter15/src/main/java/com/seaofnodes/simple/node/PhiNode.java b/chapter15/src/main/java/com/seaofnodes/simple/node/PhiNode.java index ebed8dd1..0b5abc6c 100644 --- a/chapter15/src/main/java/com/seaofnodes/simple/node/PhiNode.java +++ b/chapter15/src/main/java/com/seaofnodes/simple/node/PhiNode.java @@ -73,7 +73,8 @@ public class PhiNode extends Node { // Phi(op(A,B),op(Q,R),op(X,Y)) becomes // op(Phi(A,Q,X), Phi(B,R,Y)). Node op = in(1); - if( op.nIns()==3 && op.in(0)==null && !op.isCFG() && same_op() ) { + if( op.nIns()==3 && op.in(0)==null && same_op() ) { + assert !(op instanceof CFGNode); Node[] lhss = new Node[nIns()]; Node[] rhss = new Node[nIns()]; lhss[0] = rhss[0] = in(0); // Set Region diff --git a/chapter15/src/main/java/com/seaofnodes/simple/node/ScopeNode.java b/chapter15/src/main/java/com/seaofnodes/simple/node/ScopeNode.java index 843ce733..877ae4a4 100644 --- a/chapter15/src/main/java/com/seaofnodes/simple/node/ScopeNode.java +++ b/chapter15/src/main/java/com/seaofnodes/simple/node/ScopeNode.java @@ -1,10 +1,9 @@ package com.seaofnodes.simple.node; import com.seaofnodes.simple.IterPeeps; -import com.seaofnodes.simple.type.Type; +import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.Utils; -import com.seaofnodes.simple.type.TypeMemPtr; - +import com.seaofnodes.simple.type.*; import java.util.*; /** @@ -21,24 +20,22 @@ public class ScopeNode extends Node { public static final String ARG0 = "arg"; /** - * Names for every input edge + * Map variable names to Scope input edge */ - public final Stack<HashMap<String, Integer>> _scopes; + public final Stack<HashMap<String, Integer>> _idxs; /** - * Tracks declared types for every name + * Map variable names to declared Type */ - public Stack<HashMap<String, Type>> _types; - + final Stack<HashMap<String, Type>> _decls; // A new ScopeNode public ScopeNode() { - _scopes = new Stack<>(); - _types = new Stack<>(); + _idxs = new Stack<>(); + _decls= new Stack<>(); _type = Type.BOTTOM; } - @Override public String label() { return "Scope"; } @Override @@ -58,6 +55,20 @@ public class ScopeNode extends Node { return sb.append("]"); } + public Node ctrl() { return in(0); } + + /** + * The ctrl of a ScopeNode is always bound to the currently active + * control node in the graph, via a special name '$ctrl' that is not + * a valid identifier in the language grammar and hence cannot be + * referenced in Simple code. + * + * @param n The node to be bound to '$ctrl' + * + * @return Node that was bound + */ + public Node ctrl(Node n) { return setDef(0,n); } + /** * Recover the names for all variable bindings. * The result is an array of names that is aligned with the @@ -67,7 +78,7 @@ public class ScopeNode extends Node { */ public String[] reverseNames() { String[] names = new String[nIns()]; - for( HashMap<String,Integer> syms : _scopes ) + for( HashMap<String,Integer> syms : _idxs ) for( String name : syms.keySet() ) names[syms.get(name)] = name; return names; @@ -77,33 +88,34 @@ public class ScopeNode extends Node { @Override public Node idealize() { return null; } - public void push() { _scopes.push(new HashMap<>()); _types.push(new HashMap<>()); } - public void pop() { popN(_scopes.pop().size()); _types.pop(); } + public void push() { _idxs.push(new HashMap<>()); _decls.push(new HashMap<>()); } + public void pop() { popN(_idxs.pop().size()); _decls.pop(); } /** - * Create a new name in the current scope + * Create a new variable name in the current scope */ public Node define( String name, Type declaredType, Node n ) { - HashMap<String,Integer> syms = _scopes.lastElement(); - _types.lastElement().put(name,declaredType); + HashMap<String,Integer> syms = _idxs.lastElement(); + _decls.lastElement().put(name,declaredType); if( syms.put(name,nIns()) != null ) return null; // Double define return addDef(n); } + /** * Lookup a name in all scopes starting from most deeply nested. * * @param name Name to be looked up * @see #update(String, Node, int) */ - public Node lookup( String name ) { return update(name,null,_scopes.size()-1); } + public Node lookup( String name ) { return update(name,null,_idxs.size()-1); } /** * If the name is present in any scope, then redefine else null * * @param name Name being redefined * @param n The node to bind to the name */ - public Node update( String name, Node n ) { return update(name,n,_scopes.size()-1); } + public Node update( String name, Node n ) { return update(name,n,_idxs.size()-1); } /** * Both recursive lookup and update. * <p> @@ -117,7 +129,7 @@ public class ScopeNode extends Node { */ private Node update( String name, Node n, int nestingLevel ) { if( nestingLevel<0 ) return null; // Missed in all scopes, not found - var syms = _scopes.get(nestingLevel); // Get the symbol table for nesting level + var syms = _idxs.get(nestingLevel); // Get the symbol table for nesting level var idx = syms.get(name); if( idx == null ) return update(name,n,nestingLevel-1); // Not found in this scope, recursively look in parent scope Node old = in(idx); @@ -135,29 +147,15 @@ public class ScopeNode extends Node { return n==null ? old : setDef(idx,n); // Not lazy, so this is the answer } - // Return declared type + // Return declared type for a variable public Type lookupDeclaredType( String name ) { - for( int i=_types.size(); i>0; i-- ) { - Type t = _types.get(i-1).get(name); + for( int i=_decls.size(); i>0; i-- ) { + Type t = _decls.get(i-1).get(name); if( t != null ) return t; } return null; } - public Node ctrl() { return in(0); } - - /** - * The ctrl of a ScopeNode is always bound to the currently active - * control node in the graph, via a special name '$ctrl' that is not - * a valid identifier in the language grammar and hence cannot be - * referenced in Simple code. - * - * @param n The node to be bound to '$ctrl' - * - * @return Node that was bound - */ - public Node ctrl(Node n) { return setDef(0,n); } - /** * Duplicate a ScopeNode; including all levels, up to Nodes. So this is * neither shallow (would dup the Scope but not the internal HashMap @@ -165,7 +163,7 @@ public class ScopeNode extends Node { * also the program Nodes). * <p> * If the {@code loop} flag is set, the edges are filled in as the original - * Scope, as a indication of Lazy Phis at loop heads. The goal here is to + * Scope, as an indication of Lazy Phis at loop heads. The goal here is to * not make Phis at loop heads for variables which are never touched in the * loop body. * <p> @@ -178,10 +176,10 @@ public class ScopeNode extends Node { // 1) duplicate the name bindings of the ScopeNode across all stack levels // 2) Make the new ScopeNode a user of all the nodes bound // 3) Ensure that the order of defs is the same to allow easy merging - for( HashMap<String,Integer> syms : _scopes ) - dup._scopes.push(new HashMap<>(syms)); - for( HashMap<String,Type> ts : _types ) - dup._types.push(ts); // Types don't change, just keep stacks aligned + for( HashMap<String,Integer> syms : _idxs ) + dup._idxs.push(new HashMap<>(syms)); + for( HashMap<String,Type> ts : _decls ) + dup._decls.push(ts); // Types don't change, just keep stacks aligned dup.addDef(ctrl()); // Control input is just copied for( int i=1; i<nIns(); i++ ) |
