summaryrefslogtreecommitdiff
path: root/src/main/java/com/seaofnodes/simple/node/MemPhiNode.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/seaofnodes/simple/node/MemPhiNode.java')
-rw-r--r--src/main/java/com/seaofnodes/simple/node/MemPhiNode.java62
1 files changed, 45 insertions, 17 deletions
diff --git a/src/main/java/com/seaofnodes/simple/node/MemPhiNode.java b/src/main/java/com/seaofnodes/simple/node/MemPhiNode.java
index 787333d9..cdfaaf97 100644
--- a/src/main/java/com/seaofnodes/simple/node/MemPhiNode.java
+++ b/src/main/java/com/seaofnodes/simple/node/MemPhiNode.java
@@ -1,39 +1,64 @@
package com.seaofnodes.simple.node;
-import com.seaofnodes.simple.codegen.CodeGen;
import com.seaofnodes.simple.type.Type;
import com.seaofnodes.simple.type.TypeMem;
+import com.seaofnodes.simple.codegen.GlobalBits;
+import com.seaofnodes.simple.util.BAOS;
-/** A Phi for one field alias, parallel to a bulk Phi at the same Region. */
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+
+/** A Phi for one precise memory alias. */
public class MemPhiNode extends PhiNode {
+
public final int _alias;
public MemPhiNode(String label, int alias, Node... inputs) {
- super(label,TypeMem.make(alias,Type.BOTTOM),inputs);
+ super(label, inputs);
assert alias > 1;
_alias = alias;
}
- public MemPhiNode(MemPhiNode phi) { super(phi); _alias = phi._alias; }
+ public MemPhiNode(MemPhiNode phi) {
+ super(phi,phi._label);
+ _alias = phi._alias;
+ }
+
+ @Override public Tag serialTag() { return Tag.MemPhi; }
+
+ @Override
+ public void packed(BAOS baos, HashMap<String,Integer> strs, HashMap<Type,Integer> types,
+ IdentityHashMap<Node,Integer> anodes) {
+ super.packed(baos,strs,types,anodes);
+ baos.packed2(_alias);
+ }
- @Override public String label() { return "MemPhi_"+_alias; }
+ static Node make(BAOS bais, String[] strs, Type[] types, GlobalBits fileAliases, GlobalBits aliases) {
+ Node[] ins = new Node[bais.packed1()];
+ String label = strs[bais.packed2()];
+ int alias = bais.packed2();
+ if( alias >= GlobalBits.RESERVED ) alias = aliases.map(fileAliases,alias);
+ return new MemPhiNode(label,alias,ins);
+ }
- @Override public Type compute() {
+ @Override
+ public Type compute() {
+ Type t = super.compute();
assert BulkMemPhiNode.checkMem(this,_alias);
- if( !(region() instanceof RegionNode r) )
- return (region()._type==Type.XCONTROL || region()._type==Type.TOP) ? TypeMem.TOP : _type;
- if( r.inProgress() ) return r instanceof LoopNode ? _minType : TypeMem.BOT;
- Type t = Type.TOP;
- for( int i=1; i<nIns(); i++ )
- if( addDep(r.in(i))._type!=Type.XCONTROL && r.in(i)._type!=Type.TOP )
- t = t.meet(MemMergeNode.contents(in(i),_alias,this));
- return TypeMem.make(_alias,t);
+ if( !(t instanceof TypeMem tmem) ) return t;
+ assert tmem._alias==1 || tmem._alias==_alias;
+ // This Phi structurally knows its alias, but not whether the field is
+ // final. Do not infer slice finality from evolving input types.
+ return TypeMem.make(_alias,tmem._t,tmem._one,tmem._clz,false,tmem._escFs,tmem._escAs);
}
- @Override public Node idealize() {
+ @Override
+ public Node idealize() {
+ // A precise memory Phi can always bypass a MemMerge and select its
+ // matching slice.
for( int i=1; i<nIns(); i++ )
if( in(i) instanceof MemMergeNode mem ) {
- setDef(i,CodeGen.CODE.add(mem.alias(_alias)));
+ setDef(i,mem.alias(_alias));
return this;
}
if( nIns()==3 && region() instanceof LoopNode loop && !loop.inProgress() &&
@@ -44,6 +69,9 @@ public class MemPhiNode extends PhiNode {
return super.idealize();
}
- @Override public boolean eq(Node n) { return _alias==((MemPhiNode)n)._alias && super.eq(n); }
+ @Override public boolean eq(Node n) {
+ return _alias==((MemPhiNode)n)._alias && super.eq(n);
+ }
+
@Override int hash() { return _alias; }
}