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/ConFldOffNode.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/ConFldOffNode.java')
| -rw-r--r-- | src/main/java/com/seaofnodes/simple/node/ConFldOffNode.java | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/src/main/java/com/seaofnodes/simple/node/ConFldOffNode.java b/src/main/java/com/seaofnodes/simple/node/ConFldOffNode.java index afdd29be..f94fa484 100644 --- a/src/main/java/com/seaofnodes/simple/node/ConFldOffNode.java +++ b/src/main/java/com/seaofnodes/simple/node/ConFldOffNode.java @@ -2,11 +2,14 @@ package com.seaofnodes.simple.node; import com.seaofnodes.print.ExprPrinter; +import com.seaofnodes.simple.Parser; import com.seaofnodes.simple.codegen.CodeGen; import com.seaofnodes.simple.type.Type; import com.seaofnodes.simple.type.TypeInteger; import com.seaofnodes.simple.type.TypeStruct; import com.seaofnodes.simple.util.SB; +import com.seaofnodes.simple.util.Utils; +import java.util.HashMap; /** * A field offset. This becomes a constant *after* other optimizations which @@ -15,27 +18,57 @@ import com.seaofnodes.simple.util.SB; */ public class ConFldOffNode extends ConstantNode { - public final String _name; // Struct name + public TypeStruct _ts; // Struct holding field public final String _fname; // Field name - public ConFldOffNode( String name, String fname ) { super(TypeInteger.BOT); _name = name; _fname = fname; } + public ConFldOffNode( TypeStruct ts, String fname ) { super(TypeInteger.BOT); _ts = ts; _fname = fname; } + @Override public Tag serialTag() { throw Utils.TODO("should not reach here"); } @Override public String label() { - return _fname == " len" ? "sizeof("+_name+")" : "#"+_fname; + return _fname == " len" ? "sizeof("+_ts._name+")" : "#"+_fname; } @Override protected ExprPrinter<Node> _print1(ExprPrinter<Node> p) { return p.p(label()); } + @Override public Node idealize() { + // Some array offsets are known early + if( _ts.isAry() ) { + // Length always at offset zero + if( _fname==" len" ) + return CodeGen.CODE.ZERO; + // The shift depends on the element + if( _fname=="<<" ) + return Node.con(_ts.aryScale()); + // The base depends on the layout (alignment for large elements may + // involve padding) and MAY depend on the length if I go for + // smaller array lengths. + } + return null; + } + // Convert field offset to an integer - public Node asOffset(TypeStruct ts) { - return new ConstantNode(TypeInteger.constant(ts.offset(_fname==" len" ? ts._fields.length : ts.find(_fname)))).peephole(); + public Node asOffset() { + int fldx = _fname==" len" ? _ts._fields.length : _ts.find(_fname); + if( fldx == -1 ) return null; + // " len" selects the terminal size slot, not a Field. + if( fldx < _ts._fields.length && _ts._fields[fldx]._extern ) + return new ExternOffsetNode(_fname).peephole(); + return ConstantNode.make(TypeInteger.constant(_ts.offset(fldx))).peephole(); } + // Upgrade the internal type + @Override boolean _upgradeType( HashMap<String,Type> TYPES) { + boolean progress = super._upgradeType(TYPES); + TypeStruct ts = (TypeStruct)_ts.upgradeType(TYPES); + if( ts == _ts ) return progress; + _ts = ts; + return true; + } @Override public boolean eq(Node n) { ConFldOffNode off = (ConFldOffNode)n; // Invariant - return _name.equals(off._name) && _fname.equals(off._fname) && super.eq(n); + return _ts._name==off._ts._name && _fname.equals(off._fname) && super.eq(n); } - @Override int hash() { return super.hash() * _name.hashCode() * _fname.hashCode(); } + @Override int hash() { return super.hash() * _ts._name.hashCode() * _fname.hashCode(); } } |
