aa
RegionNode.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.type.Type;
6 import com.cliffc.aa.type.TypeMem;
7 
8 import java.util.function.Predicate;
9 
10 // Merge results. Supports many merging paths; used by FunNode and LoopNode.
11 public class RegionNode extends Node {
12  public RegionNode( Node... ctrls) { super(OP_REGION,ctrls); }
13  RegionNode( byte op ) { super(op,(Node)null); } // For FunNodes
14 
15  @Override public Node ideal_reduce() {
16  // TODO: The unzip xform, especially for funnodes doing type-specialization
17  // TODO: treat _cidx like U/F and skip_dead it also
18  if( _keep >= 2 ) return null; // Mid-construction in parser
19  int dlen = _defs.len();
20  for( int i=1; i<dlen; i++ ) {
21  Node cc = in(i).is_copy(0);
22  if( cc!=null && cc != this ) return set_def(i,cc);
23  }
24 
25  // Look for dead paths. If found, cut dead path out of all Phis and this
26  // Node, and return-for-progress.
27  for( int i=1; i<dlen; i++ )
28  if( val(i)==Type.XCTRL && !(i==1 && is_prim()) ) { // Found dead path; cut out
29  for( Node phi : _uses )
30  if( phi instanceof PhiNode )
31  phi.remove(i);
32  unwire(i);
33  remove(i);
34  if( this instanceof FunNode && _defs._len==2 && in(1).in(0) instanceof CallNode ) {
35  Node cepi = ((CallNode)in(1).in(0)).cepi();
36  if( cepi!=null ) Env.GVN.add_reduce(cepi);
37  }
38  return this; // Progress
39  }
40 
41  if( dlen == 1 ) return null; // No live inputs; dead in value() call
42  if( in(1) == Env.ALL_CTRL ) return null; // Alive from unknown caller
43  if( dlen==2 ) { // Exactly 1 live path
44  // If only 1 live path and no Phis then return 1 live path.
45  for( Node phi : _uses ) if( phi instanceof PhiNode ) return null;
46  // Single input FunNodes can NOT inline to their one caller,
47  // unless the one caller only also calls the one FunNode.
48  // Wait for the FunNode to be declared dead.
49  if( in(0)==null && this instanceof FunNode )
50  return null; // I am not yet dead
51  // Self-dead-cycle is dead in value() call
52  return in(1)==this ? null : in(1);
53  }
54  // Check for empty diamond
55  if( dlen==3 ) { // Exactly 2 live paths
56  Node nif = in(1).in(0);
57  if( in(1) instanceof CProjNode && nif==in(2).in(0) && nif instanceof IfNode ) {
58  // Must have no phi uses
59  for( Node phi : _uses ) if( phi instanceof PhiNode ) return null;
60  return nif.in(0);
61  }
62  }
63 
64  // Check for stacked Region (not Fun) and collapse.
65  Node stack = stacked_region();
66  if( stack != null ) return stack;
67 
68  return null;
69  }
70  @Override public void add_flow_def_extra(Node chg) {
71  if( chg.is_CFG() ) { // If losing an extra CFG user
72  for( Node use : _uses )
73  if( use._op == OP_REGION ) // Then stacked regions can fold
74  Env.GVN.add_reduce(use); // Put lower region of stack on worklist
75  if( this instanceof FunNode && ((FunNode)this).ret()==null )
76  Env.GVN.add_reduce(this);
77  }
78  }
79 
80  // Collapse stacked regions.
82  if( _op != OP_REGION ) return null; // Does not apply to e.g. functions & loops
83  int idx = _defs.find( e -> e !=null && e._op==OP_REGION );
84  if( idx== -1 ) return null; // No stacked region
85  Node r = in(idx);
86  if( r == this ) return null; // Dying code
87  int cfgs=0;
88  for( Node use : r._uses ) cfgs += use.is_CFG() ? 1 : 0;
89  if( cfgs != 1 ) return null;
90  // Every 'r' Phi is pointed *at* by exactly a 'this' Phi
91  for( Node rphi : r._uses )
92  if( rphi._op == OP_PHI ) {
93  if( rphi._uses._len != 1 ) return null; // Busy rphi
94  Node phi = rphi._uses.at(0); // Exactly a this.phi
95  if( phi._op != OP_PHI || // Not a Phi
96  phi.in(0) != this || // Control to this
97  phi.in(idx) != rphi ) // Matching along idx
98  return null; // Not exact shape
99  }
100 
101  // Collapse stacked Phis
102  for( Node phi : _uses )
103  if( phi._op == OP_PHI ) {
104  Node rphi = phi.in(idx);
105  boolean stacked_phi = rphi._op == OP_PHI && rphi.in(0)==r;
106  for( int i = 1; i<r._defs._len; i++ )
107  phi.add_def(stacked_phi ? rphi.in(i) : rphi);
108  phi.remove(idx);
109  assert !stacked_phi || rphi._uses._len==0;
110  }
111 
112  // Collapse stacked Region
113  for( int i = 1; i<r._defs._len; i++ )
114  add_def(r.in(i));
115  remove(idx);
116  return this;
117  }
118 
119  void unwire(int idx) { }
120 
121  @Override public Type value(GVNGCM.Mode opt_mode) {
122  if( _defs._len==2 && in(1)==this ) return Type.XCTRL; // Dead self-loop
123  for( int i=1; i<_defs._len; i++ ) {
124  Type c = val(i);
125  if( c == Type.CTRL || c == Type.ALL )
126  return Type.CTRL;
127  }
128  return Type.XCTRL;
129  }
130  // Control into a Region allows Phis to make progress
131  @Override public void add_flow_use_extra(Node chg) {
132  Env.GVN.add_reduce(this);
133  for( Node phi : _uses )
134  if( phi instanceof PhiNode ) {
135  Env.GVN.add_flow(phi);
136  Env.GVN.add_flow_defs(phi); // Inputs to Phi change liveness
137  }
138  }
139 
140  @Override public TypeMem all_live() { return TypeMem.ALIVE; }
141  @Override public TypeMem live_use(GVNGCM.Mode opt_mode, Node def ) { return TypeMem.ALIVE; }
142 
143  //@Override public TV2 new_tvar(String alloc_site) { return TV2.make_base(this,Type.CTRL,alloc_site); }
144  //
146  //@Override public boolean unify( boolean test ) {
147  // boolean progress = false;
148  // for( int i=1; i<_defs._len; i++ )
149  // if( val(i)!=Type.XCTRL && val(i)!=Type.ANY ) { // Only unify alive paths
150  // progress |= tvar().unify(tvar(i),test);
151  // if( progress && test ) return true;
152  // }
153  // return progress;
154  //}
155 
156  // Complex dominator tree. Ok to subset, attempt the easy walk
157  @Override Node walk_dom_last(Predicate<Node> P) {
158  // Allow moving up simple diamonds
159  if( _defs._len==3 && in(1) instanceof ProjNode && in(1).in(0) instanceof IfNode &&
160  in(1).in(0) == in(2).in(0) ) {
161  Node n = in(1).in(0).walk_dom_last(P);
162  if( n != null ) return n;
163  }
164  // Experimental stronger version
165  if( _defs._len==3 && !(this instanceof FunNode) ) {
166  Node n1 = in(1).walk_dom_last(P);
167  Node n2 = in(2).walk_dom_last(P);
168  if( n1 != null && n1==n2 ) return n1;
169  }
170  return P.test(this) ? this : null;
171  }
172  @Override public Node is_copy(int idx) { return _defs._len==2 ? in(1) : null; }
173 }
com.cliffc.aa.node.Node.remove
Node remove(int idx)
Definition: Node.java:176
com.cliffc.aa.node.Node.walk_dom_last
Node walk_dom_last(Predicate< Node > P)
Definition: Node.java:863
com.cliffc.aa.type.TypeMem
Memory type; the state of all of memory; memory edges order memory ops.
Definition: TypeMem.java:53
com.cliffc
com.cliffc.aa.node.IfNode
Definition: IfNode.java:9
com.cliffc.aa.node.Node
Definition: Node.java:16
com.cliffc.aa.node.RegionNode.all_live
TypeMem all_live()
Definition: RegionNode.java:140
com.cliffc.aa.node.RegionNode.add_flow_def_extra
void add_flow_def_extra(Node chg)
Definition: RegionNode.java:70
com.cliffc.aa.type.Type
an implementation of language AA
Definition: Type.java:94
com.cliffc.aa.node.RegionNode.stacked_region
Node stacked_region()
Definition: RegionNode.java:81
com.cliffc.aa.node.PhiNode
Definition: PhiNode.java:9
com.cliffc.aa.node.CProjNode
Definition: CProjNode.java:10
com.cliffc.aa.node.Node.add_def
Node add_def(Node n)
Definition: Node.java:152
com.cliffc.aa.node.RegionNode.live_use
TypeMem live_use(GVNGCM.Mode opt_mode, Node def)
Definition: RegionNode.java:141
com.cliffc.aa.node.CallNode
Definition: CallNode.java:86
com.cliffc.aa.node.RegionNode.RegionNode
RegionNode(Node... ctrls)
Definition: RegionNode.java:12
com.cliffc.aa.type.Type.ALL
static final Type ALL
Definition: Type.java:324
com.cliffc.aa.node.Node.is_prim
boolean is_prim()
Definition: Node.java:260
com.cliffc.aa.Env.GVN
static final GVNGCM GVN
Definition: Env.java:13
com.cliffc.aa.node.Node._keep
byte _keep
Definition: Node.java:86
com.cliffc.aa.type.Type.CTRL
static final Type CTRL
Definition: Type.java:326
com.cliffc.aa.node.Node.is_copy
Node is_copy(int idx)
Definition: Node.java:827
com.cliffc.aa.node.Node.in
Node in(int i)
Definition: Node.java:126
com.cliffc.aa.type.TypeMem.ALIVE
static final TypeMem ALIVE
Definition: TypeMem.java:226
com.cliffc.aa.type.Type.XCTRL
static final Type XCTRL
Definition: Type.java:327
com.cliffc.aa.GVNGCM
Definition: GVNGCM.java:12
com.cliffc.aa.node.ProjNode
Definition: ProjNode.java:11
com.cliffc.aa.node.Node._uses
Ary< Node > _uses
Definition: Node.java:245
com.cliffc.aa.node.RegionNode.walk_dom_last
Node walk_dom_last(Predicate< Node > P)
Definition: RegionNode.java:157
com.cliffc.aa.node.Node.is_CFG
boolean is_CFG()
Definition: Node.java:356
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.RegionNode.value
Type value(GVNGCM.Mode opt_mode)
Definition: RegionNode.java:121
com.cliffc.aa.node.Node.set_def
Node set_def(int idx, Node n)
Definition: Node.java:154
com.cliffc.aa.GVNGCM.add_reduce
public< N extends Node > N add_reduce(N n)
Definition: GVNGCM.java:49
com.cliffc.aa.node.RegionNode.RegionNode
RegionNode(byte op)
Definition: RegionNode.java:13
com.cliffc.aa.node.Node._op
final byte _op
Definition: Node.java:85
com.cliffc.aa.node.RegionNode.ideal_reduce
Node ideal_reduce()
Definition: RegionNode.java:15
com.cliffc.aa.GVNGCM.add_flow_defs
void add_flow_defs(Node n)
Definition: GVNGCM.java:54
com.cliffc.aa.node.RegionNode.add_flow_use_extra
void add_flow_use_extra(Node chg)
Definition: RegionNode.java:131
com.cliffc.aa.GVNGCM.add_flow
public< N extends Node > N add_flow(N n)
Definition: GVNGCM.java:50
com.cliffc.aa.node.RegionNode.is_copy
Node is_copy(int idx)
Definition: RegionNode.java:172
com.cliffc.aa.node.RegionNode.unwire
void unwire(int idx)
Definition: RegionNode.java:119
com.cliffc.aa.node.FunNode
Definition: FunNode.java:58
com.cliffc.aa.node.RegionNode
Definition: RegionNode.java:11
com
com.cliffc.aa.node.Node.OP_PHI
static final byte OP_PHI
Definition: Node.java:38
com.cliffc.aa.Env
Definition: Env.java:12
com.cliffc.aa.type
Definition: Bits.java:1
com.cliffc.aa.node.Node._defs
Ary< Node > _defs
Definition: Node.java:124
com.cliffc.aa.node.Node.OP_REGION
static final byte OP_REGION
Definition: Node.java:41
com.cliffc.aa.Env.ALL_CTRL
static ConNode ALL_CTRL
Definition: Env.java:20
com.cliffc.aa.GVNGCM.Mode
Definition: GVNGCM.java:14