summaryrefslogtreecommitdiff
path: root/src/main/java/com/seaofnodes/simple/node/ParmNode.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/ParmNode.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/ParmNode.java')
-rw-r--r--src/main/java/com/seaofnodes/simple/node/ParmNode.java72
1 files changed, 57 insertions, 15 deletions
diff --git a/src/main/java/com/seaofnodes/simple/node/ParmNode.java b/src/main/java/com/seaofnodes/simple/node/ParmNode.java
index 95934e4b..899d7639 100644
--- a/src/main/java/com/seaofnodes/simple/node/ParmNode.java
+++ b/src/main/java/com/seaofnodes/simple/node/ParmNode.java
@@ -2,28 +2,54 @@ package com.seaofnodes.simple.node;
import com.seaofnodes.print.ExprPrinter;
-import com.seaofnodes.simple.Parser;
-import com.seaofnodes.simple.type.Type;
-import com.seaofnodes.simple.type.TypeMemPtr;
+import com.seaofnodes.simple.type.*;
+import com.seaofnodes.simple.util.BAOS;
+
+import java.util.HashMap;
+import java.util.IdentityHashMap;
public class ParmNode extends PhiNode {
// Argument indices are mapped one-to-one on CallNode inputs
public final int _idx; // Argument index
+ public Type _declaredType;
public ParmNode(String label, int idx, Type declaredType, Node... inputs) {
- super(label,declaredType,inputs);
+ super(label, inputs);
_idx = idx;
+ _declaredType = declaredType;
+ _type = declaredType;
+ }
+ public ParmNode(ParmNode parm) { super(parm, parm._label ); _idx = parm._idx; _declaredType = parm._declaredType; }
+ @Override public Tag serialTag() { return Tag.Parm; }
+ @Override public void packed( BAOS baos, HashMap<String,Integer> strs, HashMap<Type,Integer> types, IdentityHashMap<Node, Integer> anodes ) {
+ baos.packed1(nIns()); // Number of linked calls
+ baos.packed2(_label==null ? 0 : strs.get(_label));
+ baos.packed2(types.get(_declaredType)); // NPE if fails lookup
+ baos.packed1(_idx);
+ }
+ static Node make( BAOS bais, String[] strs, Type[] types) {
+ Node[] ins = new Node[bais.packed1()];
+ String label = strs[bais.packed2()];
+ Type minType = types[bais.packed2()];
+ return new ParmNode(label, bais.packed1(), minType, ins);
}
- public ParmNode(ParmNode parm) { super(parm, parm._label, parm._minType ); _idx = parm._idx; }
@Override public String label() { return MemOpNode.mlabel(_label); }
+ @Override boolean _upgradeType( HashMap<String,Type> TYPES) {
+ Type t = _declaredType.upgradeType(TYPES);
+ if( t == _declaredType ) return false;
+ unlock();
+ _declaredType = t;
+ return true;
+ }
+
public FunNode fun() { return (FunNode)in(0); }
@Override
protected ExprPrinter<Node> _print1(ExprPrinter<Node> p) {
- if( "main".equals(fun()._name) && _label.equals("arg") )
+ if( fun()._name!=null && fun()._name.endsWith("<clinit>") && _label.equals("arg") )
return p.p("arg");
p.p("Parm_").p(_label).open();
for( Node in : _inputs ) p.n(in).p(",");
@@ -35,20 +61,36 @@ public class ParmNode extends PhiNode {
@Override public boolean inProgress() { return in(0) instanceof FunNode fun && fun.inProgress(); }
@Override
+ public Type compute() {
+ if( !(region() instanceof RegionNode r) )
+ return region()._type==Type.XCONTROL || region()._type==Type.TOP ? (_type instanceof TypeMem ? TypeMem.TOP : Type.TOP) : _type;
+ // During parsing Phis have to be computed type pessimistically.
+ if( r.inProgress() || in(nIns()-1)==null )
+ return _declaredType;
+ // Set type to local top of the starting type
+ Type t = Type.TOP;
+ for( int i = 1; i < nIns(); i++ ) {
+ // If the region's control input is live, add this as a dependency
+ // to the control because we can be peeped should it become dead.
+ Type ctrl = addDep(r.in(i))._type;
+ if( ctrl != Type.XCONTROL && ctrl != Type.TOP ) {
+ if( in(i)._type==Type.BOTTOM )
+ return Type.BOTTOM;
+ t = t.meet(in(i)._type);
+ }
+ }
+ return t.join(_declaredType);
+ }
+
+ @Override
public Node idealize() {
if( !(region() instanceof FunNode) )
- return in(1); // Input has collapse to e.g. starting control.
+ // A dead function can lose every caller before the Parm itself is
+ // removed; there is no replacement input in that transient form.
+ return nIns()==1 ? null : in(1); // Input has collapse to e.g. starting control.
// If function is folding, do all possible peeps
if( fun()._folding ) return super.idealize();
- // Can upgrade minType even while in-progress
- if( _minType instanceof TypeMemPtr tmp && _minType.isFRef() ) {
- TypeMemPtr tmp2 = (TypeMemPtr) Parser.TYPES.get(tmp._obj._name);
- if( tmp2!=null && tmp2 != _minType ) {
- _minType = tmp2;
- return this;
- }
- }
// Skip most phi optimizations on parms
return null;
}