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/node/ParmNode.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/node/ParmNode.java')
| -rw-r--r-- | src/main/java/com/seaofnodes/simple/node/ParmNode.java | 72 |
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; } |
