From 1a9cac97df063af82516ca35bde34fde62d24c56 Mon Sep 17 00:00:00 2001 From: Dibyendu Majumdar Date: Sat, 11 Nov 2023 23:17:22 +0000 Subject: Chapter 6 (#38) * #37 Create chapter 6 skeleton * #37 Revise type system - TOP, BOTTOM, CONTROL are now directly implemented in Type, XCONTROL is a new type and that's implemented directly too. We have a _type field that is like an enum. * #37 Revise Type.meet() - this is now final. Subclasses can override xmeet() which is protected but now handles simple types in Type itself. * #37 Basic test for peephole of CFG * #37 Revise compute of if * #37 Revise compute of if * #37 WIP peephole of If * #37 WIP peephole of If * #37 WIP peephole of If * #37 WIP peephole of If * #37 WIP peephole of If * #37 WIP fix the chars inserted by IntelliJ * #37 WIP Fix compute type in IfNode * #37 WIP Null check region inputs * #37 WIP Fix where we choose great grand parent instead of grand parent Add new test * #37 WIP More fixes and tests * #37 WIP Some minor adjustments * Cleanup folding dead IF tests Remove isDeadCtrl & just test for the constant. Remove DEAD_CTRL, doesn't properly reset between tests. Move keep/unkeep to Node. PhiNode has a proper compute() call. ProjNode ideal is a lot simpler. Region doesn't ever get a null. Move the mergeScopes Region peep till after all Phis are added. Type TOP and XCONTROL count as constants. TypeTuple gets a toString * #37 WIP Upate README * #37 WIP Region node should check if one of its inputs is a region that needs to be peepholed * #37 WIP If node should check if its ctrl input is a Region that has only 1 live input so can be peepholed * #37 WIP Further update to README to make the peephole logic clearer. Also discuss the relationship between Region and Phi nodes * Region removes dead input paths Remove region-folding in Return, If. Add a Makefile. Reformat triple-quote lines to be emacs-friendly. * StopNode idealize Return type sharpens to include control input. * Remove !=, >=, >; use Not and <, <=, == Fix bug mixing rotating different ops. Generalize Add fold constants; apply to Mul, EQ. Fix Div.copy * Fix bug rotating e.g. < or <= Peep is only valid for associative ops * #37 WIP Doc updates * Work over the Ch6 Readme Major issue: Region inputs align 1-to-1 with Phi inputs, but a Region can have zero to many Phis. When we lose a Region input (dead path), we need to lose the same inputs to each Phi - but we don't lose the Phis themselves, unless we're folding away down to the last live input. * Update chapter06/README.md Co-authored-by: Yichen Yan * Update chapter06/README.md Co-authored-by: Yichen Yan * #37 Backport type system changes to chapter 2 * #37 Backport type system changes to chapter 3 * #37 Backport type system changes to chapter 4 * #37 Backport type system changes to chapter 5 * #37 Merge chapter 5 updates from main. Remove language grammar module as we describe the grammar incrementally in each chapter. * #37 Chapter 6 doc updates - added visuals to show effects of CFG peephole * #37 Sync some updates to chapter 2 * #37 Sync some updates to chapter 3 * #37 Sync some updates to chapter 4 --------- Co-authored-by: Cliff Click Co-authored-by: Yichen Yan --- .../main/java/com/seaofnodes/simple/Parser.java | 1 + .../java/com/seaofnodes/simple/node/AddNode.java | 2 +- .../java/com/seaofnodes/simple/node/BoolNode.java | 3 +-- .../java/com/seaofnodes/simple/node/DivNode.java | 5 ++-- .../java/com/seaofnodes/simple/node/IfNode.java | 1 + .../java/com/seaofnodes/simple/node/MinusNode.java | 3 +-- .../java/com/seaofnodes/simple/node/MulNode.java | 3 +-- .../main/java/com/seaofnodes/simple/node/Node.java | 2 +- .../java/com/seaofnodes/simple/node/PhiNode.java | 3 +-- .../java/com/seaofnodes/simple/node/ProjNode.java | 7 ++++-- .../com/seaofnodes/simple/node/RegionNode.java | 3 +-- .../com/seaofnodes/simple/node/ReturnNode.java | 2 +- .../java/com/seaofnodes/simple/node/ScopeNode.java | 8 +++---- .../java/com/seaofnodes/simple/node/StartNode.java | 1 - .../java/com/seaofnodes/simple/node/StopNode.java | 3 +-- .../java/com/seaofnodes/simple/node/SubNode.java | 3 +-- .../main/java/com/seaofnodes/simple/type/Type.java | 28 ++++++++++++++++++---- .../java/com/seaofnodes/simple/type/TypeBot.java | 19 --------------- .../com/seaofnodes/simple/type/TypeControl.java | 16 ------------- .../com/seaofnodes/simple/type/TypeInteger.java | 6 ++++- .../java/com/seaofnodes/simple/type/TypeTuple.java | 8 ++++++- 21 files changed, 58 insertions(+), 69 deletions(-) delete mode 100644 chapter05/src/main/java/com/seaofnodes/simple/type/TypeBot.java delete mode 100644 chapter05/src/main/java/com/seaofnodes/simple/type/TypeControl.java (limited to 'chapter05/src/main/java/com/seaofnodes') diff --git a/chapter05/src/main/java/com/seaofnodes/simple/Parser.java b/chapter05/src/main/java/com/seaofnodes/simple/Parser.java index a132fce0..0461dc69 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/Parser.java @@ -182,6 +182,7 @@ public class Parser { // Merge results _scope = tScope; _allScopes.pop(); // Discard pushed from graph display + return ctrl(tScope.mergeScopes(fScope)); } 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 f2b93b2e..f6c49abf 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/AddNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/AddNode.java @@ -25,7 +25,7 @@ public class AddNode extends Node { return TypeInteger.constant(i0.value()+i1.value()); return i0.meet(i1); } - return TypeBot.BOTTOM; + return Type.BOTTOM; } @Override 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 c1471c58..0ba5e7b0 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/BoolNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/BoolNode.java @@ -1,7 +1,6 @@ package com.seaofnodes.simple.node; import com.seaofnodes.simple.type.Type; -import com.seaofnodes.simple.type.TypeBot; import com.seaofnodes.simple.type.TypeInteger; abstract public class BoolNode extends Node { @@ -33,7 +32,7 @@ abstract public class BoolNode extends Node { return TypeInteger.constant(doOp(i0.value(), i1.value()) ? 1 : 0); return i0.meet(i1); } - return TypeBot.BOTTOM; + return Type.BOTTOM; } abstract boolean doOp(long lhs, long rhs); 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 489e7275..01314c74 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/DivNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/DivNode.java @@ -1,7 +1,6 @@ package com.seaofnodes.simple.node; import com.seaofnodes.simple.type.Type; -import com.seaofnodes.simple.type.TypeBot; import com.seaofnodes.simple.type.TypeInteger; public class DivNode extends Node { @@ -28,11 +27,11 @@ public class DivNode extends Node { : TypeInteger.constant(i0.value()/i1.value()); return i0.meet(i1); } - return TypeBot.BOTTOM; + return Type.BOTTOM; } @Override public Node idealize() { return null; } - @Override Node copy(Node lhs, Node rhs) { return new AddNode(lhs,rhs); } + @Override Node copy(Node lhs, Node rhs) { return new DivNode(lhs,rhs); } } diff --git a/chapter05/src/main/java/com/seaofnodes/simple/node/IfNode.java b/chapter05/src/main/java/com/seaofnodes/simple/node/IfNode.java index feb4f245..b46d37db 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/IfNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/IfNode.java @@ -1,6 +1,7 @@ package com.seaofnodes.simple.node; import com.seaofnodes.simple.type.Type; +import com.seaofnodes.simple.type.TypeInteger; import com.seaofnodes.simple.type.TypeTuple; public class IfNode extends MultiNode { 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 533155d9..08924563 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/MinusNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/MinusNode.java @@ -1,7 +1,6 @@ package com.seaofnodes.simple.node; import com.seaofnodes.simple.type.Type; -import com.seaofnodes.simple.type.TypeBot; import com.seaofnodes.simple.type.TypeInteger; public class MinusNode extends Node { @@ -21,7 +20,7 @@ public class MinusNode extends Node { public Type compute() { if (in(1)._type instanceof TypeInteger i0) return i0.isConstant() ? TypeInteger.constant(-i0.value()) : i0; - return TypeBot.BOTTOM; + return Type.BOTTOM; } @Override 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 9962c445..0f21f67a 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/MulNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/MulNode.java @@ -1,7 +1,6 @@ package com.seaofnodes.simple.node; import com.seaofnodes.simple.type.Type; -import com.seaofnodes.simple.type.TypeBot; import com.seaofnodes.simple.type.TypeInteger; public class MulNode extends Node { @@ -26,7 +25,7 @@ public class MulNode extends Node { return TypeInteger.constant(i0.value()*i1.value()); return i0.meet(i1); } - return TypeBot.BOTTOM; + return Type.BOTTOM; } @Override 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 2d8a14d4..65151acb 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/Node.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/Node.java @@ -227,7 +227,7 @@ public abstract class Node { // Remove node 'use' from 'def's (i.e. our) output list, by compressing the list in-place. // Return true if the output list is empty afterward. // Error is 'use' does not exist; ok for 'use' to be null. - private boolean delUse( Node use ) { + protected boolean delUse( Node use ) { ArrayList outs = _outputs; int lidx = outs.size()-1; // Last index // This 1-line hack compresses an element out of an ArrayList 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 656e6182..87c84453 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/PhiNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/PhiNode.java @@ -1,7 +1,6 @@ package com.seaofnodes.simple.node; import com.seaofnodes.simple.type.Type; -import com.seaofnodes.simple.type.TypeBot; public class PhiNode extends Node { @@ -25,7 +24,7 @@ public class PhiNode extends Node { @Override public Type compute() { - return TypeBot.BOTTOM; + return Type.BOTTOM; } @Override diff --git a/chapter05/src/main/java/com/seaofnodes/simple/node/ProjNode.java b/chapter05/src/main/java/com/seaofnodes/simple/node/ProjNode.java index 8e223e93..86e3b144 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/ProjNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/ProjNode.java @@ -1,7 +1,6 @@ package com.seaofnodes.simple.node; import com.seaofnodes.simple.type.Type; -import com.seaofnodes.simple.type.TypeBot; import com.seaofnodes.simple.type.TypeTuple; public class ProjNode extends Node { @@ -31,7 +30,11 @@ public class ProjNode extends Node { @Override public Type compute() { Type t = ctrl()._type; - return t instanceof TypeTuple tt ? tt._types[_idx] : TypeBot.BOTTOM; + return getType(t); + } + + private Type getType(Type t) { + return t instanceof TypeTuple tt ? tt._types[_idx] : Type.BOTTOM; } @Override 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 ae8724b9..354a8f8b 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/RegionNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/RegionNode.java @@ -1,7 +1,6 @@ package com.seaofnodes.simple.node; import com.seaofnodes.simple.type.Type; -import com.seaofnodes.simple.type.TypeControl; public class RegionNode extends Node { public RegionNode(Node... inputs) { super(inputs); } @@ -18,7 +17,7 @@ public class RegionNode extends Node { @Override public Type compute() { - return TypeControl.CONTROL; + return Type.CONTROL; } @Override diff --git a/chapter05/src/main/java/com/seaofnodes/simple/node/ReturnNode.java b/chapter05/src/main/java/com/seaofnodes/simple/node/ReturnNode.java index e20d01e5..73594d2a 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/ReturnNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/ReturnNode.java @@ -32,7 +32,7 @@ public class ReturnNode extends Node { @Override public Type compute() { - return new TypeTuple(TypeControl.CONTROL,expr()._type); + return new TypeTuple(Type.CONTROL,expr()._type); } @Override 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 61fac118..93ef54f6 100644 --- a/chapter05/src/main/java/com/seaofnodes/simple/node/ScopeNode.java +++ b/chapter05/src/main/java/com/seaofnodes/simple/node/ScopeNode.java @@ -1,7 +1,7 @@ package com.seaofnodes.simple.node; import com.seaofnodes.simple.Parser; -import com.seaofnodes.simple.type.TypeBot; +import com.seaofnodes.simple.type.Type; import java.util.*; @@ -43,7 +43,7 @@ public class ScopeNode extends Node { } @Override - public TypeBot compute() { return TypeBot.BOTTOM; } + public Type compute() { return Type.BOTTOM; } @Override public Node idealize() { return null; } @@ -124,9 +124,9 @@ public class ScopeNode extends Node { * 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 + * @return A new node representing the merge point */ - public RegionNode mergeScopes(ScopeNode that) { + public Node mergeScopes(ScopeNode that) { RegionNode r = (RegionNode)ctrl(new RegionNode(null,ctrl(), that.ctrl()).peephole()); for( int i=1; i