diff options
| author | Cliff Click <cliffc@acm.org> | 2026-08-10 11:11:18 -0700 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2026-10-08 16:52:27 -0700 |
| commit | d32f97238c903765dec4e9a9f3cbfa5fd12cded6 (patch) | |
| tree | a5ac731801ef7066bab6359c4e85c2bdd20082a6 /src/main/java/com/seaofnodes/simple/print/SimpleGraphAdapter.java | |
| parent | b5ebb2032aa04cf4506d533127d373d4cf5a25c6 (diff) | |
| download | Simple-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/print/SimpleGraphAdapter.java')
| -rw-r--r-- | src/main/java/com/seaofnodes/simple/print/SimpleGraphAdapter.java | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/src/main/java/com/seaofnodes/simple/print/SimpleGraphAdapter.java b/src/main/java/com/seaofnodes/simple/print/SimpleGraphAdapter.java index 8dc6ea47..9ca0ec51 100644 --- a/src/main/java/com/seaofnodes/simple/print/SimpleGraphAdapter.java +++ b/src/main/java/com/seaofnodes/simple/print/SimpleGraphAdapter.java @@ -2,22 +2,30 @@ package com.seaofnodes.simple.print; import com.seaofnodes.graph.GraphAdapter; import com.seaofnodes.graph.GraphSnapshot.*; +import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.node.Node; import com.seaofnodes.simple.type.TypeMem; -/** Chapter 24's view of the IR; browser, transport and layout are shared. */ +/** Chapter 25's view of the IR, including partially constructed parse-time graphs. */ public class SimpleGraphAdapter extends GraphAdapter<Node> { + @Override protected boolean show(Node n) { + if( n != CodeGen.CODE.ZERO && n != CodeGen.CODE.XCTRL ) return true; + for( int i=0; i<n.nOuts(); i++ ) + if( n.out(i) != null ) return true; + return false; // The parser's keep is not a graph use. + } + @Override protected String edgeName(Node n, int i) { return n instanceof ScopeNode scope && i < scope._vars.size() - ? scope._vars.get(i)._name : null; + ? scope.var(i)._name : null; } @Override protected int edgeJump(Node n, int i) { return n instanceof CallEndNode && i>0 && n.in(i) instanceof ReturnNode ret ? ref(ret.fun()) : 0; } - @Override protected int projectionIndex(Node n) { return n instanceof ProjNode p ? p._idx : n instanceof CProjNode p ? p._idx : -1; } + @Override protected int projectionIndex(Node n) { return n instanceof Proj p ? p.idx() : -1; } @Override protected boolean folding(Node n) { if( n instanceof FunNode fun ) return fun.folding(); @@ -32,26 +40,41 @@ public class SimpleGraphAdapter extends GraphAdapter<Node> { @Override protected Kind kind(Node n) { if( n instanceof StopNode ) return Kind.STOP; if( n instanceof ScopeNode ) return Kind.SCOPE; + if( n instanceof StartCUNode ) return Kind.UNIT; if( n instanceof FunNode ) return Kind.FUN; - if( n instanceof StartNode ) return Kind.CTRL; + // Start inherits Loop for whole-program analysis, but is not a source loop. + if( n instanceof StartNode ) return Kind.START; if( n instanceof LoopNode ) return Kind.LOOP; if( n instanceof RegionNode ) return Kind.REGION; if( n instanceof PhiNode ) return Kind.PHI; - return n instanceof CFGNode ? Kind.CTRL : isMem(n) ? Kind.MEM : Kind.DATA; + if( n instanceof CFGNode ) return Kind.CTRL; + return isMem(n) ? Kind.MEM : Kind.DATA; } @Override protected Role role(Node n, int i) { - if( n instanceof ScopeNode || n instanceof ConstantNode || n instanceof CtrlNode || n instanceof XCtrlNode ) return Role.ASSOC; - if( n instanceof PhiNode ) return i == 0 ? Role.ASSOC : isMem(n) ? Role.MEM : Role.DATA; - if( n instanceof ProjNode || n instanceof CProjNode ) + if( n instanceof ScopeNode || n instanceof ConstantNode || n instanceof FunPtrNode || + n instanceof CtrlNode || n instanceof XCtrlNode ) + return Role.ASSOC; + if( n instanceof PhiNode ) + return i == 0 ? Role.ASSOC : isMem(n) ? Role.MEM : Role.DATA; + if( n instanceof Proj ) return n instanceof CFGNode ? Role.CTRL : isMem(n) ? Role.MEM : Role.DATA; + // StartCU inherits Region, but slot 0 really connects it to Start. + if( n instanceof StartCUNode && i == 0 ) return Role.CTRL; if( n instanceof RegionNode && i == 0 ) return Role.ASSOC; + // Preserve known slot roles even when an input is not attached/typed yet. if( i == 0 || n instanceof RegionNode || n instanceof StopNode ) return Role.CTRL; - if( n instanceof MemMergeNode || (i == 1 && (n instanceof MemOpNode || n instanceof ReturnNode || n instanceof CallNode || n instanceof NewNode)) ) return Role.MEM; + if( n instanceof MemMergeNode || + (i == 1 && (n instanceof MemOpNode || n instanceof ReturnNode || n instanceof CallNode)) || + (n instanceof EscapeNode && i >= 2) ) return Role.MEM; Node def = n.in(i); + if( def instanceof CFGNode ) return Role.CTRL; if( def != null && isMem(def) ) return Role.MEM; return Role.DATA; } - private boolean isMem(Node n) { return n.isMem() || n._type instanceof TypeMem; } + private boolean isMem(Node n) { + // These Phi subclasses are memory even before their first type computation. + return n instanceof MemPhiNode || n instanceof BulkMemPhiNode || n.isMem() || n._type instanceof TypeMem; + } } |
