aa
StoreNode.java
Go to the documentation of this file.
1 package com.cliffc.aa.node;
2 
3 import com.cliffc.aa.Env;
4 import com.cliffc.aa.GVNGCM;
5 import com.cliffc.aa.Parse;
6 import com.cliffc.aa.type.*;
7 import com.cliffc.aa.tvar.*;
8 import com.cliffc.aa.util.Util;
9 
10 import static com.cliffc.aa.type.TypeFld.Access;
11 
12 // Store a value into a named struct field. Does it's own nil-check and value
13 // testing; also checks final field updates.
14 public class StoreNode extends Node {
15  final String _fld; // Field being updated
16  private final Access _fin; // TypeFld.Access.Final or TypeFld.Access.RW
17  private final Parse _bad;
18  public StoreNode( Node mem, Node adr, Node val, Access fin, String fld, Parse bad ) {
19  super(OP_STORE,null,mem,adr,val);
20  _fld = fld;
21  _fin = fin;
22  _bad = bad; // Tests can pass a null, but nobody else does
23  }
24  private StoreNode( StoreNode st, Node mem, Node adr ) { this(mem,adr,st.rez(),st._fin,st._fld,st._bad); }
25 
26  @Override public String xstr() { return "."+_fld+"="; } // Self short name
27  String str() { return xstr(); } // Inline short name
28  @Override public boolean is_mem() { return true; }
29 
30  Node mem() { return in(1); }
31  Node adr() { return in(2); }
32  Node rez() { return in(3); }
33  public int find(TypeStruct ts) { return ts.fld_find(_fld); }
34 
35  @Override public Node ideal_reduce() {
36  Node mem = mem();
37  Node adr = adr();
38  Type ta = adr._val;
39  TypeMemPtr tmp = ta instanceof TypeMemPtr ? (TypeMemPtr)ta : null;
40 
41  // Is this Store dead from below?
42  if( mem==this ) return null;
43  if( ta.above_center() ) return mem;
44  if( tmp!=null && _live.ld(tmp)==TypeObj.UNUSED ) return mem;
45 
46  // If Store is by a New and no other Stores, fold into the New.
47  NewObjNode nnn; int idx;
48  if( mem instanceof MrgProjNode && mem._keep==0 &&
49  mem.in(0) instanceof NewObjNode && (nnn=(NewObjNode)mem.in(0)) == adr.in(0) &&
50  !rez().is_forward_ref() &&
51  mem._uses._len==2 && // Use is by DefMem and self
52  (idx=nnn._ts.fld_find(_fld))!= -1 && nnn._ts.fld(idx)._access==Access.RW ) {
53  // Update the value, and perhaps the final field
54  nnn.update(idx,_fin,rez());
55  mem.xval();
56  Env.GVN.add_flow_uses(this);
57  add_reduce_extra(); // Folding in allows store followers to fold in
58  return mem; // Store is replaced by using the New directly.
59  }
60 
61  // If Store is of a MemJoin and it can enter the split region, do so.
62  // Requires no other memory *reader* (or writer), as the reader will
63  // now see the Store effects as part of the Join.
64  if( _keep<=1 && tmp != null && mem._keep==0 && mem instanceof MemJoinNode && mem._uses._len==1 ) {
65  Node memw = _uses._len==0 ? this : get_mem_writer(); // Zero or 1 mem-writer
66  // Check the address does not have a memory dependence on the Join.
67  // TODO: This is super conservative
68  if( adr instanceof FreshNode ) adr = ((FreshNode)adr).id();
69  if( memw != null && adr instanceof ProjNode && adr.in(0) instanceof NewNode )
70  return ((MemJoinNode)mem).add_alias_below_new(new StoreNode(this,mem,adr()),this);
71  }
72 
73  return null;
74  }
75  @Override public Node ideal_mono() { return null; }
76  @Override public Node ideal_grow() {
77  Node mem = mem();
78  Node adr = adr();
79  Type ta = adr._val;
80  TypeMemPtr tmp = ta instanceof TypeMemPtr ? (TypeMemPtr)ta : null;
81 
82  // If Store is of a memory-writer, and the aliases do not overlap, make parallel with a Join
83  if( tmp != null && (tmp._aliases!=BitsAlias.NIL.dual()) &&
84  mem.is_mem() && mem.check_solo_mem_writer(this) ) {
85  Node head2;
86  if( mem instanceof StoreNode ) head2=mem;
87  else if( mem instanceof MrgProjNode && ((MrgProjNode)mem).mem()!=this ) head2=mem;
88  else if( mem instanceof MProjNode && mem.in(0) instanceof CallEpiNode ) head2 = mem.in(0).in(0);
89  else head2 = null;
90  // Check no extra readers/writers at the split point
91  if( head2 != null && MemSplitNode.check_split(this,escapees()) ) {
92  MemSplitNode.insert_split(this, escapees(), this, mem, head2);
93  assert _uses._len==1 && _uses.at(0) instanceof MemJoinNode;
94  return _uses.at(0); // Return the mem join
95  }
96  }
97  return null;
98  }
99  // Liveness changes, check if reduce
100  @Override public void add_flow_extra(Type old) {
101  Env.GVN.add_reduce(this); // Args can be more-alive
102  }
103  // If changing an input or value allows the store to no longer be in-error,
104  // following Loads can collapse
105  @Override public void add_reduce_extra() {
106  for( Node use : _uses )
107  if( use instanceof LoadNode )
109  }
110 
111  // StoreNode needs to return a TypeObj for the Parser.
112  @Override public Type value(GVNGCM.Mode opt_mode) {
113  Node mem = mem(), adr = adr(), rez = rez();
114  Type tmem = mem._val;
115  Type tadr = adr._val;
116  Type tval = rez._val; // Value
117  if( tmem==Type.ALL || tadr==Type.ALL ) return Type.ALL;
118 
119  if( !(tmem instanceof TypeMem ) ) return tmem.oob(TypeMem.ALLMEM);
120  if( !(tadr instanceof TypeMemPtr) ) return tadr.above_center() ? tmem : TypeMem.ALLMEM;
121  TypeMem tm = (TypeMem )tmem;
122  TypeMemPtr tmp = (TypeMemPtr)tadr;
123  return tm.update(tmp._aliases,_fin,_fld,tval);
124  }
125  @Override BitsAlias escapees() {
126  Type adr = adr()._val;
127  if( !(adr instanceof TypeMemPtr) ) return adr.above_center() ? BitsAlias.EMPTY : BitsAlias.FULL;
128  return ((TypeMemPtr)adr)._aliases;
129  }
130 
131  @Override public TypeMem all_live() { return TypeMem.ALLMEM; }
132  // Compute the liveness local contribution to def's liveness. Ignores the
133  // incoming memory types, as this is a backwards propagation of demanded
134  // memory.
135  @Override public TypeMem live_use(GVNGCM.Mode opt_mode, Node def ) {
136  if( def==mem() ) return _live; // Pass full liveness along
137  if( def==adr() ) return TypeMem.ALIVE; // Basic aliveness
138  if( def==rez() ) return TypeMem.ESCAPE;// Value escapes
139  throw com.cliffc.aa.AA.unimpl(); // Should not reach here
140  }
141 
142  @Override public ErrMsg err( boolean fast ) {
143  Type tadr = adr()._val;
144  if( tadr.must_nil() ) return fast ? ErrMsg.FAST : ErrMsg.niladr(_bad,"Struct might be nil when writing",_fld);
145  if( !(tadr instanceof TypeMemPtr) )
146  return bad("Unknown",fast,null); // Not a pointer nor memory, cannot store a field
147  TypeMemPtr ptr = (TypeMemPtr)tadr;
148  Type tmem = mem()._val;
149  if( tmem==Type.ALL ) return bad("Unknown",fast,null);
150  if( tmem==Type.ANY ) return null; // No error
151  TypeObj objs = tmem instanceof TypeMem
152  ? ((TypeMem)tmem).ld(ptr) // General load from memory
153  : ((TypeObj)tmem);
154  if( !(objs instanceof TypeStruct) ) return bad("No such",fast,objs);
155  TypeStruct ts = (TypeStruct)objs;
156  int idx = ts.fld_find(_fld);
157  if( idx==-1 ) return bad("No such",fast,objs);
158  Access access = ts.fld(idx)._access;
159  if( access!=Access.RW )
160  return bad("Cannot re-assign "+access,fast,ts);
161  return null;
162  }
163  private ErrMsg bad( String msg, boolean fast, TypeObj to ) {
164  if( fast ) return ErrMsg.FAST;
165  boolean is_closure = adr() instanceof ProjNode && adr().in(0) instanceof NewObjNode && ((NewObjNode)adr().in(0))._is_closure;
166  return ErrMsg.field(_bad,msg,_fld,is_closure,to);
167  }
168  @Override public int hashCode() { return super.hashCode()+_fld.hashCode()+_fin.hashCode(); }
169  // Stores are can be CSE/equal, and we might force a partial execution to
170  // become a total execution (require a store on some path it didn't happen).
171  // This can be undone later with splitting.
172  @Override public boolean equals(Object o) {
173  if( this==o ) return true;
174  if( !(o instanceof StoreNode) || !super.equals(o) ) return false;
175  StoreNode st = (StoreNode)o;
176  return _fin==st._fin && Util.eq(_fld,st._fld);
177  }
178 
179  @Override public boolean unify( boolean test ) {
180  return unify(this,rez(),_fld,test,"Store_unify");
181  }
182 
183  public static boolean unify( Node n, Node rez, String fld, boolean test, String alloc_site) {
184  // Input should be a TMem
185  TV2 tmem = n.tvar(1);
186  if( !tmem.isa("Mem") ) return false;
187  // Address needs to name the aliases
188  Type tadr = n.val(2);
189  if( !(tadr instanceof TypeMemPtr) ) return false; // Wait until types are sharper
190  TypeMemPtr tmp = (TypeMemPtr)tadr;
191  // This produces same memory
192  boolean progress = n.tvar().unify(tmem,test);
193  if( progress && test ) return progress;
194 
195  // Unify the given aliases and field against the stored type
196  return tmem.unify_alias_fld(n,tmp._aliases,fld,rez.tvar(),test,alloc_site);
197  }
198 
199 }
com.cliffc.aa.type.Bits.dual
B dual()
Definition: Bits.java:368
com.cliffc.aa.node.StoreNode.live_use
TypeMem live_use(GVNGCM.Mode opt_mode, Node def)
Definition: StoreNode.java:135
com.cliffc.aa.type.BitsAlias.FULL
static BitsAlias FULL
Definition: BitsAlias.java:27
com.cliffc.aa.node.StoreNode.StoreNode
StoreNode(Node mem, Node adr, Node val, Access fin, String fld, Parse bad)
Definition: StoreNode.java:18
com.cliffc.aa.node.StoreNode.StoreNode
StoreNode(StoreNode st, Node mem, Node adr)
Definition: StoreNode.java:24
com.cliffc.aa.node.StoreNode.xstr
String xstr()
Definition: StoreNode.java:26
com.cliffc.aa.node.StoreNode.unify
boolean unify(boolean test)
Definition: StoreNode.java:179
com.cliffc.aa.tvar.TV2.unify
boolean unify(TV2 that, boolean test)
Definition: TV2.java:288
com.cliffc.aa.type.TypeMem.ld
TypeObj ld(TypeMemPtr ptr)
Definition: TypeMem.java:325
com.cliffc.aa.node.MrgProjNode.mem
Node mem()
Definition: MrgProjNode.java:15
com.cliffc.aa.node.StoreNode.adr
Node adr()
Definition: StoreNode.java:31
com.cliffc.aa.type.TypeMem.update
TypeMem update(BitsAlias aliases, Access fin, String fld, Type val)
Definition: TypeMem.java:459
com.cliffc.aa.type.TypeMem
Memory type; the state of all of memory; memory edges order memory ops.
Definition: TypeMem.java:53
com.cliffc.aa.util.Util.eq
static boolean eq(String s0, String s1)
Definition: Util.java:16
com.cliffc.aa.node.NewObjNode.update
void update(String tok, Access mutable, Node val)
Definition: NewObjNode.java:64
com.cliffc.aa.GVNGCM.add_mono
public< N extends Node > N add_mono(N n)
Definition: GVNGCM.java:51
com.cliffc.aa.node.Node._live
TypeMem _live
Definition: Node.java:89
com.cliffc.aa.GVNGCM.add_flow_uses
void add_flow_uses(Node n)
Definition: GVNGCM.java:55
com.cliffc
com.cliffc.aa.node.StoreNode.value
Type value(GVNGCM.Mode opt_mode)
Definition: StoreNode.java:112
com.cliffc.aa.node.Node.get_mem_writer
Node get_mem_writer()
Definition: Node.java:840
com.cliffc.aa.type.TypeFld
Definition: TypeFld.java:12
com.cliffc.aa.node.Node
Definition: Node.java:16
com.cliffc.aa.node.StoreNode.hashCode
int hashCode()
Definition: StoreNode.java:168
com.cliffc.aa.util
Definition: AbstractEntry.java:1
com.cliffc.aa.type.TypeMem.ESCAPE
static final TypeMem ESCAPE
Definition: TypeMem.java:227
com.cliffc.aa.node.StoreNode._bad
final Parse _bad
Definition: StoreNode.java:17
com.cliffc.aa.tvar
Definition: TV2.java:1
com.cliffc.aa.type.Type
an implementation of language AA
Definition: Type.java:94
com.cliffc.aa.node.MemJoinNode
Definition: MemJoinNode.java:15
com.cliffc.aa.node.StoreNode
Definition: StoreNode.java:14
com.cliffc.aa.type.BitsAlias
Definition: BitsAlias.java:8
com.cliffc.aa.node.StoreNode.ideal_grow
Node ideal_grow()
Definition: StoreNode.java:76
com.cliffc.aa.type.TypeFld.Access.RW
RW
Definition: TypeFld.java:111
com.cliffc.aa.node.Node.ErrMsg.niladr
static ErrMsg niladr(Parse loc, String msg, String fld)
Definition: Node.java:934
com.cliffc.aa.type.TypeMem.ALLMEM
static final TypeMem ALLMEM
Definition: TypeMem.java:228
com.cliffc.aa.node.Node._val
Type _val
Definition: Node.java:88
com.cliffc.aa.node.LoadNode
Definition: LoadNode.java:13
com.cliffc.aa.type.Type.ANY
static final Type ANY
Definition: Type.java:325
com.cliffc.aa.node.Node.ErrMsg
Definition: Node.java:888
com.cliffc.aa.type.TypeStruct
A memory-based collection of optionally named fields.
Definition: TypeStruct.java:50
com.cliffc.aa.AA.unimpl
static RuntimeException unimpl()
Definition: AA.java:10
com.cliffc.aa.node.MProjNode
Definition: MProjNode.java:10
com.cliffc.aa.node.StoreNode.add_reduce_extra
void add_reduce_extra()
Definition: StoreNode.java:105
com.cliffc.aa.node.StoreNode.ideal_reduce
Node ideal_reduce()
Definition: StoreNode.java:35
com.cliffc.aa.type.Type.ALL
static final Type ALL
Definition: Type.java:324
com.cliffc.aa.tvar.TV2.unify_alias_fld
boolean unify_alias_fld(Node ldst, BitsAlias aliases, String fld, TV2 tv, boolean test, String alloc_site)
Definition: TV2.java:488
com.cliffc.aa.node.Node.check_solo_mem_writer
boolean check_solo_mem_writer(Node memw)
Definition: Node.java:845
com.cliffc.aa.node.StoreNode._fld
final String _fld
Definition: StoreNode.java:15
com.cliffc.aa.Env.GVN
static final GVNGCM GVN
Definition: Env.java:13
com.cliffc.aa.type.TypeObj
Definition: TypeObj.java:15
com.cliffc.aa.node.StoreNode.add_flow_extra
void add_flow_extra(Type old)
Definition: StoreNode.java:100
com.cliffc.aa.type.TypeFld._access
Access _access
Definition: TypeFld.java:17
com.cliffc.aa.type.Type.above_center
boolean above_center()
Definition: Type.java:741
com.cliffc.aa.type.BitsAlias.NIL
static BitsAlias NIL
Definition: BitsAlias.java:27
com.cliffc.aa.node.StoreNode.unify
static boolean unify(Node n, Node rez, String fld, boolean test, String alloc_site)
Definition: StoreNode.java:183
com.cliffc.aa.node.Node._keep
byte _keep
Definition: Node.java:86
com.cliffc.aa.node.StoreNode.bad
ErrMsg bad(String msg, boolean fast, TypeObj to)
Definition: StoreNode.java:163
com.cliffc.aa.util.Util
Definition: Util.java:5
com.cliffc.aa.type.TypeObj.UNUSED
static final TypeObj UNUSED
Definition: TypeObj.java:46
com.cliffc.aa.node.StoreNode.err
ErrMsg err(boolean fast)
Definition: StoreNode.java:142
com.cliffc.aa.node.Node.ErrMsg.FAST
static final ErrMsg FAST
Definition: Node.java:893
com.cliffc.aa.node.Node.in
Node in(int i)
Definition: Node.java:126
com.cliffc.aa.node.MemSplitNode.check_split
static boolean check_split(Node head1, BitsAlias head1_escs)
Definition: MemSplitNode.java:165
com.cliffc.aa.type.Type.must_nil
boolean must_nil()
Definition: Type.java:845
com.cliffc.aa.type.TypeMem.ALIVE
static final TypeMem ALIVE
Definition: TypeMem.java:226
com.cliffc.aa.GVNGCM
Definition: GVNGCM.java:12
com.cliffc.aa.node.StoreNode.is_mem
boolean is_mem()
Definition: StoreNode.java:28
com.cliffc.aa.node.FreshNode
Definition: FreshNode.java:11
com.cliffc.aa.type.BitsAlias.EMPTY
static BitsAlias EMPTY
Definition: BitsAlias.java:27
com.cliffc.aa.node.ProjNode
Definition: ProjNode.java:11
com.cliffc.aa.node.NewObjNode
Definition: NewObjNode.java:20
com.cliffc.aa.node.StoreNode._fin
final Access _fin
Definition: StoreNode.java:16
com.cliffc.aa.tvar.TV2.isa
boolean isa(String s)
Definition: TV2.java:77
com.cliffc.aa.node.Node._uses
Ary< Node > _uses
Definition: Node.java:245
com.cliffc.aa.node.Node.is_mem
boolean is_mem()
Definition: Node.java:838
com.cliffc.aa.AA
an implementation of language AA
Definition: AA.java:9
com.cliffc.aa.node.Node.OP_STORE
static final byte OP_STORE
Definition: Node.java:47
com.cliffc.aa.type.TypeStruct.fld_find
int fld_find(String fld)
Definition: TypeStruct.java:1038
com.cliffc.aa.node.Node.val
Type val(int idx)
Definition: Node.java:470
com.cliffc.aa
Definition: AA.java:1
com.cliffc.aa.node.StoreNode.escapees
BitsAlias escapees()
Definition: StoreNode.java:125
com.cliffc.aa.type.TypeStruct.fld
TypeFld fld(int idx)
Definition: TypeStruct.java:1012
com.cliffc.aa.node.NewNode
Definition: NewNode.java:17
com.cliffc.aa.node.MrgProjNode
Definition: MrgProjNode.java:10
com.cliffc.aa.node.Node.is_forward_ref
boolean is_forward_ref()
Definition: Node.java:830
com.cliffc.aa.type.TypeMemPtr._aliases
BitsAlias _aliases
Definition: TypeMemPtr.java:16
com.cliffc.aa.GVNGCM.add_reduce
public< N extends Node > N add_reduce(N n)
Definition: GVNGCM.java:49
com.cliffc.aa.node.CallEpiNode
Definition: CallEpiNode.java:24
com.cliffc.aa.tvar.TV2
Definition: TV2.java:23
com.cliffc.aa.node.MemSplitNode
Definition: MemSplitNode.java:19
com.cliffc.aa.type.Type.oob
Type oob()
Definition: Type.java:635
com.cliffc.aa.node.Node.xval
Type xval()
Definition: Node.java:460
com.cliffc.aa.node.StoreNode.ideal_mono
Node ideal_mono()
Definition: StoreNode.java:75
com.cliffc.aa.node.StoreNode.rez
Node rez()
Definition: StoreNode.java:32
com.cliffc.aa.type.TypeFld.Access
Definition: TypeFld.java:109
com.cliffc.aa.node.Node.tvar
TV2 tvar()
Definition: Node.java:96
com.cliffc.aa.node.StoreNode.find
int find(TypeStruct ts)
Definition: StoreNode.java:33
com.cliffc.aa.node.StoreNode.equals
boolean equals(Object o)
Definition: StoreNode.java:172
com.cliffc.aa.node.StoreNode.str
String str()
Definition: StoreNode.java:27
com
com.cliffc.aa.node.MemSplitNode.insert_split
static Node insert_split(Node tail1, BitsAlias head1_escs, Node head1, Node tail2, Node head2)
Definition: MemSplitNode.java:142
com.cliffc.aa.Env
Definition: Env.java:12
com.cliffc.aa.type
Definition: Bits.java:1
com.cliffc.aa.node.StoreNode.mem
Node mem()
Definition: StoreNode.java:30
com.cliffc.aa.type.TypeMemPtr
Definition: TypeMemPtr.java:14
com.cliffc.aa.node.StoreNode.all_live
TypeMem all_live()
Definition: StoreNode.java:131
com.cliffc.aa.Parse
an implementation of language AA
Definition: Parse.java:68
com.cliffc.aa.GVNGCM.Mode
Definition: GVNGCM.java:14
com.cliffc.aa.node.Node.ErrMsg.field
static ErrMsg field(Parse loc, String msg, String fld, boolean closure, TypeObj to)
Definition: Node.java:929