aa
GVNGCM.java
Go to the documentation of this file.
1 package com.cliffc.aa;
2 
3 import com.cliffc.aa.node.*;
4 import com.cliffc.aa.tvar.UQNodes;
5 import com.cliffc.aa.type.*;
6 import com.cliffc.aa.util.Ary;
7 import com.cliffc.aa.util.VBitSet;
8 
9 import java.util.BitSet;
10 
11 // Global Value Numbering, Global Code Motion
12 public class GVNGCM {
13 
14  public enum Mode {
15  Parse (false), // Parsing
16  PesiNoCG(false), // Lifting, unknown Call Graph
17  Opto (true ), // Falling, Call Graph discovery, no more code
18  PesiCG (true ); // Lifting, known Call Graph
19  public final boolean _CG; // True if full CG is known or being discovered. Only for whole programs during or after Opto.
20  Mode(boolean CG) { _CG=CG; }
21  }
23 
24  // Iterative worklists.
25  private final Work _work_dead = new Work("dead" , false) { @Override public Node apply(Node n) { return n._keep==0 && n._uses._len == 0 ? n.kill() : null; } };
26  private final Work _work_reduce = new Work("reduce", true ) { @Override public Node apply(Node n) { return n.do_reduce(); } };
27  private final Work _work_flow = new Work("flow" , false) { @Override public Node apply(Node n) { return n.do_flow (); } };
28  private final Work _work_mono = new Work("mono" , true ) { @Override public Node apply(Node n) { return n.do_mono (); } };
29  private final Work _work_grow = new Work("grow" , true ) { @Override public Node apply(Node n) { return n.do_grow (); } };
30  private final Work _work_inline = new Work("inline", false) { @Override public Node apply(Node n) { return ((FunNode)n).ideal_inline(false); } };
31  public final Work _work_dom = new Work("dom" , false) { @Override public Node apply(Node n) { return n.do_mono (); } };
32  @SuppressWarnings("unchecked")
34  @SuppressWarnings("unchecked")
36  @SuppressWarnings("unchecked")
38  static private boolean HAS_WORK;
39  public boolean on_dead ( Node n ) { return _work_dead .on(n); }
40  public boolean on_flow ( Node n ) { return _work_flow .on(n); }
41  public boolean on_reduce( Node n ) { return _work_reduce.on(n); }
42 
43  static public <N extends Node> N add_work( Work work, N n ) {
44  if( n==null || n.is_dead() ) return n;
45  if( !HAS_WORK ) HAS_WORK = true; // Filtered set
46  return work.add(n);
47  }
48  public void add_dead ( Node n ) { add_work(_work_dead, n); }
49  public <N extends Node> N add_reduce( N n ) { return add_work(_work_reduce,n); }
50  public <N extends Node> N add_flow ( N n ) { return add_work(_work_flow ,n); }
51  public <N extends Node> N add_mono ( N n ) { return add_work(_work_mono ,n); }
52  public void add_grow ( Node n ) { add_work(_work_grow ,n); }
53  public void add_inline( FunNode n ) { add_work(_work_inline, n); }
54  public void add_flow_defs ( Node n ) { add_work_defs(_work_flow ,n); }
55  public void add_flow_uses ( Node n ) { add_work_uses(_work_flow ,n); }
56  public void add_flow( UQNodes deps ) { if( deps != null ) for( Node dep : deps.values() ) add_flow(dep); }
58  // n goes unused
59  public Node add_unuse( Node n ) {
60  if( n._uses._len==0 && n._keep==0 ) { add_dead(n); return n; } // might be dead
61  return add_reduce(add_flow(n));
62  }
63  static public void add_work_defs( Work work, Node n ) {
64  for( Node def : n._defs )
65  if( def != null && def != n )
66  add_work(work,def);
67  }
68  static public void add_work_uses( Work work, Node n ) {
69  for( Node use : n._uses )
70  if( use != n )
71  add_work(work,use);
72  }
73  public Node add_work_all( Node n ) {
74  if( n.is_dead() ) return n;
75  if( !HAS_WORK ) HAS_WORK = true; // Filtered set
76  for( Work work : _new_works ) work.add(n);
77  if( n instanceof FunNode )
79  return n;
80  }
81 
82  // Initial state after loading e.g. primitives.
83  void init0() {
84  for( Work work : _all_works ) assert work.isEmpty();
85  }
86  // Reset is called after a top-level exec exits (e.g. junits) with no parse
87  // state left alive. NOT called after a line in the REPL or a user-call to
88  // "eval" as user state carries on.
89  void reset_to_init0() {
90  for( Work work : _all_works ) work.clear();
91  _work_dom.clear();
93  ITER_CNT = ITER_CNT_NOOP = 0;
94  }
95 
96  // Record a Node, but do not optimize it for value and ideal calls, as it is
97  // mid-construction from the parser. Any function call with yet-to-be-parsed
98  // call sites, and any loop top with an unparsed backedge needs to use this.
99  public <N extends Node> N init( N n ) { return add_flow(add_reduce(n.keep(2))); }
100 
101  // Did a bulk not-monotonic update. Forcibly update the entire region at
102  // once; restores monotonicity over the whole region when done.
103  public void revalive(Node... ns) {
104  for( Node n : ns ) {
105  if( n == null ) continue;
106  Type t = n.value(_opt_mode);
107  if( t != n._val ) {
108  n._val = t;
109  add_flow_uses(n);
110  }
111  }
112  for( int i=ns.length-1; i>=0; i-- ) {
113  Node n = ns[i];
114  if( n==null ) continue;
115  TypeMem t = n.live(_opt_mode);
116  if( t != n._live ) {
117  n._live=t;
118  add_flow_defs(n);
119  }
120  }
121  }
122 
123  // Apply graph-rewrite rules on new nodes (those with no users and kept alive
124  // for the parser). Return a node registered with GVN that is possibly "more
125  // ideal" than what was before.
126  public Node xform( Node n ) {
127  assert n._uses._len==0 && n._keep==0; // New to GVN
129  assert !x.is_dead();
130  return add_flow(x); // No liveness (yet), since uses not known
131  }
132 
133  // Apply graph-rewrite rules, up to the ideal_reduce calls. Return a node
134  // that is possibly "more ideal" than what was before.
135  public Node xreduce( Node n ) {
136  assert n._uses._len==0 && n._keep==0; // New to GVN
137  n.do_flow(); // Compute _val (for finding constants)
138  Node x = n.do_reduce(); // Maybe find a more ideal Node
139  if( x==null ) x=n; // Ignore lack-of-progress
140  return add_flow(x); // No liveness (yet), since uses not known
141  }
142 
143 
144  // Top-level iter cleanout. Changes GVN modes & empties all queues &
145  // aggressively checks no-more-progress.
146  private static final VBitSet IDEAL_VISIT = new VBitSet();
147  public void iter(Mode opt_mode) {
148  _opt_mode = opt_mode;
149  boolean progress=true;
150  while( progress ) {
151  progress = false;
152  iter(null,_all_works);
153  // Only a very few nodes can make progress via dominance relations, and
154  // these can make progress "very far" in the graph. So instead of using
155  // a neighbors list, we bulk revisit them here.
156  for( int i=0; i<_work_dom.len(); i++ ) {
157  Node dom = _work_dom.at(i);
158  if( dom.is_dead() ) _work_dom.del(i--);
159  else progress |= _work_dom.apply(dom)!=null;
160  }
161  }
162  IDEAL_VISIT.clear();
163  // Expensive assert
164  assert !Env.START.more_ideal(IDEAL_VISIT);
165  }
166 
167  // Any time anything is on any worklist we can always conservatively iterate on it.
168  // Empties the worklist, attempting to do every possible thing.
169  // Returns 'x' or a replacement for 'x'.
170  static int ITER_CNT;
171  static int ITER_CNT_NOOP;
172  public Node iter(Node x, Work[] works) {
173  if( !HAS_WORK ) return x;
174  if( x!=null ) x.keep();
175  while( true ) {
176  Work W=null;
177  for( Work work : works )
178  if( !(W = work).isEmpty() )
179  break;
180  if( W.isEmpty() ) break; // All worklists empty
181  Node n = W.pop();
182  Node m = n.is_dead() ? null : W.apply(n);
183  if( m == null ) { // not-null is progress
184  ITER_CNT_NOOP++; // No progress
185  } else {
186  // VERY EXPENSIVE ASSERT
187  //assert W==_work_dead || Env.START.more_flow(true)==0; // Initial conditions are correct
188  ITER_CNT++; assert ITER_CNT < 35000; // Catch infinite ideal-loops
189  if( x==n ) x=m; // Keep track of the replacement for x, if any
190  }
191  }
192  HAS_WORK=false;
193  Node.roll_back_CNT(); // Can reclaim node numbers
194  if( x==null ) return null; // No special node to track
195  return x.unkeep();
196  }
197 
198  // Global Optimistic Constant Propagation. Passed in the final program state
199  // (including any return result, i/o & memory state). Returns the most-precise
200  // types possible, and replaces constants types with constants.
201  //
202  // Besides the obvious GCP algorithm (and the type-precision that results
203  // from the analysis), GCP does a few more things.
204  //
205  // GCP builds an explicit Call-Graph. Before GCP not all callers are known
206  // and this is approximated by being called by ALL_CTRL, a ConNode of Type
207  // CTRL, as a permanently available unknown caller. If the whole program is
208  // available to us then we can compute all callers conservatively and fairly
209  // precisely - we may have extra never-taken caller/callee edges, but no
210  // missing caller/callee edges. These edges are virtual (represented by
211  // ALL_CTRL) before GCP. Just before GCP we remove the ALL_CTRL path, and
212  // during GCP we add in physical CG edges as possible calls are discovered.
213  //
214  // GCP resolves all ambiguous (overloaded) calls, using the precise types
215  // first, and then inserting conversions using a greedy decision. If this is
216  // not sufficient to resolve all calls, the program is ambiguous and wrong.
217  public void gcp(Mode mode, ScopeNode rez ) {
218  _opt_mode = mode;
219  // Set all values to ALL and lives to DEAD, their most optimistic types.
220  VBitSet visit = new VBitSet();
221  Env.START.walk_initype(this,visit);
222  assert Env.START.more_flow(false)==0; // Initial conditions are correct
223  // Collect unresolved calls, and verify they get resolved.
224  Ary<CallNode> ambi_calls = new Ary<>(new CallNode[1],0);
225 
226  // Repeat, if we remove some ambiguous choices, and keep falling until the
227  // graph stabilizes without ambiguity.
228  while( !_work_flow.isEmpty() ) {
229  // Analysis phase.
230  // Work down list until all reachable nodes types quit falling
231  Node n;
232  while( (n=_work_flow.pop()) != null ) {
233  if( n.is_dead() ) continue; // Can be dead functions after removing ambiguous calls
234 
235  // Forwards flow
236  Type oval = n._val; // Old local type
237  Type nval = n.value(_opt_mode); // New type
238  if( oval != nval ) { // Progress
239  if( check_not_monotonic(n, oval, nval) ) continue; // Debugging hook
240  n._val = nval; // Record progress
241  for( Node use : n._uses ) // Classic forwards flow on change
242  add_flow(use).add_flow_use_extra(n);
243  n.add_flow_extra(oval);
244  if( n instanceof CallEpiNode ) check_and_wire((CallEpiNode)n);
245  for( Node use : n._uses )
246  if( use instanceof CallEpiNode ) check_and_wire((CallEpiNode)use);
247  // All liveness is skipped if may_be_con, since the possible constant
248  // has no inputs.
249  assert oval.may_be_con() || !nval.may_be_con(); // May_be_con is monotonic
250  if( oval.may_be_con() && !nval.may_be_con() )
251  add_flow_defs(n); // Now check liveness
252  }
253 
254  // Reverse flow
255  TypeMem oliv = n._live;
256  TypeMem nliv = n.live(_opt_mode);
257  if( oliv != nliv ) { // Liveness progress
258  if( check_not_monotonic(n, oliv, nliv) ) continue; // Debugging hook
259  n._live = nliv; // Record progress
260  n.add_flow_extra(nliv);
261  for( Node def : n._defs ) // Classic reverse flow on change
262  if( def!=null ) add_flow(def).add_flow_def_extra(n);
263  }
264  // See if we can resolve an unresolved
265  if( n instanceof CallNode && n._live != TypeMem.DEAD ) {
266  CallNode call = (CallNode)n;
267  if( call.ctl()._val == Type.CTRL && call._val instanceof TypeTuple ) { // Wait until the Call is reachable
268  // Track ambiguous calls: resolve after GCP gets stable, and if we
269  // can resolve we continue to let GCP fall.
270  BitsFun fidxs = CallNode.ttfp(call._val).fidxs();
271  if( fidxs.above_center() && fidxs.abit() == -1 && ambi_calls.find(call) == -1 )
272  ambi_calls.add(call);
273  }
274  }
275  // Very expensive assert
276  //assert Env.START.more_flow(false)==0; // Initial conditions are correct
277  }
278 
279  // Remove CallNode ambiguity after worklist runs dry. This makes a
280  // 'least_cost' choice on unresolved Calls, and lowers them in the
281  // lattice... allowing more GCP progress.
282  while( !ambi_calls.isEmpty() )
283  remove_ambi(ambi_calls.pop());
284  }
285 
286  assert Env.START.more_flow(false)==0; // Final conditions are correct
287  visit.clear();
288  Env.START.walk_opt(visit);
289  }
290 
291  private void remove_ambi( CallNode call ) {
292  TypeFunPtr tfp = CallNode.ttfpx(call._val);
293  FunPtrNode fptr = null;
294  BitsFun fidxs = tfp.fidxs();
295  if( !fidxs.above_center() ) return; // Resolved after all
296  if( fidxs!=BitsFun.ANY ) { // And have choices
297  // Pick least-cost among choices
298  fptr = call.least_cost(fidxs,call.fdx());
299  if( fptr==null ) { // Not resolving, program is in-error
300  call._not_resolved_by_gcp = true; // will drop fdx in lattice
301  add_flow(call);
302  return;
303  }
304  }
305  call.set_dsp(fptr.display());
306  call.set_fdx(fptr); // Set resolved edge
307  add_flow(call);
308  assert Env.START.more_flow(false)==0; // Post conditions are correct
309  }
310 
311  private void check_and_wire( CallEpiNode cepi ) {
312  if( !cepi.check_and_wire() ) return;
313  assert Env.START.more_flow(false)==0;
314  }
315 
316  // Debugging hook
317  private boolean check_not_monotonic( Node n, Type ot, Type nt) {
318  assert nt==nt.simple_ptr() || n instanceof ConTypeNode; // Only simple pointers in node types
319  if( ot.isa(nt) ) return false; // No bug
320  _work_flow.del(n); // Might be back on the lift
321  add_flow(n); // Setup for a re-run
322  System.out.println("Not monotonic");
323  return true; // Just single-step forward in debugging to re-run n.value
324  }
325 
326  // Walk all memory edges, and 'retype' them, probably DOWN (counter to
327  // 'iter'). Used when inlining, and the inlined body needs to acknowledge
328  // bypasses aliases. Used during code-clone, to lift the split alias parent
329  // up & out.
330  public static void retype_mem( BitSet aliases, Node mem, Node exit, boolean skip_calls ) {
331  Ary<Node> work = new Ary<>(new Node[1],0);
332  work.push(mem);
333  // Update all memory ops
334  while( !work.isEmpty() ) {
335  Node wrk = work.pop();
336  if( !wrk.is_mem() && wrk!=mem ) continue; // Not a memory Node?
337  Type twrk = wrk._val;
338  Type tmem0 = twrk instanceof TypeTuple ? ((TypeTuple)twrk).at(1) : twrk;
339  if( !(tmem0 instanceof TypeMem) ) continue; // Node does have have a memory type?
340  if( aliases!=null && !((TypeMem)tmem0).has_used(aliases) ) continue; // Not does not use the listed memory?
341  if( wrk instanceof CallNode ) { // Do the CEPI for a Call, skipping in-between
342  CallEpiNode cepi = ((CallNode)wrk).cepi();
343  if( cepi != null ) work.push(cepi);
344  }
345  Type tval = wrk.value(Env.GVN._opt_mode); // Recompute memory value
346  if( twrk == tval ) continue; // No change
347  wrk._val = tval; // Progress!!!
348  Env.GVN.add_flow_uses(wrk); // Forwards flow the update
349  if( wrk==exit ) continue; // Stop at end
350  if( skip_calls && wrk instanceof MProjNode && wrk.in(0) instanceof CallNode )
351  continue; // Skip the inside of calls
352  work.addAll(wrk._uses);
353  }
354  }
355 
356  public class Build<N extends Node> implements AutoCloseable {
357  Ary<Node> _tmps = new Ary<>(new Node[1],0);
358  public N _ret;
359  public Node xform( Node n ) {
360  Node x = n.do_reduce(); // Attempt to reduce
361  return init(x==null ? n : x);
362  }
363  public Node init( Node n ) {
364  assert _tmps._len<16; // Time for a BitSet
365  if( _tmps.find(n)!=-1 ) return n; // Already flowed & keeped
366  n.keep().do_flow(); // Update types, and future Parser uses, so always alive
367  return _tmps.push(n);
368  }
369  public Node add( Node n ) {
370  assert _tmps._len<16; // Time for a BitSet
371  if( _tmps.find(n)!=-1 ) return n; // Already flowed & keeped
372  return _tmps.push(n.keep());
373  }
374  @SuppressWarnings("unchecked")
375  public <M extends Node> M init2( M n ) { return (M)init(n); }
376  @Override public void close() {
377  for( Node tmp : _tmps )
378  add_unuse(tmp.unkeep()); // Needs proper liveness at least
379  }
380  }
381 }
com.cliffc.aa.GVNGCM.add_grow
void add_grow(Node n)
Definition: GVNGCM.java:52
com.cliffc.aa.GVNGCM.Build.close
void close()
Definition: GVNGCM.java:376
com.cliffc.aa.node.Node.roll_back_CNT
static void roll_back_CNT()
Definition: Node.java:222
com.cliffc.aa.GVNGCM.Build._tmps
Ary< Node > _tmps
Definition: GVNGCM.java:357
com.cliffc.aa.GVNGCM.add_unuse
Node add_unuse(Node n)
Definition: GVNGCM.java:59
com.cliffc.aa.type.TypeMem.DEAD
static final TypeMem DEAD
Definition: TypeMem.java:226
com.cliffc.aa.type.TypeFunPtr
Definition: TypeFunPtr.java:23
com.cliffc.aa.GVNGCM.ITER_CNT
static int ITER_CNT
Definition: GVNGCM.java:170
com.cliffc.aa.util.Ary.push
E push(E e)
Add element in amortized constant time.
Definition: Ary.java:58
com.cliffc.aa.util.Ary.isEmpty
boolean isEmpty()
Definition: Ary.java:20
com.cliffc.aa.type.Type.isa
boolean isa(Type t)
Definition: Type.java:623
com.cliffc.aa.node.Node.live
TypeMem live(GVNGCM.Mode opt_mode)
Definition: Node.java:478
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.node.Work
Definition: Work.java:8
com.cliffc.aa.GVNGCM._work_reduce
final Work _work_reduce
Definition: GVNGCM.java:26
com.cliffc.aa.GVNGCM.add_mono
public< N extends Node > N add_mono(N n)
Definition: GVNGCM.java:51
com.cliffc.aa.GVNGCM.Mode.PesiCG
PesiCG
Definition: GVNGCM.java:18
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.aa.GVNGCM.add_inline
void add_inline(FunNode n)
Definition: GVNGCM.java:53
com.cliffc
com.cliffc.aa.util.Ary.pop
E pop()
Definition: Ary.java:41
com.cliffc.aa.node.Work.del
void del(int i)
Definition: Work.java:28
com.cliffc.aa.node.ScopeNode
Definition: ScopeNode.java:17
com.cliffc.aa.util.Ary.addAll
Ary< E > addAll(Collection<? extends E > c)
Definition: Ary.java:151
com.cliffc.aa.node.Node
Definition: Node.java:16
com.cliffc.aa.GVNGCM._work_inline
final Work _work_inline
Definition: GVNGCM.java:30
com.cliffc.aa.util
Definition: AbstractEntry.java:1
com.cliffc.aa.node.Node.do_flow
Node do_flow()
Definition: Node.java:592
com.cliffc.aa.GVNGCM.Build.init
Node init(Node n)
Definition: GVNGCM.java:363
com.cliffc.aa.node.Work.on
boolean on(Node n)
Definition: Work.java:36
com.cliffc.aa.GVNGCM.add_work_all
Node add_work_all(Node n)
Definition: GVNGCM.java:73
com.cliffc.aa.tvar
Definition: TV2.java:1
com.cliffc.aa.node.Node.more_ideal
final boolean more_ideal(VBitSet bs)
Definition: Node.java:722
com.cliffc.aa.type.Type
an implementation of language AA
Definition: Type.java:94
com.cliffc.aa.GVNGCM.check_not_monotonic
boolean check_not_monotonic(Node n, Type ot, Type nt)
Definition: GVNGCM.java:317
com.cliffc.aa.util.Ary
Definition: Ary.java:11
com.cliffc.aa.GVNGCM.revalive
void revalive(Node... ns)
Definition: GVNGCM.java:103
com.cliffc.aa.type.TypeTuple
Definition: TypeTuple.java:11
com.cliffc.aa.node.Node.do_mono
Node do_mono()
Definition: Node.java:632
com.cliffc.aa.node.Node.keep
public< N extends Node > N keep()
Definition: Node.java:228
com.cliffc.aa.GVNGCM._work_grow
final Work _work_grow
Definition: GVNGCM.java:29
com.cliffc.aa.node.CallNode.ttfpx
static TypeFunPtr ttfpx(Type tcall)
Definition: CallNode.java:162
com.cliffc.aa.type.TypeFunPtr.fidxs
BitsFun fidxs()
Definition: TypeFunPtr.java:127
com.cliffc.aa.GVNGCM.Mode._CG
final boolean _CG
Definition: GVNGCM.java:19
com.cliffc.aa.node.Node._val
Type _val
Definition: Node.java:88
com.cliffc.aa.GVNGCM.check_and_wire
void check_and_wire(CallEpiNode cepi)
Definition: GVNGCM.java:311
com.cliffc.aa.GVNGCM._work_dead
final Work _work_dead
Definition: GVNGCM.java:25
com.cliffc.aa.node.FunPtrNode
Definition: FunPtrNode.java:40
com.cliffc.aa.GVNGCM.reset_to_init0
void reset_to_init0()
Definition: GVNGCM.java:89
com.cliffc.aa.node.CallEpiNode.check_and_wire
boolean check_and_wire()
Definition: CallEpiNode.java:179
com.cliffc.aa.GVNGCM.add_work_defs
static void add_work_defs(Work work, Node n)
Definition: GVNGCM.java:63
com.cliffc.aa.node.CallNode
Definition: CallNode.java:86
com.cliffc.aa.GVNGCM.on_reduce
boolean on_reduce(Node n)
Definition: GVNGCM.java:41
com.cliffc.aa.node.MProjNode
Definition: MProjNode.java:10
com.cliffc.aa.GVNGCM.add_work_uses
static void add_work_uses(Work work, Node n)
Definition: GVNGCM.java:68
com.cliffc.aa.Env.START
static StartNode START
Definition: Env.java:14
com.cliffc.aa.GVNGCM.Mode.PesiNoCG
PesiNoCG
Definition: GVNGCM.java:16
com.cliffc.aa.GVNGCM._work_flow
final Work _work_flow
Definition: GVNGCM.java:27
com.cliffc.aa.GVNGCM.add_work
static public< N extends Node > N add_work(Work work, N n)
Definition: GVNGCM.java:43
com.cliffc.aa.GVNGCM._all_works
final Work[] _all_works
Definition: GVNGCM.java:37
com.cliffc.aa.GVNGCM.xform
Node xform(Node n)
Definition: GVNGCM.java:126
com.cliffc.aa.type.Bits.above_center
boolean above_center()
Definition: Bits.java:204
com.cliffc.aa.Env.GVN
static final GVNGCM GVN
Definition: Env.java:13
com.cliffc.aa.GVNGCM._new_works
final Work[] _new_works
Definition: GVNGCM.java:33
com.cliffc.aa.node.Node.unkeep
public< N extends Node > N unkeep()
Definition: Node.java:232
com.cliffc.aa.GVNGCM.Build.init2
public< M extends Node > M init2(M n)
Definition: GVNGCM.java:375
com.cliffc.aa.util.Ary.add
Ary< E > add(E e)
Add element in amortized constant time.
Definition: Ary.java:49
com.cliffc.aa.node.Node.is_dead
boolean is_dead()
Definition: Node.java:820
com.cliffc.aa.node.Node.value
abstract Type value(GVNGCM.Mode opt_mode)
com.cliffc.aa.GVNGCM._work_mono
final Work _work_mono
Definition: GVNGCM.java:28
com.cliffc.aa.node.Node.kill
Node kill()
Definition: Node.java:211
com.cliffc.aa.node.CallNode._not_resolved_by_gcp
boolean _not_resolved_by_gcp
Definition: CallNode.java:90
com.cliffc.aa.node.Node._keep
byte _keep
Definition: Node.java:86
com.cliffc.aa.GVNGCM.add_reduce_uses
void add_reduce_uses(Node n)
Definition: GVNGCM.java:57
com.cliffc.aa.node.Work.apply
abstract Node apply(Node n)
com.cliffc.aa.GVNGCM.HAS_WORK
static boolean HAS_WORK
Definition: GVNGCM.java:38
com.cliffc.aa.GVNGCM.xreduce
Node xreduce(Node n)
Definition: GVNGCM.java:135
com.cliffc.aa.type.Type.CTRL
static final Type CTRL
Definition: Type.java:326
com.cliffc.aa.GVNGCM.retype_mem
static void retype_mem(BitSet aliases, Node mem, Node exit, boolean skip_calls)
Definition: GVNGCM.java:330
com.cliffc.aa.node.Node.in
Node in(int i)
Definition: Node.java:126
com.cliffc.aa.node.Work.clear
void clear()
Definition: Work.java:37
com.cliffc.aa.GVNGCM.on_flow
boolean on_flow(Node n)
Definition: GVNGCM.java:40
com.cliffc.aa.type.Type.may_be_con
boolean may_be_con()
Definition: Type.java:759
com.cliffc.aa.GVNGCM
Definition: GVNGCM.java:12
com.cliffc.aa.type.Type.simple_ptr
Type simple_ptr()
Definition: Type.java:358
com.cliffc.aa.GVNGCM.Build.xform
Node xform(Node n)
Definition: GVNGCM.java:359
com.cliffc.aa.GVNGCM.add_flow
void add_flow(UQNodes deps)
Definition: GVNGCM.java:56
com.cliffc.aa.node.Node.walk_initype
final void walk_initype(GVNGCM gvn, VBitSet bs)
Definition: Node.java:691
com.cliffc.aa.util.VBitSet
Definition: VBitSet.java:5
com.cliffc.aa.node.Node.more_flow
final int more_flow(boolean lifting)
Definition: Node.java:747
com.cliffc.aa.type.BitsFun
Definition: BitsFun.java:7
com.cliffc.aa.GVNGCM.remove_ambi
void remove_ambi(CallNode call)
Definition: GVNGCM.java:291
com.cliffc.aa.node.CallNode.least_cost
FunPtrNode least_cost(BitsFun choices, Node unk)
Definition: CallNode.java:624
com.cliffc.aa.GVNGCM.iter
Node iter(Node x, Work[] works)
Definition: GVNGCM.java:172
com.cliffc.aa.node.CallNode.ctl
Node ctl()
Definition: CallNode.java:118
com.cliffc.aa.GVNGCM.Mode.Mode
Mode(boolean CG)
Definition: GVNGCM.java:20
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.node.Work.at
Node at(int i)
Definition: Work.java:27
com.cliffc.aa.node.Work.add
public< N extends Node > N add(N n)
Definition: Work.java:15
com.cliffc.aa.GVNGCM.init0
void init0()
Definition: GVNGCM.java:83
com.cliffc.aa
Definition: AA.java:1
com.cliffc.aa.node.ConTypeNode
Definition: ConTypeNode.java:18
com.cliffc.aa.type.BitsFun.ANY
static final BitsFun ANY
Definition: BitsFun.java:34
com.cliffc.aa.GVNGCM._reduce_works
final Work[] _reduce_works
Definition: GVNGCM.java:35
com.cliffc.aa.tvar.UQNodes
Definition: UQNodes.java:8
com.cliffc.aa.GVNGCM.IDEAL_VISIT
static final VBitSet IDEAL_VISIT
Definition: GVNGCM.java:146
com.cliffc.aa.GVNGCM.ITER_CNT_NOOP
static int ITER_CNT_NOOP
Definition: GVNGCM.java:171
com.cliffc.aa.type.Bits.abit
int abit()
Definition: Bits.java:203
com.cliffc.aa.GVNGCM.gcp
void gcp(Mode mode, ScopeNode rez)
Definition: GVNGCM.java:217
com.cliffc.aa.node.CallNode.ttfp
static TypeFunPtr ttfp(Type tcall)
Definition: CallNode.java:157
com.cliffc.aa.type.TypeTuple.at
Type at(int idx)
Definition: TypeTuple.java:182
AutoCloseable
com.cliffc.aa.node.Node.do_grow
Node do_grow()
Definition: Node.java:639
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.node.Work.pop
Node pop()
Definition: Work.java:21
com.cliffc.aa.GVNGCM.Mode.Opto
Opto
Definition: GVNGCM.java:17
com.cliffc.aa.GVNGCM._work_dom
final Work _work_dom
Definition: GVNGCM.java:31
com.cliffc.aa.GVNGCM.add_flow_defs
void add_flow_defs(Node n)
Definition: GVNGCM.java:54
com.cliffc.aa.node.Work.isEmpty
boolean isEmpty()
Definition: Work.java:35
com.cliffc.aa.GVNGCM._opt_mode
Mode _opt_mode
Definition: GVNGCM.java:22
com.cliffc.aa.GVNGCM.Build
Definition: GVNGCM.java:356
com.cliffc.aa.GVNGCM.add_flow
public< N extends Node > N add_flow(N n)
Definition: GVNGCM.java:50
com.cliffc.aa.node.CallNode.set_fdx
Node set_fdx(Node fun)
Definition: CallNode.java:132
com.cliffc.aa.node.CallNode.set_dsp
Node set_dsp(Node dsp)
Definition: CallNode.java:130
com.cliffc.aa.GVNGCM.add_dead
void add_dead(Node n)
Definition: GVNGCM.java:48
com.cliffc.aa.GVNGCM.iter
void iter(Mode opt_mode)
Definition: GVNGCM.java:147
com.cliffc.aa.GVNGCM.Build._ret
N _ret
Definition: GVNGCM.java:358
com.cliffc.aa.util.Ary.find
int find(E e)
Find the first matching element using ==, or -1 if none.
Definition: Ary.java:192
com.cliffc.aa.node.FunNode
Definition: FunNode.java:58
com.cliffc.aa.GVNGCM.Build.add
Node add(Node n)
Definition: GVNGCM.java:369
com.cliffc.aa.node.FunPtrNode.display
Node display()
Definition: FunPtrNode.java:63
com.cliffc.aa.node.CallNode.fdx
Node fdx()
Definition: CallNode.java:121
com
com.cliffc.aa.node.Node.do_reduce
Node do_reduce()
Definition: Node.java:545
com.cliffc.aa.node.Work.len
int len()
Definition: Work.java:14
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.GVNGCM.Mode.Parse
Parse
Definition: GVNGCM.java:15
com.cliffc.aa.node.Node.walk_opt
void walk_opt(VBitSet visit)
Definition: Node.java:797
com.cliffc.aa.type
Definition: Bits.java:1
com.cliffc.aa.GVNGCM.on_dead
boolean on_dead(Node n)
Definition: GVNGCM.java:39
com.cliffc.aa.node.Node.add_flow_extra
void add_flow_extra(Type old)
Definition: Node.java:513
com.cliffc.aa.GVNGCM.init
public< N extends Node > N init(N n)
Definition: GVNGCM.java:99
com.cliffc.aa.node.Node._defs
Ary< Node > _defs
Definition: Node.java:124
com.cliffc.aa.node
Definition: AssertNode.java:1
com.cliffc.aa.GVNGCM.Mode
Definition: GVNGCM.java:14