summaryrefslogtreecommitdiff
path: root/chapter05/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'chapter05/src/main/java')
-rw-r--r--chapter05/src/main/java/com/seaofnodes/simple/GraphVisualizer.java16
-rw-r--r--chapter05/src/main/java/com/seaofnodes/simple/Parser.java3
-rw-r--r--chapter05/src/main/java/com/seaofnodes/simple/node/MinusNode.java2
-rw-r--r--chapter05/src/main/java/com/seaofnodes/simple/node/ScopeNode.java12
4 files changed, 21 insertions, 12 deletions
diff --git a/chapter05/src/main/java/com/seaofnodes/simple/GraphVisualizer.java b/chapter05/src/main/java/com/seaofnodes/simple/GraphVisualizer.java
index f3942edb..01b5aeeb 100644
--- a/chapter05/src/main/java/com/seaofnodes/simple/GraphVisualizer.java
+++ b/chapter05/src/main/java/com/seaofnodes/simple/GraphVisualizer.java
@@ -146,7 +146,7 @@ public class GraphVisualizer {
// Walk the node edges
private void nodeEdges(StringBuilder sb, Collection<Node> all) {
// All them edge labels
- sb.append("\tedge [ fontname=Helvetica, fontsize=8 ];\n");
+ sb.append("\tedge [ fontname=Helvetica, fontsize=8 ];\n");
for( Node n : all ) {
// Do not display the Constant->Start edge;
// ProjNodes handled by Multi;
@@ -155,16 +155,12 @@ public class GraphVisualizer {
continue;
int i=0;
for( Node def : n._inputs ) {
- // Do not draw the Phi->Region edge (in red); instead Phis are
- // on a line with their Region, and we draw an invisible line
- // from the Region to the Phi, to force all the Phis to the
- // right of the Region.
if( n instanceof PhiNode && def instanceof RegionNode ) {
- sb.append('\t').append(def.uniqueName());
+ // Draw a dotted use->def edge from Phi to Region.
+ sb.append('\t').append(n.uniqueName());
sb.append(" -> ");
- sb.append(n.uniqueName());
- sb.append(" [style=invis]\n");
-
+ 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(" -> ");
@@ -176,7 +172,7 @@ public class GraphVisualizer {
sb.append("[taillabel=").append(i);
// control edges are colored red
if( def.isCFG() )
- sb.append("; color=red");
+ sb.append(" color=red");
sb.append("];\n");
}
i++;
diff --git a/chapter05/src/main/java/com/seaofnodes/simple/Parser.java b/chapter05/src/main/java/com/seaofnodes/simple/Parser.java
index 8bf343b3..a132fce0 100644
--- a/chapter05/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter05/src/main/java/com/seaofnodes/simple/Parser.java
@@ -94,6 +94,7 @@ public class Parser {
_scope.define(CTRL , new ProjNode(START, 0, CTRL ).peephole());
_scope.define("arg", new ProjNode(START, 1, "arg").peephole());
parseBlock();
+ if (!_lexer.isEOF()) throw error("Syntax error, unexpected " + _lexer.getAnyNextToken());
return STOP;
}
finally {
@@ -129,7 +130,7 @@ public class Parser {
* Parses a statement
*
* <pre>
- * returnStatement | declStatement | blockStatement | expressionStatement
+ * returnStatement | declStatement | blockStatement | ifStatement | expressionStatement
* </pre>
* @return a {@link Node} or {@code null}
*/
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 834f4c11..533155d9 100644
--- a/chapter05/src/main/java/com/seaofnodes/simple/node/MinusNode.java
+++ b/chapter05/src/main/java/com/seaofnodes/simple/node/MinusNode.java
@@ -20,7 +20,7 @@ public class MinusNode extends Node {
@Override
public Type compute() {
if (in(1)._type instanceof TypeInteger i0)
- return TypeInteger.constant(-i0.value());
+ return i0.isConstant() ? TypeInteger.constant(-i0.value()) : i0;
return TypeBot.BOTTOM;
}
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 64061030..61fac118 100644
--- a/chapter05/src/main/java/com/seaofnodes/simple/node/ScopeNode.java
+++ b/chapter05/src/main/java/com/seaofnodes/simple/node/ScopeNode.java
@@ -105,6 +105,10 @@ public class ScopeNode extends Node {
* The new Scope is a full-fledged Node with proper use<->def edges.
*/
public ScopeNode dup() {
+ // Our goals are:
+ // 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
ScopeNode dup = new ScopeNode();
for( HashMap<String, Integer> tab : _scopes )
dup._scopes.push(new HashMap<>(tab));
@@ -114,6 +118,14 @@ public class ScopeNode extends Node {
return dup;
}
+ /**
+ * Merges the names whose node bindings differ, by creating Phi node for such names
+ * The names could occur at all stack levels, but a given name can only differ in the
+ * innermost stack level where the name is bound.
+ *
+ * @param that The ScopeNode to be merged into this
+ * @return A new Region node representing the merge point
+ */
public RegionNode mergeScopes(ScopeNode that) {
RegionNode r = (RegionNode)ctrl(new RegionNode(null,ctrl(), that.ctrl()).peephole());
for( int i=1; i<nIns(); i++ )