aa
TV2.java
Go to the documentation of this file.
1 package com.cliffc.aa.tvar;
2 
3 import com.cliffc.aa.Env;
5 import com.cliffc.aa.node.Node;
6 import com.cliffc.aa.node.FreshNode;
7 import com.cliffc.aa.type.*;
8 import com.cliffc.aa.util.*;
9 import org.jetbrains.annotations.NotNull;
10 
11 import java.util.*;
12 
13 import static com.cliffc.aa.AA.unimpl;
14 
15 // Type Variable. TVars unify (ala Tarjan Union-Find), and can have structure
16 // (such as "{ A -> B }"). TVars are tied to a TNode to enforce Type structure
17 // on Types. TVars with no structure either refer to a plain Node, or get
18 // unioned into another TVar. TVars with structure have to match structure to
19 // be unified, but then can be recursively unified.
20 
21 // See HM.java for the prototype this is based from.
22 
23 public class TV2 {
24  // Unique ID
25  private static int UID=1;
26  public final int _uid;
27  // - "Args", "Ret", "Fun", "Mem", "Obj", "If". A structural tag for the H-M
28  // "type", these have to be equal during unification; their Keys in _args are
29  // unioned and equal keys are unified
30  // - "Base" - some constant Type, Base Types MEET when unified.
31  // - "Nil" - The XNIL/NIL Type. Always loses all unifications.
32  // - "Fresh": A one-off indirection to another TV2 which needs to be fresh-
33  // unified instead of normal-unification of this TV2. The freshable TV2 is
34  // under the solo key "Fresh".
35  // - "Dead": a dead Node or a Type.ANY ConNode, and a dead TV2. Unifies with
36  // everything, wins all unifications, and has no structure.
37  // - "Free": Nothing points to it, can be re-used.
38  private String _name;
39  // Set of structural H-M parts. Indexed by dense integer for fixed-size (ala
40  // Args,Ret,Fun), indexed by sparse integer alias for TMem, indexed by String
41  // for Obj field names. Can be null if empty.
43 
44  // U-F algo. Only set when unified, monotonic null->unification_target.
45  // Can change again to shorten unification changes.
46  private TV2 _unified;
47 
48  // Base primitive types, not really tied to any Node. TypeInt, TypeFlt.
49  public Type _type;
50 
51  // Set of dependent CallEpiNodes, to be re-worklisted if the called function changes TV2.
52  public UQNodes _deps;
53 
54  // Debug only. Set of unioned Nodes. null for empty. Helpful to track where TV2s come from.
55  public UQNodes _ns; //
56  public String _alloc_site; // Creation site; used to track excessive creation.
57 
58  // Track allocation statistics
59  static private class ACnts { int _malloc, _free; }
60  static private final HashMap<String,ACnts> ALLOCS = new HashMap<>(); // Counts at alloc sites
61 
62  // Common constructor
63  private TV2(@NotNull String name, NonBlockingHashMap<Comparable,TV2> args, Type type, UQNodes ns, @NotNull String alloc_site) {
64  _uid = UID++;
65  _name = name;
66  _args = args;
67  _type = type;
68  _deps = null; // Lazy added
69  _ns = ns;
70  _alloc_site = alloc_site;
71  ACnts ac = ALLOCS.computeIfAbsent(alloc_site,e -> new ACnts());
72  ac._malloc++;
73  }
74 
75  // Accessors
76  public boolean is_unified() { return _unified!=null; }
77  public boolean isa(String s){ return !is_unified() && Util.eq(_name,s); }
78  public boolean is_leaf () { return !is_unified() && isa("Leaf" ); }
79  public boolean is_base () { return !is_unified() && isa("Base" ); }
80  public boolean is_nil () { return !is_unified() && isa("Nil" ); }
81  public boolean is_dead () { return !is_unified() && isa("Dead" ); }
82  public boolean is_free () { return !is_unified() && isa("Free" ); }
83  public boolean is_err () { return !is_unified() && isa("Err" ); }
84  public boolean is_tvar () { return !is_unified() && _args!=null; } // Excludes unified,base,dead,nil,free
85  public TV2 get_unified() { assert is_unified(); return _unified; }
86  public String name() { return _name; }
87 
88  // Get at a key, with U-F rollup
89  public TV2 get( Comparable key ) {
90  if( _args==null ) return null;
91  TV2 tv = _args.get(key);
92  if( tv==null ) return null;
93  TV2 tv2 = tv.find();
94  if( tv!=tv2 ) args_put(key,tv2);
95  return tv2;
96  }
97 
98  // When inserting a new key, propagate deps
99  public void args_put(Comparable key, TV2 tv) {
100  _args.put(key,tv); // Pick up a key->tv mapping
101  merge_deps(tv); // tv gets all deps that 'this' has
102  }
103 
104  // Unify-at a selected key
105  public boolean unify_at(Comparable key, TV2 tv2, boolean test ) {
106  if( is_dead() ) return unify(tv2,test);
107  assert is_tvar() && _args!=null && !tv2.is_unified();
108  TV2 old = get(key);
109  if( old!=null )
110  return old.unify(tv2,test);
111  if( test ) return true;
112  args_put(key,tv2);
113  Env.GVN.add_flow(_deps); // Re-CallEpi
114  return true;
115  }
116 
117  // Reset-at a selected key, when a non-HM-structure change happens
118  public void reset_at(Object o ) {
119  if( !is_dead() )
120  _args.remove(o);
121  }
122 
123  // --------------------------------------------
124  // Public factories
125  // Make a new TV2 attached to a Node.
126  public static TV2 make_leaf(Node n, @NotNull String alloc_site) {
127  UQNodes ns = n==null ? null : UQNodes.make(n);
128  return make_leaf_ns(ns,alloc_site);
129  }
130  public static TV2 make_leaf_ns(UQNodes ns, @NotNull String alloc_site) {
131  TV2 tv2 = new TV2("Leaf",null,null,ns,alloc_site);
132  assert tv2.is_leaf() && !tv2.is_base();
133  return tv2;
134  }
135  // Make a new primitive base TV2
136  public static TV2 make_base(Node n, Type type, @NotNull String alloc_site) {
137  if( type instanceof TypeObj ) { // Constant object?
138  return make("Obj",n,alloc_site); // Empty object constant
139  }
140  UQNodes ns = n==null ? null : UQNodes.make(n);
141  type = type.widen();
142  TV2 tv2 = new TV2("Base",null,type,ns,alloc_site);
143  assert tv2.is_base() && !tv2.is_leaf();
144  return tv2;
145  }
146  // Make a new primitive base TV2
147  public static TV2 make_err(Node n, String msg, @NotNull String alloc_site) {
148  UQNodes ns = n==null ? null : UQNodes.make(n);
149  TV2 tv2 = new TV2("Err",null,TypeStr.con(msg.intern()),ns,alloc_site);
150  assert tv2.is_err() && !tv2.is_leaf() && !tv2.is_base();
151  return tv2;
152  }
153  // Structural constructor, empty
154  public static TV2 make(@NotNull String name, Node n, @NotNull String alloc_site ) { return make(name,n,alloc_site,new NonBlockingHashMap<>()); }
155  // Structural constructor
156  public static TV2 make(@NotNull String name, Node n, @NotNull String alloc_site, NonBlockingHashMap<Comparable,TV2> args) {
157  assert args!=null; // Must have some structure
158  TV2 tv2 = new TV2(name,args,null,UQNodes.make(n),alloc_site);
159  assert !tv2.is_base() && !tv2.is_leaf();
160  return tv2;
161  }
162  // Structural constructor from array of TVs
163  public static TV2 make(@NotNull String name, Node n, @NotNull String alloc_site, Node... ntvs) {
164  assert ntvs!=null; // Must have some structure
166  for( int i=0; i<ntvs.length; i++ )
167  if( ntvs[i]!=null )
168  args.put(i,ntvs[i].tvar());
169  return make(name,n,alloc_site,args);
170  }
171  public static TV2 make(@NotNull String name, UQNodes ns, @NotNull String alloc_site ) {
172  TV2 tv2 = new TV2(name, new NonBlockingHashMap<>(),null,ns,alloc_site);
173  assert !tv2.is_base() && !tv2.is_leaf();
174  return tv2;
175  }
176 
177  // Structural constructor for new memory
178  public static TV2 make_mem(Node n, @NotNull String alloc_site) { return make("Mem",n,alloc_site,new NonBlockingHashMap<>()); }
179 
180  public static TV2 DEAD = new TV2("Dead",null,null,null,"static");
181  public static TV2 NIL = new TV2("Nil" ,null,null,null,"static");
182 
183  public static void reset_to_init0() {
184  NIL._deps = DEAD._deps = null;
185  NIL._ns = DEAD._ns = null;
186  }
187  public void reset(Node n) { if( _ns!=null ) _ns.remove(n._uid); }
188 
189  public void free() {
190  if( !is_unified() ) ALLOCS.get(_alloc_site)._free++;
191  _name = "Free";
192  _args = null;
193  _type = null;
194  _deps = null;
195  _ns = null;
196  }
197 
198  // --------------------------------------------
199  // Cyclic (structural) equals
200  public final boolean eq( TV2 that ) {
201  if( that==null ) return false;
202  assert VARS.isEmpty() && DUPS.isEmpty();
203  boolean eq = _eq(that);
204  VARS.clear(); DUPS.clear();
205  return eq;
206  }
207  private boolean _eq( TV2 that) {
208  if( this==that ) return true;
209  assert !is_unified() && !that.is_unified();
210  if( !Util.eq(_name,that._name) ) return false;
211  if( is_base() ) return _type==that._type; // Base types are equal if base _types are equal
212  if( is_leaf() ) { // Leafs are equal if they always map the same
213  TV2 eq2 = VARS.computeIfAbsent(this,k -> that);
214  return that==eq2;
215  }
216 
217  if( _args.size() != that._args.size() ) return false;
218  // Cyclic check
219  long luid = ((long)_uid<<32)|that._uid; // Make a unique id for the pair
220  if( DUPS.get(luid)!=null ) return true; // Cyclic, wrapped. Something else determines eq/ne
221  DUPS.put(luid,this); // Mark for cycle
222 
223  // Structural recursion
224  for( Comparable key : _args.keySet() )
225  if( !get(key)._eq(that.get(key)) )
226  return false;
227  return true;
228  }
229 
230  // True if args are equal
231  public boolean eq(Node[] args) {
232  for( int i=0; i<args.length; i++ )
233  if( args[i]!=null && args[i].tvar()!=get(i) )
234  return false;
235  return true;
236  }
237 
238  // --------------------------------------------
239  // Classic Tarjan U-F with rollup
240  public TV2 find() {
241  if( !is_unified() ) return this;
242  TV2 top = get_unified();
243  if( !top.is_unified() ) return top;
244  // Find U-F top
245  int cnt=0;
246  while( top.is_unified() && cnt++<100 ) top = top.get_unified();
247  assert cnt<100; // Infinite roll-up loop
248  TV2 v = this; // Rerun, rolling up to top
249  while( v != top ) v = v._union(top);
250  return top;
251  }
252 
253  // U-F union; 'this' becomes 'that'. If 'this' was used in an CallEpi/Apply,
254  // re-check the CallEpi. Always returns true.
255  public boolean union(TV2 that) {
256  if( this==that ) return true;
257  assert !is_unified() && !is_dead();
258  // Worklist: put updates on the worklist for revisiting
259  Env.GVN.add_flow(_deps); // Re-CallEpi
260  // TODO: REMOVE THIS BACKDOORS HACK
261  if( _ns!=null && that._ns!=null && _ns.size()==1 ) {
262  Node val=null; for( Node xval : _ns.values() ) { val=xval; break; }
263  if( val instanceof FreshNode && that._ns.containsKey(((FreshNode)val).in(1)._uid) )
264  Env.GVN.add_reduce(val);
265  }
266  _union(that);
267  ALLOCS.get(_alloc_site)._free++;
268  return true;
269  }
270  private TV2 _union(TV2 that) {
271  TV2 old = _unified;
272  _unified=that;
273  assert is_unified();
274  merge_deps(that); // Merge update lists, for future unions
275  merge_ns (that); // Merge Node list, for easier debugging
276  _deps = null;
277  _ns = null;
278  return old;
279  }
280 
281  // --------------------------------------------
282  // Used in the recursive unification process. During unify detects cycles,
283  // to allow cyclic unification.
285 
286  // Structural unification. Both 'this' and that' are the same afterwards.
287  // Returns True if progress.
288  public boolean unify(TV2 that, boolean test) {
289  //assert !this.is_unified() && !that.is_unified();
290  //if( this==that ) return false;
291  //assert DUPS.isEmpty();
292  //boolean progress = _unify(that,test);
293  //DUPS.clear();
294  //return progress;
295  throw unimpl();
296  }
297 
298  // Classic structural unification, no "fresh". Unifies 'this' into 'that'.
299  // Both 'this' and 'that' are the same afterwards. Returns true if progress.
300  private boolean _unify(TV2 that, boolean test) {
301  assert !is_unified() && !that.is_unified();
302  if( this==that ) return false;
303 
304  // Check for simple, non-recursive, unification.
305  // NIL always loses and makes no progress (no structure implications)
306  if( this.is_nil () ) return false;
307  if( that.is_nil () ) return false;
308  // All remaining paths make progress and return true.
309  if( test ) return true;
310  // Dead wins all
311  if( this.is_dead() ) return that.union(this);
312  if( that.is_dead() ) return this.union(that);
313  // two errs union in either order, so keep lower uid (actually should merge error strings)
314  if( is_err() && that.is_err() && _uid<that._uid ) return that.union(this);
315  if( is_err() ) return that.union(this);
316  if( that.is_err() ) return union(that);
317  // Two leafs union in either order, so keep lower uid
318  if( this.is_leaf() && that.is_leaf() && _uid < that._uid ) return that.union(this);
319  if( this.is_leaf() ) return this.union(that);
320  if( that.is_leaf() ) return that.union(this);
321  // Bases unify constants also
322  if( this.is_base() && that.is_base() ) return unify_base(that);
323 
324  // Cycle check.
325  long luid = ((long)_uid<<32)|that._uid; // Make a unique id for the pair
326  TV2 rez = DUPS.get(luid);
327  if( rez!=null ) return false; // Been there, done that
328  DUPS.put(luid,that); // Close cycles
329 
330  // Errors
331  if( !Util.eq(_name,that._name) )
332  return union_err(that,"Cannot unify "+this+" and "+that);
333  assert _args!=that._args; // Efficiency hack elsewhere if this is true here
334 
335 
336  // Structural recursion unification, this into that.
337  for( Comparable key : _args.keySet() ) {
338  TV2 vthis = get(key); assert vthis!=null;
339  TV2 vthat = that.get(key);
340  if( vthat==null ) that.args_put(key,vthis);
341  else { vthis._unify(vthat,test); that = that.find(); }
342  assert !that.is_unified();
343  }
344 
345  // TODO: Check for being equal, cyclic-ly, and return a prior if possible.
346  return find().union(that);
347  }
348  private boolean union_err(TV2 that, String msg) {
349  union(that);
350  return that.union(make_err(null,msg,"TV2.unify_err"));
351  }
352 
353  private boolean unify_base(TV2 that) {
354  that._type = _type.meet(that._type);
355  return union(that);
356  }
357  private boolean fresh_base(TV2 that, boolean test) {
358  Type con = _type.meet(that._type);
359  if( con==that._type ) return false; // No progress
360  if( !test ) that._type = con; // Yes progress, but no update if testing
361  return true;
362  }
363 
364  // Used in the recursive unification process. During fresh_unify tracks the
365  // mapping from LHS TV2s to RHS TVs.
366  private static final HashMap<TV2,TV2> VARS = new HashMap<>();
367 
368  // Make a (lazy) fresh copy of 'this' and unify it with 'that'. This is
369  // the same as calling 'fresh' then 'unify', without the clone of 'this'.
370  // The TV2[] is used when making the 'fresh' copy for the occurs_check.
371 
372  // Returns progress.
373  // If test, we are testing only and make no changes.
374  public boolean fresh_unify(TV2 that, TV2[] vs, boolean test) {
375  //assert VARS.isEmpty() && DUPS.isEmpty();
376  //boolean progress = _fresh_unify(that,vs,test);
377  //VARS.clear(); DUPS.clear();
378  //return progress;
379  throw unimpl();
380  }
381 
382  // Apply 'this' structure on 'that'; no modifications to 'this'. VARS maps
383  // from the cloned LHS to the RHS replacement.
384  private boolean _fresh_unify(TV2 that, TV2[] vs, boolean test) {
385  assert !is_unified() && !that.is_unified();
386 
387  // Several trivial cases that do not really do any work
388  if( this==that ) return false;
389  if( that.is_dead() ) return false;
390  if( this.is_dead() ) return that.union(this); // Kill 'that', same as LHS
391  if( this.is_nil() || that.is_nil() ) return false;
392 
393  // Check for closing cycles
394  TV2 prior = VARS.get(this);
395  if( prior!=null ) // Been there, done that? Return prior mapping
396  return prior.find()._unify(that, test);
397  if( cycle_equals(that) ) return vput(that,false);
398 
399  if( that.is_err() ) return vput(that,false); // That is an error, ignore 'this' and no progress
400  if( this.is_err() ) return vput(that,_unify(that,test));
401 
402  // Famous 'occurs-check', switch to normal unify
403  if( occurs_in( vs ) ) return vput(that,_unify(that,test));
404  // Either side is a Leaf, unify to the other (perhaps with a fresh copy)
405  if( this.is_leaf() ) return vput(that,false); // Lazy map LHS tvar to RHS
406  if( that.is_leaf() ) // RHS is a leaf tvar; union with a copy of LHS
407  return test || vput(that,that.union(repl(vs)));
408  // Bases MEET cons in RHS
409  if( is_base() && that.is_base() ) return vput(that,fresh_base(that,test));
410 
411  // Should be structurally equal now
412  if( !Util.eq(_name,that._name) )
413  throw com.cliffc.aa.AA.unimpl(); // unification error
414 
415  // Structural recursion unification, lazy on LHS
416  boolean progress = vput(that,false); // Early set, to stop cycles
417  for( Comparable key : _args.keySet() ) {
418  TV2 lhs = get(key); assert lhs!=null;
419  TV2 rhs = that.get(key);
420  if( rhs==null ) { // No RHS to unify against
421  if( !test ) { // RHS is a fresh copy of the LHS
422  that.args_put(key,lhs.repl(vs));
423  Env.GVN.add_flow(that._deps); // Re-CallEpi
424  }
425  progress = true;
426  } else {
427  progress |= lhs._fresh_unify(rhs,vs,test);
428  }
429  if( progress && test ) return true;
430  }
431  return progress;
432  }
433 
434  private boolean vput(TV2 that, boolean progress) { VARS.put(this,that); return progress; }
435  private TV2 vput(TV2 that) { VARS.put(this,that); return that; }
436 
437  // Replicate LHS, including structure and cycles, replacing leafs as they appear
438  private TV2 repl(TV2[] vs) {
439  assert !is_unified(); // Already chased these down
440  if( is_dead() ) return this; // Dead always unifies and wins
441  TV2 t = VARS.get(this); // Prior answer?
442  if( t!=null ) return t; // Been there, done that, return prior answer
443 
444  if( is_leaf() ) // If occurs_in lexical scope, keep same variable, else make a new leaf
445  return vput( occurs_in(vs) ? this : make_leaf_ns(null,"TV2_repl_leaf") );
446 
447  // Must replicate Base's, like a Mem or Obj.
448  if( is_base() ) return vput(make_base(null,_type,"TV2_repl_base"));
449  // A few no-arg variants (Nil, Fresh)
450  if( _args==null ) return vput(new TV2(_name,null,null,null,"TV2_repl_shallow"));
451 
452  // Structural recursion replicate
453  TV2 rez = new TV2(_name, new NonBlockingHashMap<>(),null,null,"TV2_repl_deep");
454  VARS.put(this,rez); // Insert in dups BEFORE structural recursion, to stop cycles
455  for( Comparable key : _args.keySet() )
456  rez.args_put(key,get(key).repl(vs));
457  return rez;
458  }
459 
460  // Do a repl, then rename all _ns lists.
461  public TV2 repl_rename(TV2[]vs, HashMap<Node,Node> map) {
462  assert VARS.isEmpty() && DUPS.isEmpty();
463  TV2 tv = repl(vs);
464  _rename(tv,map);
465  VARS.clear(); DUPS.clear();
466  return tv;
467  }
468  private void _rename(TV2 tv, HashMap<Node,Node> map) {
469  if( DUPS.get(_uid) != null ) return; // Been there, remapped this
470  DUPS.put(_uid,this); // Only remap once
471  if( this==tv ) return; // Using the same TVar
472  assert tv._ns==null && tv._deps==null;
473  tv._deps= _deps==null ? null : _deps.rename(map);
474  tv._ns = _ns ==null ? null : _ns .rename(map);
475  if( _args != null )
476  for( Comparable key : _args.keySet() )
477  _args.get(key)._rename(tv.get(key),map);
478  }
479 
480 
481  // --------------------------------------------
482 
483  // Used by Loads and Stores. Unify tv against all aliases at this field
484  // only. Aliases are either produced by the Parser (so very generic) or from
485  // forwards-flow from News and very specific. Ignore the generic ones until
486  // they refine. TODO: As aliases further refine, need to undo-redo prior
487  // unifies against larger/weaker aliases.
488  public boolean unify_alias_fld(Node ldst, BitsAlias aliases, String fld, TV2 tv, boolean test, String alloc_site) {
489  assert isa("Mem");
490  assert !tv.is_unified();
491  boolean progress=false;
492  for( int alias : aliases ) {
493  // TODO: Probably wrong, as no reason to believe that as soon as alias
494  // sharpens above AARY that it has hit its best sane value.
495  if( alias <= BitsAlias.AARY ) return false; // No unify on parser-specific values
496  TV2 tobj = get(alias);
497  if( tobj == null ) { // Missing, act as a fresh TV2 and lazily manifest
498  if( test ) return true; // Definitely will be progress
499  progress = true;
500  TV2 tvo = make("Obj",ldst,alloc_site);
501  args_put(alias,tvo);
502  tvo.args_put(fld,tv);
503  } else if( tobj.isa("Obj") ) {
504  progress = tobj.unify_at(fld,tv.find(),test);
505  } else if( tobj.is_dead() || tobj.isa("Err") ) {
506  tobj.unify(tv.find(),test);
507  } else
508  throw com.cliffc.aa.AA.unimpl();
509  if( progress && test ) return progress; // Shortcut
510  }
511  return progress;
512  }
513 
514  // Unify the two memories only at the given aliases
515  public boolean unify_alias(BitsAlias aliases, TV2 mem, boolean test) {
516  if( this==mem ) return false; // Already unified, no progress
517  assert (isa("Mem") || is_dead()) && mem.isa("Mem");
518  boolean progress = false;
519  TV2 tobj=null; // For asserts
520  for( int alias : aliases ) {
521  TV2 tv = mem.get(alias); // Get prior mem idea of this alias
522  if( tv==null ) continue; // No idea (yet) from prior mem, nothing to unify
523  if( tobj==null ) tobj=tv; // All objects in this set of aliases are already unified
524  else assert tobj==tv;
525  progress |= unify_at(alias,tv,test); // Overwrite the default for alias
526  if( progress && test ) return true;
527  }
528  return progress;
529  }
530 
531  // --------------------------------------------
532  // Find instances of 'tv' inside of 'this' via structural recursion. Walk
533  // the matching Type at the same time. Report the first one found, and
534  // assert all the others have the same Type.
535  public Type find_tvar(Type t, TV2 tv) {
536  assert DUPS.isEmpty();
537  Type rez = _find_tvar(t,tv,Type.ALL);
538  DUPS.clear();
539  return rez;
540  }
541  private Type _find_tvar(Type t, TV2 tv, Type rez) {
542  if( tv.is_dead() ) return rez;
543  if( t==Type.ALL ) return rez; // Join against 'ALL' never changes anything
544  if( tv==this ) {
545  rez = rez.join(t);
546  return rez;
547  }
548  switch(_name) {
549  case "Mem":
550  if( t ==Type.ANY ) return rez; // No substructure in type
551  TypeMem tmem = (TypeMem)t;
552  for( Comparable key : _args.keySet() ) {
553  TypeObj to = tmem.at((Integer) key);
554  TV2 obj = get(key);
555  if( obj!=null )
556  rez = obj._find_tvar(to,tv,rez);
557  }
558  return rez;
559  case "Obj":
560  if( t==TypeObj.UNUSED || t==TypeObj.ISUSED )
561  return rez; // No substructure in type
562  if( t instanceof TypeStr || t instanceof TypeAry )
563  return rez; // TODO: Handle These
564  TypeStruct ts = (TypeStruct)t; //
565  for( Comparable key : _args.keySet() ) {
566  //int idx = ts.find((String)key);
567  //if( idx!= -1 ) // If field exists
568  // rez = get(key)._find_tvar(ts.at(idx),tv,rez);
569  throw unimpl();
570  }
571  return rez;
572  case "Fun":
573  if( t.is_forward_ref() ) return rez;
574  if( !(t instanceof TypeFunPtr) ) return rez;
575  // TypeFunPtrs carry only a set of FIDXS & a DISPLAY.
576  // Hence no other Type is available here for lifting.
577  return rez;
578  case "Ret":
579  TypeTuple tt = (TypeTuple)t;
580  for( int i=0; i<tt.len(); i++ )
581  rez = get(i)._find_tvar(tt.at(i),tv,rez);
582  return rez;
583  case "Ptr":
584  if( !(t instanceof TypeMemPtr) ) return rez;
585  return get(0)._find_tvar(((TypeMemPtr)t)._obj,tv,rez);
586  case "Base":
587  case "Dead":
588  case "Err":
589  case "Leaf":
590  case "Nil":
591  return rez; // No substructure in TV2 and not equal already
592 
593  default: throw com.cliffc.aa.AA.unimpl();
594  }
595  }
596 
597  // --------------------------------------------
598  private static final VBitSet ODUPS = new VBitSet();
599  boolean occurs_in(TV2[] vs) {
600  if( vs==null ) return false;
601  assert ODUPS.isEmpty();
602  boolean found = _occurs_in(vs);
603  ODUPS.clear();
604  return found;
605  }
606 
607  // Does 'this' type occur in any scope, mid-definition (as a forward-ref).
608  // If not, then return false (and typically make a fresh copy).
609  // If it does, then 'this' reference is a recursive self-reference
610  // and needs to keep the self-type instead of making fresh.
611  boolean _occurs_in(TV2[] vs) {
612  // Can NOT modify 'vs' for U-F, because blows FreshNode hash.
613  for( TV2 v : vs )
614  if( _occurs_in_type(v.find()) )
615  return true;
616  return false;
617  }
618 
619  boolean _occurs_in_type(TV2 x) {
620  assert !is_unified() && !x.is_unified();
621  if( x==this ) return true;
622  if( ODUPS.tset(x._uid) ) return false; // Been there, done that
623  if( !x.is_leaf() && x._args!=null )
624  for( Comparable key : x._args.keySet() )
625  if( _occurs_in_type(x.get(key)) )
626  return true;
627  return false;
628  }
629 
630  // Get TV2 from array, with U-F rollup
631  public static TV2 get(TV2[] vs, int i) {
632  TV2 tv = vs[i].find();
633  return vs[i]==tv ? tv : (vs[i]=tv); // U-F rollup
634  }
635 
636 
637  // --------------------------------------------
638  // Test for structural equivalence, including cycles
639  static private final HashMap<TV2,TV2> CDUPS = new HashMap<>();
640  boolean cycle_equals(TV2 that) {
641  assert CDUPS.isEmpty();
642  boolean rez = _cycle_equals(that);
643  CDUPS.clear();
644  return rez;
645  }
646  boolean _cycle_equals(TV2 that) {
647  assert !is_unified() && !that.is_unified();
648  if( this==that ) return true;
649  if( is_base() && that.is_base() )
650  return _type==that._type; // Base-cases have to be completely identical
651  if( !Util.eq(_name,that._name) ) return false; // Wrong type-var names
652  if( is_leaf() || that.is_leaf() ) return false; // Unequal leaves are unequal
653  if( _args==that._args && !is_leaf() ) return true; // Both null is OK
654  if( _args.size() != that._args.size() ) return false; // Mismatched sizes
655  // Cycles stall the equal/unequal decision until we see a difference.
656  TV2 tc = CDUPS.get(this);
657  if( tc!=null )
658  return tc==that; // Cycle check; true if both cycling the same
659  CDUPS.put(this,that);
660  for( Comparable key : _args.keySet() ) {
661  TV2 lhs = get(key); assert lhs!=null;
662  TV2 rhs = that.get(key);
663  if( rhs==null || !lhs._cycle_equals(rhs) ) return false;
664  }
665  return true;
666  }
667 
668  // --------------------------------------------
669  // This is a TV2 function that is the target of 'fresh', i.e., this function
670  // might be fresh-unified with some other function. Push the application
671  // down the function parts; if any changes the fresh-application may make
672  // progress.
673  static final VBitSet DEPS_VISIT = new VBitSet();
674  public TV2 push_dep(CallEpiNode dep) {
675  assert DEPS_VISIT.isEmpty();
676  _push_update(dep);
677  DEPS_VISIT.clear();
678  return this;
679  }
680  private void _push_update(CallEpiNode dep) {
681  assert !is_unified();
682  if( DEPS_VISIT.tset(_uid) ) return;
683  if( _deps!=null && _deps.get(dep._uid)!=null ) return; // Already here and in all children
684  if( isa("Dead") ) return;
685  _deps = _deps==null ? UQNodes.make(dep) : _deps.add(dep);
686  if( _args!=null )
687  for( Comparable key : _args.keySet() ) // Structural recursion on a complex TV2
688  get(key)._push_update(dep);
689  }
690 
691  // Merge Dependent CallEpiNode lists, 'this' into 'that'. Required to
692  // trigger CEPI.unify_lift when types change structurally.
693  private void merge_deps( TV2 that ) { if( !that.isa("Dead") ) that._deps = that._deps==null ? _deps : that._deps.addAll(_deps); }
694  // Merge Node lists, 'this' into 'that', for easier debugging.
695  // Lazily remove dead nodes on the fly.
696  private void merge_ns ( TV2 that ) { if( !that.isa("Dead") ) that._ns = that._ns ==null ? _ns : that._ns .addAll(_ns ); }
697 
698 
699  // --------------------------------------------
700  // Pretty print
701  @Override public final String toString() {
703  VBitSet bs = new VBitSet();
704  find_dups(bs,dups,0);
705  return str(new SB(),bs.clr(),dups,true,0,0).toString();
706  }
707  public final String str(int d) {
709  VBitSet bs = new VBitSet();
710  find_dups(bs,dups,0);
711  return str(new SB(),bs.clr(),dups,true,0,d).toString();
712  }
713 
714  boolean is_prim() {
715  return isa("Obj") && _args!=null && _args.containsKey("!");
716  }
717 
718  // These TV2 types get large, with complex sharing patterns.
719  // Need to find the sharing to pretty-print the shared parts.
720  public final int find_dups(VBitSet bs, NonBlockingHashMapLong<String> dups, int scnt) {
721  if( bs.tset(_uid) ) {
722  if( is_dead() || is_nil() ) return scnt;
723  if( dups.containsKey(_uid) ) return scnt; // Already has a dup name
724  dups.put(_uid,new String(new char[]{(char)('A'+scnt)}));
725  return scnt+1;
726  }
727  if( is_unified() )
728  return get_unified().find_dups(bs,dups,scnt);
729  if( _args!=null )
730  for( TV2 tv : _args.values() )
731  if( !is_prim() )
732  scnt = tv.find_dups(bs,dups,scnt);
733  return scnt;
734  }
735 
736  // Pretty print
737  @SuppressWarnings("unchecked")
738  public final SB str(SB sb, VBitSet bs, NonBlockingHashMapLong<String> dups, boolean debug, int d, int max) {
739  if( is_dead() ) return sb.p("Dead"); // Do not print NS
740  if( is_nil() ) return sb.p("Nil" ); // Do not print NS
741  if( is_err() ) return sb.p(_type.getstr());
742 
743  String stv = dups.get(_uid);
744  if( stv!=null ) {
745  sb.p('$').p(stv);
746  if( bs.tset(_uid) ) return sb;
747  sb.p(':');
748  }
749  // Explicit U-F chain
750  if( is_unified() ) {
751  if( debug ) sb.p("V").p(_uid).p(">>");
752  return _unified.str(sb,bs,dups,debug,d,max);
753  }
754 
755  (is_base() ? sb.p(_type) : sb.p(_name)).p(':');
756  // Print all unioned nodes
757  if( _ns!=null && _ns.size() != 0 ) { // Have any
758  for( Node tn : _ns.values() ) // For all unioned
759  if( !tn.is_dead() ) { // Dead lazily cleared out, do not bother to print
760  sb.p('N').p(tn._uid).p(':');
761  if( !debug ) break; // Debug, see them all; non-debug just the first
762  }
763  } else // No unioned nodes
764  sb.p("V").p(_uid); // So just the _uid
765  if( is_prim() ) return sb.p(":PRIMS");
766 
767  // Structural contents
768  if( _args != null ) {
769  final int min = Math.min(d+1,max);
770  switch(_name) {
771  case "Fun":
772  sb.p(":{ ");
773  if( d < max ) sb.nl().i(min);
774  TV2 args = _args.get("Args");
775  if( args==null ) sb.p("Args");
776  else args.str(sb,bs,dups,debug,d+1,max);
777  if( d < max ) sb.nl().i(min);
778  sb.p(" -> ");
779  if( d < max ) sb.nl().i(min);
780  TV2 ret = _args.get("Ret");
781  if( ret ==null ) sb.p("Ret" );
782  else ret .str(sb,bs,dups,debug,d+1,max);
783  if( d < max ) sb.nl().i(d);
784  sb.p(" }");
785  break;
786  default:
787  sb.p(":[ ");
788  Ary<Comparable> keys = new Ary<>(_args.keySet().toArray(new Comparable[_args.size()]));
789  keys.sort_update((x,y)-> {
790  if( x==y ) return 0;
791  if( x=="^" ) return -1;
792  if( y=="^" ) return -1;
793  return x.compareTo(y);
794  });
795  for( Comparable key : keys ) {
796  if( d < max ) sb.nl().i(min);
797  sb.p(key.toString()).p(':');
798  _args.get(key).str(sb,bs,dups,debug,d+1,max);
799  sb.p(' ');
800  }
801  if( d < max ) sb.nl().i(d);
802  sb.p("]");
803  }
804  }
805  return sb;
806  }
807 }
com.cliffc.aa.tvar.TV2._args
NonBlockingHashMap< Comparable, TV2 > _args
Definition: TV2.java:42
com.cliffc.aa.tvar.TV2.name
String name()
Definition: TV2.java:86
com.cliffc.aa.tvar.TV2.get_unified
TV2 get_unified()
Definition: TV2.java:85
com.cliffc.aa.tvar.TV2.is_err
boolean is_err()
Definition: TV2.java:83
com.cliffc.aa.tvar.TV2.unify_at
boolean unify_at(Comparable key, TV2 tv2, boolean test)
Definition: TV2.java:105
com.cliffc.aa.tvar.TV2.DEPS_VISIT
static final VBitSet DEPS_VISIT
Definition: TV2.java:673
com.cliffc.aa.tvar.TV2.unify
boolean unify(TV2 that, boolean test)
Definition: TV2.java:288
com.cliffc.aa.type.TypeFunPtr
Definition: TypeFunPtr.java:23
com.cliffc.aa.tvar.TV2._unify
boolean _unify(TV2 that, boolean test)
Definition: TV2.java:300
com.cliffc.aa.tvar.TV2.make_base
static TV2 make_base(Node n, Type type, @NotNull String alloc_site)
Definition: TV2.java:136
com.cliffc.aa.tvar.TV2._cycle_equals
boolean _cycle_equals(TV2 that)
Definition: TV2.java:646
com.cliffc.aa.util.NonBlockingHashMap
A lock-free alternate implementation of java.util.concurrent.ConcurrentHashMap with better scaling pr...
Definition: NonBlockingHashMap.java:75
com.cliffc.aa.tvar.TV2.ALLOCS
static final HashMap< String, ACnts > ALLOCS
Definition: TV2.java:60
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.type.Type.join
Type join(Type t)
Definition: Type.java:619
com.cliffc
com.cliffc.aa.type.BitsAlias.AARY
static final int AARY
Definition: BitsAlias.java:25
com.cliffc.aa.type.Type.widen
Type widen()
Definition: Type.java:828
com.cliffc.aa.tvar.TV2._union
TV2 _union(TV2 that)
Definition: TV2.java:270
com.cliffc.aa.tvar.TV2.is_tvar
boolean is_tvar()
Definition: TV2.java:84
com.cliffc.aa.node.Node
Definition: Node.java:16
com.cliffc.aa.tvar.TV2.ODUPS
static final VBitSet ODUPS
Definition: TV2.java:598
com.cliffc.aa.util
Definition: AbstractEntry.java:1
com.cliffc.aa.tvar.TV2._name
String _name
Definition: TV2.java:38
com.cliffc.aa.tvar.TV2.args_put
void args_put(Comparable key, TV2 tv)
Definition: TV2.java:99
com.cliffc.aa.type.Type
an implementation of language AA
Definition: Type.java:94
com.cliffc.aa.tvar.TV2.ACnts._free
int _free
Definition: TV2.java:59
com.cliffc.aa.util.Ary
Definition: Ary.java:11
com.cliffc.aa.tvar.TV2._alloc_site
String _alloc_site
Definition: TV2.java:56
com.cliffc.aa.type.BitsAlias
Definition: BitsAlias.java:8
com.cliffc.aa.type.TypeTuple
Definition: TypeTuple.java:11
com.cliffc.aa.tvar.TV2._deps
UQNodes _deps
Definition: TV2.java:52
com.cliffc.aa.tvar.TV2.ACnts._malloc
int _malloc
Definition: TV2.java:59
com.cliffc.aa.tvar.TV2.vput
boolean vput(TV2 that, boolean progress)
Definition: TV2.java:434
com.cliffc.aa.tvar.TV2.reset
void reset(Node n)
Definition: TV2.java:187
com.cliffc.aa.tvar.UQNodes.addAll
UQNodes addAll(UQNodes uq)
Definition: UQNodes.java:47
com.cliffc.aa.tvar.TV2._ns
UQNodes _ns
Definition: TV2.java:55
com.cliffc.aa.tvar.TV2.union_err
boolean union_err(TV2 that, String msg)
Definition: TV2.java:348
com.cliffc.aa.util.VBitSet.clr
VBitSet clr()
Definition: VBitSet.java:9
com.cliffc.aa.type.Type.ANY
static final Type ANY
Definition: Type.java:325
com.cliffc.aa.util.NonBlockingHashMapLong.size
int size()
Returns the number of key-value mappings in this map.
Definition: NonBlockingHashMapLong.java:255
com.cliffc.aa.tvar.TV2.DUPS
static final NonBlockingHashMapLong< TV2 > DUPS
Definition: TV2.java:284
com.cliffc.aa.tvar.TV2._eq
boolean _eq(TV2 that)
Definition: TV2.java:207
com.cliffc.aa.type.TypeAry
Definition: TypeAry.java:7
com.cliffc.aa.type.Type.meet
final Type meet(Type t)
Definition: Type.java:412
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.tvar.TV2.ACnts
Definition: TV2.java:59
com.cliffc.aa.tvar.TV2.make_leaf_ns
static TV2 make_leaf_ns(UQNodes ns, @NotNull String alloc_site)
Definition: TV2.java:130
com.cliffc.aa.tvar.TV2.push_dep
TV2 push_dep(CallEpiNode dep)
Definition: TV2.java:674
com.cliffc.aa.tvar.TV2.is_unified
boolean is_unified()
Definition: TV2.java:76
com.cliffc.aa.tvar.TV2._type
Type _type
Definition: TV2.java:49
com.cliffc.aa.tvar.TV2.DEAD
static TV2 DEAD
Definition: TV2.java:180
com.cliffc.aa.tvar.TV2.reset_to_init0
static void reset_to_init0()
Definition: TV2.java:183
com.cliffc.aa.tvar.TV2._occurs_in_type
boolean _occurs_in_type(TV2 x)
Definition: TV2.java:619
com.cliffc.aa.tvar.TV2._unified
TV2 _unified
Definition: TV2.java:46
com.cliffc.aa.type.Type.ALL
static final Type ALL
Definition: Type.java:324
com.cliffc.aa.tvar.TV2.make
static TV2 make(@NotNull String name, Node n, @NotNull String alloc_site)
Definition: TV2.java:154
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.util.VBitSet.tset
boolean tset(int idx)
Definition: VBitSet.java:7
com.cliffc.aa.tvar.TV2._rename
void _rename(TV2 tv, HashMap< Node, Node > map)
Definition: TV2.java:468
com.cliffc.aa.Env.GVN
static final GVNGCM GVN
Definition: Env.java:13
com.cliffc.aa.tvar.TV2.TV2
TV2(@NotNull String name, NonBlockingHashMap< Comparable, TV2 > args, Type type, UQNodes ns, @NotNull String alloc_site)
Definition: TV2.java:63
com.cliffc.aa.type.TypeObj
Definition: TypeObj.java:15
com.cliffc.aa.tvar.TV2.is_dead
boolean is_dead()
Definition: TV2.java:81
com.cliffc.aa.tvar.TV2.CDUPS
static final HashMap< TV2, TV2 > CDUPS
Definition: TV2.java:639
com.cliffc.aa.tvar.TV2.occurs_in
boolean occurs_in(TV2[] vs)
Definition: TV2.java:599
com.cliffc.aa.util.NonBlockingHashMapLong.get
final TypeV get(long key)
Returns the value to which the specified key is mapped, or.
Definition: NonBlockingHashMapLong.java:368
com.cliffc.aa.tvar.TV2.toString
final String toString()
Definition: TV2.java:701
com.cliffc.aa.tvar.TV2.UID
static int UID
Definition: TV2.java:25
com.cliffc.aa.tvar.TV2.make
static TV2 make(@NotNull String name, Node n, @NotNull String alloc_site, NonBlockingHashMap< Comparable, TV2 > args)
Definition: TV2.java:156
com.cliffc.aa.tvar.TV2.free
void free()
Definition: TV2.java:189
com.cliffc.aa.tvar.TV2.eq
final boolean eq(TV2 that)
Definition: TV2.java:200
com.cliffc.aa.tvar.TV2.unify_alias
boolean unify_alias(BitsAlias aliases, TV2 mem, boolean test)
Definition: TV2.java:515
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.type.TypeTuple.len
int len()
Definition: TypeTuple.java:183
com.cliffc.aa.tvar.TV2.make_mem
static TV2 make_mem(Node n, @NotNull String alloc_site)
Definition: TV2.java:178
com.cliffc.aa.tvar.TV2.cycle_equals
boolean cycle_equals(TV2 that)
Definition: TV2.java:640
com.cliffc.aa.tvar.TV2.merge_deps
void merge_deps(TV2 that)
Definition: TV2.java:693
com.cliffc.aa.tvar.TV2.is_prim
boolean is_prim()
Definition: TV2.java:714
com.cliffc.aa.type.TypeObj.ISUSED
static final TypeObj ISUSED
Definition: TypeObj.java:45
com.cliffc.aa.tvar.TV2.is_nil
boolean is_nil()
Definition: TV2.java:80
com.cliffc.aa.tvar.TV2.make_leaf
static TV2 make_leaf(Node n, @NotNull String alloc_site)
Definition: TV2.java:126
com.cliffc.aa.util.NonBlockingHashMap.put
TypeV put(TypeK key, TypeV val)
Maps the specified key to the specified value in the table.
Definition: NonBlockingHashMap.java:310
com.cliffc.aa.type.TypeStr.con
static TypeStr con(String con)
Definition: TypeStr.java:42
com.cliffc.aa.tvar.TV2._fresh_unify
boolean _fresh_unify(TV2 that, TV2[] vs, boolean test)
Definition: TV2.java:384
com.cliffc.aa.tvar.TV2.is_base
boolean is_base()
Definition: TV2.java:79
com.cliffc.aa.tvar.TV2.find_dups
final int find_dups(VBitSet bs, NonBlockingHashMapLong< String > dups, int scnt)
Definition: TV2.java:720
com.cliffc.aa.tvar.UQNodes.make
static UQNodes make(Node tn)
Definition: UQNodes.java:28
com.cliffc.aa.tvar.UQNodes.rename
UQNodes rename(HashMap< Node, Node > map)
Definition: UQNodes.java:70
com.cliffc.aa.type.TypeStr
Definition: TypeStr.java:14
com.cliffc.aa.node.FreshNode
Definition: FreshNode.java:11
com.cliffc.aa.tvar.TV2.find_tvar
Type find_tvar(Type t, TV2 tv)
Definition: TV2.java:535
com.cliffc.aa.tvar.TV2._occurs_in
boolean _occurs_in(TV2[] vs)
Definition: TV2.java:611
com.cliffc.aa.util.VBitSet
Definition: VBitSet.java:5
Comparable
com.cliffc.aa.tvar.TV2.unify_base
boolean unify_base(TV2 that)
Definition: TV2.java:353
NotNull
com.cliffc.aa.tvar.TV2.make
static TV2 make(@NotNull String name, Node n, @NotNull String alloc_site, Node... ntvs)
Definition: TV2.java:163
com.cliffc.aa.util.SB
Tight/tiny StringBuilder wrapper.
Definition: SB.java:8
com.cliffc.aa.tvar.UQNodes.add
UQNodes add(Node tn)
Definition: UQNodes.java:36
com.cliffc.aa.tvar.TV2.isa
boolean isa(String s)
Definition: TV2.java:77
com.cliffc.aa.tvar.TV2.str
final String str(int d)
Definition: TV2.java:707
com.cliffc.aa.AA
an implementation of language AA
Definition: AA.java:9
com.cliffc.aa.tvar.TV2.eq
boolean eq(Node[] args)
Definition: TV2.java:231
com.cliffc.aa.tvar.TV2.NIL
static TV2 NIL
Definition: TV2.java:181
com.cliffc.aa.tvar.TV2.get
TV2 get(Comparable key)
Definition: TV2.java:89
com.cliffc.aa
Definition: AA.java:1
com.cliffc.aa.tvar.TV2._push_update
void _push_update(CallEpiNode dep)
Definition: TV2.java:680
com.cliffc.aa.util.NonBlockingHashMapLong.containsKey
boolean containsKey(long key)
Tests if the key in the table.
Definition: NonBlockingHashMapLong.java:258
com.cliffc.aa.tvar.UQNodes
Definition: UQNodes.java:8
com.cliffc.aa.tvar.TV2.make_err
static TV2 make_err(Node n, String msg, @NotNull String alloc_site)
Definition: TV2.java:147
com.cliffc.aa.util.Ary.sort_update
void sort_update(Comparator<? super E > c)
Sorts in-place.
Definition: Ary.java:187
com.cliffc.aa.type.TypeTuple.at
Type at(int idx)
Definition: TypeTuple.java:182
com.cliffc.aa.GVNGCM.add_reduce
public< N extends Node > N add_reduce(N n)
Definition: GVNGCM.java:49
com.cliffc.aa.tvar.TV2.reset_at
void reset_at(Object o)
Definition: TV2.java:118
com.cliffc.aa.tvar.TV2.repl_rename
TV2 repl_rename(TV2[]vs, HashMap< Node, Node > map)
Definition: TV2.java:461
com.cliffc.aa.node.CallEpiNode
Definition: CallEpiNode.java:24
com.cliffc.aa.tvar.TV2
Definition: TV2.java:23
com.cliffc.aa.util.NonBlockingHashMapLong
A lock-free alternate implementation of java.util.concurrent.ConcurrentHashMap with primitive long ke...
Definition: NonBlockingHashMapLong.java:91
com.cliffc.aa.tvar.TV2.make
static TV2 make(@NotNull String name, UQNodes ns, @NotNull String alloc_site)
Definition: TV2.java:171
com.cliffc.aa.tvar.TV2.fresh_base
boolean fresh_base(TV2 that, boolean test)
Definition: TV2.java:357
com.cliffc.aa.tvar.TV2.union
boolean union(TV2 that)
Definition: TV2.java:255
com.cliffc.aa.tvar.TV2.vput
TV2 vput(TV2 that)
Definition: TV2.java:435
com.cliffc.aa.util.NonBlockingHashMapLong.put
TypeV put(long key, TypeV val)
Maps the specified key to the specified value in the table.
Definition: NonBlockingHashMapLong.java:278
com.cliffc.aa.GVNGCM.add_flow
public< N extends Node > N add_flow(N n)
Definition: GVNGCM.java:50
com.cliffc.aa.tvar.TV2.fresh_unify
boolean fresh_unify(TV2 that, TV2[] vs, boolean test)
Definition: TV2.java:374
com.cliffc.aa.node.Node._uid
int _uid
Definition: Node.java:84
com.cliffc.aa.tvar.TV2.merge_ns
void merge_ns(TV2 that)
Definition: TV2.java:696
com
com.cliffc.aa.tvar.TV2.is_free
boolean is_free()
Definition: TV2.java:82
com.cliffc.aa.tvar.TV2._find_tvar
Type _find_tvar(Type t, TV2 tv, Type rez)
Definition: TV2.java:541
com.cliffc.aa.type.TypeMem.at
TypeObj at(int alias)
Definition: TypeMem.java:135
com.cliffc.aa.Env
Definition: Env.java:12
com.cliffc.aa.util.NonBlockingHashMapLong.values
Collection< TypeV > values()
Returns a Collection view of the values contained in this map.
Definition: NonBlockingHashMapLong.java:1118
com.cliffc.aa.type.Type.getstr
String getstr()
Definition: Type.java:806
com.cliffc.aa.tvar.TV2.is_leaf
boolean is_leaf()
Definition: TV2.java:78
com.cliffc.aa.tvar.TV2._uid
final int _uid
Definition: TV2.java:26
com.cliffc.aa.type
Definition: Bits.java:1
com.cliffc.aa.tvar.TV2.find
TV2 find()
Definition: TV2.java:240
com.cliffc.aa.tvar.TV2.repl
TV2 repl(TV2[] vs)
Definition: TV2.java:438
com.cliffc.aa.type.TypeMemPtr
Definition: TypeMemPtr.java:14
com.cliffc.aa.util.NonBlockingHashMapLong.remove
TypeV remove(long key)
Removes the key (and its corresponding value) from this map.
Definition: NonBlockingHashMapLong.java:292
com.cliffc.aa.tvar.TV2.VARS
static final HashMap< TV2, TV2 > VARS
Definition: TV2.java:366
com.cliffc.aa.type.Type.is_forward_ref
boolean is_forward_ref()
Definition: Type.java:799
com.cliffc.aa.node
Definition: AssertNode.java:1