summaryrefslogtreecommitdiff
path: root/src/main/java/com/seaofnodes/simple/node/StopNode.java
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-08-10 11:11:18 -0700
committerCliff Click <cliffc@acm.org>2026-10-08 16:52:27 -0700
commitd32f97238c903765dec4e9a9f3cbfa5fd12cded6 (patch)
treea5ac731801ef7066bab6359c4e85c2bdd20082a6 /src/main/java/com/seaofnodes/simple/node/StopNode.java
parentb5ebb2032aa04cf4506d533127d373d4cf5a25c6 (diff)
downloadSimple-linear.tar.gz
Simple-linear.zip
Chapter 25: Modules, Separate Compilation, and SSA Constructionlinear
Co-authored-by: Hsiang-Ying Fu <66062782+fuhsnn@users.noreply.github.com> Co-authored-by: fuhsnn <66062782+fuhsnn@users.noreply.github.com> Co-authored-by: Symious <14933944+symious@users.noreply.github.com> Co-authored-by: Jun Kawasaki <jun784@gmail.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'src/main/java/com/seaofnodes/simple/node/StopNode.java')
-rw-r--r--src/main/java/com/seaofnodes/simple/node/StopNode.java79
1 files changed, 52 insertions, 27 deletions
diff --git a/src/main/java/com/seaofnodes/simple/node/StopNode.java b/src/main/java/com/seaofnodes/simple/node/StopNode.java
index 9f7a925b..e52a49a2 100644
--- a/src/main/java/com/seaofnodes/simple/node/StopNode.java
+++ b/src/main/java/com/seaofnodes/simple/node/StopNode.java
@@ -2,34 +2,45 @@ package com.seaofnodes.simple.node;
import com.seaofnodes.print.ExprPrinter;
-import com.seaofnodes.simple.type.Type;
-import com.seaofnodes.simple.util.Utils;
+import com.seaofnodes.simple.codegen.CodeGen;
+import com.seaofnodes.simple.type.*;
+import com.seaofnodes.simple.util.BAOS;
-public class StopNode extends CFGNode {
+import java.util.HashMap;
+import java.util.IdentityHashMap;
- public final String _src;
+// A collection of function ReturnNodes for a compilation unit.
+public class StopNode extends CFGNode {
- public StopNode(String src) {
+ public StopNode() {
super();
- _src = src;
_type = compute();
}
- public StopNode(StopNode stop) { super(stop); _src = stop==null ? null : stop._src; }
-
- @Override
- public String label() {
- return "Stop";
+ public StopNode(StopNode stop) { super(stop); }
+ @Override public Tag serialTag() { return Tag.Stop; }
+ @Override public void packed( BAOS baos, HashMap<String,Integer> strs, HashMap<Type,Integer> types, IdentityHashMap<Node, Integer> anodes ) { baos.packed1(nIns()); }
+ static Node make( BAOS bais ) {
+ StopNode stop = new StopNode();
+ stop.setDefX(bais.packed1()-1,null);
+ return stop;
}
@Override
protected ExprPrinter<Node> _print1(ExprPrinter<Node> p) {
// For the sake of many old tests, and single value prints as "return val"
- ReturnNode ret1 = ret();
+ ReturnNode ret1 = null;
+ for( Node n : _inputs ) {
+ if( n instanceof ReturnNode ret ) {
+ if( ret1 != null ) { ret1=null; break; }
+ ret1 = ret;
+ }
+ }
if( ret1!=null ) return p.n(ret1);
+
p.p("Stop[ ");
- for( Node ret : _inputs )
- if( ret!=null ) {
- String name = ((ReturnNode)ret).fun()._name;
+ for( Node n : _inputs )
+ if( n instanceof ReturnNode ret ) {
+ String name = ret.fun()._name;
if( name== null || !name.startsWith("sys.") )
p.n(ret).p(" ");
}
@@ -42,25 +53,36 @@ public class StopNode extends CFGNode {
// If a single Return, return it.
// Otherwise, null because ambiguous.
public ReturnNode ret() {
- Node ret1 = this;
- for( Node ret : _inputs ) {
- String name = ((ReturnNode)ret).fun()._name;
- if( name==null || !name.startsWith("sys.") )
- ret1 = ret1==this ? ((ReturnNode)ret) : null;
+ ReturnNode ret1 = null;
+ for( Node n : _inputs ) {
+ // TODO: remove isPublic
+ if( n instanceof ReturnNode ret && ret.fun().isPublic() ) {
+ if( ret1 != null ) return null; // Ambiguous
+ ret1 = ret;
+ }
}
- return ret1==this ? null : (ReturnNode)ret1;
+ return ret1;
}
@Override
- public Type compute() {
- return Type.BOTTOM;
+ public TypeTuple compute() {
+ // During Parsing, new Stops and Returns are being added. This Stop
+ // cannot know if more are coming, so must assume the worst.
+ if( CodeGen.CODE._phase ==null || CodeGen.CODE._phase == CodeGen.Phase.Parse )
+ return TypeTuple.STATE;
+
+ // Just meet-over-inputs.
+ TypeTuple tt = TypeTuple.STOP_HIGH;
+ for( Node def : _inputs )
+ tt = (TypeTuple)tt.meet(def._type);
+ assert tt.mem()._alias==1 && !tt.mem()._one;
+ return tt;
}
- @Override
- public Node idealize() {
+ @Override public Node idealize() {
int len = nIns();
for( int i=0; i<nIns(); i++ )
- if( addDep(((ReturnNode)in(i)).fun()).isDead() )
+ if( in(i).nIns()==0 )
delDef(i--);
if( len != nIns() ) return this;
return null;
@@ -70,7 +92,10 @@ public class StopNode extends CFGNode {
if( validIDepth() ) return _idepth;
int d=0;
for( Node ret : _inputs )
- d = Math.max(d,((ReturnNode)ret).idepth()+1);
+ // All public results are hooked on the Stop, including data
+ // values, so must check CFG
+ if( ret instanceof CFGNode cfg )
+ d = Math.max(d,cfg.idepth()+1);
return cacheIDepth(d);
}
}