1 #ifdef USE_PRAGMA_IDENT_HDR
2 #pragma ident "@(#)escape.hpp 1.9 07/05/17 15:58:25 JVM"
3 #endif
4 /*
5 * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7 *
8 * This code is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 only, as
10 * published by the Free Software Foundation.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
24 * have any questions.
25 *
26 */
27
28 //
29 // Adaptation for C2 of the escape analysis algorithm described in:
30 //
31 // [Choi99] Jong-Deok Shoi, Manish Gupta, Mauricio Seffano, Vugranam C. Sreedhar,
32 // Sam Midkiff, "Escape Analysis for Java", Procedings of ACM SIGPLAN
33 // OOPSLA Conference, November 1, 1999
34 //
35 // The flow-insensitive analysis described in the paper has been implemented.
36 //
37 // The analysis requires construction of a "connection graph" (CG) for the method being
38 // analyzed. The nodes of the connection graph are:
39 //
40 // - Java objects (JO)
41 // - Local variables (LV)
42 // - Fields of an object (OF), these also include array elements
43 //
44 // The CG contains 3 types of edges:
45 //
46 // - PointsTo (-P>) {LV,OF} to JO
47 // - Deferred (-D>) from {LV, OF} to {LV, OF}
48 // - Field (-F>) from JO to OF
49 //
50 // The following utility functions is used by the algorithm:
51 //
52 // PointsTo(n) - n is any CG node, it returns the set of JO that n could
53 // point to.
54 //
55 // The algorithm describes how to construct the connection graph in the following 4 cases:
56 //
57 // Case Edges Created
58 //
59 // (1) p = new T() LV -P> JO
60 // (2) p = q LV -D> LV
61 // (3) p.f = q JO -F> OF, OF -D> LV
62 // (4) p = q.f JO -F> OF, LV -D> OF
63 //
64 // In all these cases, p and q are local variables. For static field references, we can
65 // construct a local variable containing a reference to the static memory.
66 //
67 // C2 does not have local variables. However for the purposes of constructing
68 // the connection graph, the following IR nodes are treated as local variables:
69 // Phi (pointer values)
70 // LoadP
71 // Proj (value returned from callnodes including allocations)
72 // CheckCastPP
73 //
74 // The LoadP, Proj and CheckCastPP behave like variables assigned to only once. Only
75 // a Phi can have multiple assignments. Each input to a Phi is treated
76 // as an assignment to it.
77 //
78 // The following note types are JavaObject:
79 //
80 // top()
81 // Allocate
82 // AllocateArray
83 // Parm (for incoming arguments)
84 // CreateEx
85 // ConP
86 // LoadKlass
87 //
88 // AddP nodes are fields.
89 //
90 // After building the graph, a pass is made over the nodes, deleting deferred
91 // nodes and copying the edges from the target of the deferred edge to the
92 // source. This results in a graph with no deferred edges, only:
93 //
94 // LV -P> JO
95 // OF -P> JO
96 // JO -F> OF
97 //
98 // Then, for each node which is GlobalEscape, anything it could point to
99 // is marked GlobalEscape. Finally, for any node marked ArgEscape, anything
100 // it could point to is marked ArgEscape.
101 //
102
103 class Compile;
104 class Node;
105 class CallNode;
106 class PhiNode;
107 class PhaseTransform;
108 class Type;
109 class TypePtr;
110 class VectorSet;
111
112 class PointsToNode {
113 friend class ConnectionGraph;
114 public:
115 typedef enum {
116 UnknownType = 0,
117 JavaObject = 1,
118 LocalVar = 2,
119 Field = 3
120 } NodeType;
121
122 typedef enum {
123 UnknownEscape = 0,
124 NoEscape = 1,
125 ArgEscape = 2,
126 GlobalEscape = 3
127 } EscapeState;
128
129 typedef enum {
130 UnknownEdge = 0,
131 PointsToEdge = 1,
132 DeferredEdge = 2,
133 FieldEdge = 3
134 } EdgeType;
135
136 private:
137 enum {
138 EdgeMask = 3,
139 EdgeShift = 2,
140
141 INITIAL_EDGE_COUNT = 4
142 };
143
144 NodeType _type;
145 EscapeState _escape;
146 GrowableArray<uint>* _edges; // outgoing edges
147 int _offset; // for fields
148
149 bool _unique_type; // For allocated objects, this node may be a unique type
150 public:
151 Node* _node; // Ideal node corresponding to this PointsTo node
152 int _inputs_processed; // the number of Phi inputs that have been processed so far
153 bool _hidden_alias; // this node is an argument to a function which may return it
154 // creating a hidden alias
155
156
157 PointsToNode(): _offset(-1), _type(UnknownType), _escape(UnknownEscape), _edges(NULL), _node(NULL), _inputs_processed(0), _hidden_alias(false), _unique_type(true) {}
158
159 EscapeState escape_state() const { return _escape; }
160 NodeType node_type() const { return _type;}
161 int offset() { return _offset;}
162
163 void set_offset(int offs) { _offset = offs;}
164 void set_escape_state(EscapeState state) { _escape = state; }
165 void set_node_type(NodeType ntype) {
166 assert(_type == UnknownType || _type == ntype, "Can't change node type");
167 _type = ntype;
168 }
169
170 // count of outgoing edges
171 uint edge_count() const { return (_edges == NULL) ? 0 : _edges->length(); }
172 // node index of target of outgoing edge "e"
173 uint edge_target(uint e) const;
174 // type of outgoing edge "e"
175 EdgeType edge_type(uint e) const;
176 // add a edge of the specified type pointing to the specified target
177 void add_edge(uint targIdx, EdgeType et);
178 // remove an edge of the specified type pointing to the specified target
179 void remove_edge(uint targIdx, EdgeType et);
180 #ifndef PRODUCT
181 void dump() const;
182 #endif
183
184 };
185
186 class ConnectionGraph: public ResourceObj {
187 private:
188 enum {
189 INITIAL_NODE_COUNT = 100 // initial size of _nodes array
190 };
191
192
193 GrowableArray<PointsToNode>* _nodes; // connection graph nodes Indexed by ideal
194 // node index
195 Unique_Node_List _deferred; // Phi's to be processed after parsing
196 VectorSet _processed; // records which nodes have been processed
197 bool _collecting; // indicates whether escape information is
198 // still being collected. If false, no new
199 // nodes will be processed
200 uint _phantom_object; // index of globally escaping object that
201 // pointer values loaded from a field which
202 // has not been set are assumed to point to
203 Compile * _compile; // Compile object for current compilation
204
205 // address of an element in _nodes. Used when the element is to be modified
206 PointsToNode *ptnode_adr(uint idx) {
207 if ((uint)_nodes->length() <= idx) {
208 // expand _nodes array
209 PointsToNode dummy = _nodes->at_grow(idx);
210 }
211 return _nodes->adr_at(idx);
212 }
213
214 // offset of a field reference
215 int type_to_offset(const Type *t);
216
217 // compute the escape state for arguments to a call
218 void process_call_arguments(CallNode *call, PhaseTransform *phase);
219
220 // compute the escape state for the return value of a call
221 void process_call_result(ProjNode *resproj, PhaseTransform *phase);
222
223 // compute the escape state of a Phi. This may be called multiple
224 // times as new inputs are added to the Phi.
225 void process_phi_escape(PhiNode *phi, PhaseTransform *phase);
226
227 // compute the escape state of an ideal node.
228 void record_escape_work(Node *n, PhaseTransform *phase);
229
230 // walk the connection graph starting at the node corresponding to "n" and
231 // add the index of everything it could point to, to "ptset". This may cause
232 // Phi's encountered to get (re)processed (which requires "phase".)
233 void PointsTo(VectorSet &ptset, Node * n, PhaseTransform *phase);
234
235 // Edge manipulation. The "from_i" and "to_i" arguments are the
236 // node indices of the source and destination of the edge
237 void add_pointsto_edge(uint from_i, uint to_i);
238 void add_deferred_edge(uint from_i, uint to_i);
239 void add_field_edge(uint from_i, uint to_i, int offs);
240
241
242 // Add an edge to node given by "to_i" from any field of adr_i whose offset
243 // matches "offset" A deferred edge is added if to_i is a LocalVar, and
244 // a pointsto edge is added if it is a JavaObject
245 void add_edge_from_fields(uint adr, uint to_i, int offs);
246
247 // Add a deferred edge from node given by "from_i" to any field of adr_i whose offset
248 // matches "offset"
249 void add_deferred_edge_to_fields(uint from_i, uint adr, int offs);
250
251
252 // Remove outgoing deferred edges from the node referenced by "ni".
253 // Any outgoing edges from the target of the deferred edge are copied
254 // to "ni".
255 void remove_deferred(uint ni);
256
257 Node_Array _node_map; // used for bookeeping during type splitting
258 // Used for the following purposes:
259 // Memory Phi - most recent unique Phi split out
260 // from this Phi
261 // MemNode - new memory input for this node
262 // ChecCastPP - allocation that this is a cast of
263 // allocation - CheckCastPP of the allocation
264 void split_AddP(Node *addp, Node *base, PhaseGVN *igvn);
265 PhiNode *create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *> &orig_phi_worklist, PhaseGVN *igvn, bool &new_created);
266 PhiNode *split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *> &orig_phi_worklist, PhaseGVN *igvn);
267 Node *find_mem(Node *mem, int alias_idx, PhaseGVN *igvn);
268 // Propagate unique types created for unescaped allocated objects
269 // through the graph
270 void split_unique_types(GrowableArray<Node *> &alloc_worklist);
271
272 // manage entries in _node_map
273 void set_map(int idx, Node *n) { _node_map.map(idx, n); }
274 void set_map_phi(int idx, PhiNode *p) { _node_map.map(idx, (Node *) p); }
275 Node *get_map(int idx) { return _node_map[idx]; }
276 PhiNode *get_map_phi(int idx) {
277 Node *phi = _node_map[idx];
278 return (phi == NULL) ? NULL : phi->as_Phi();
279 }
280
281 // Notify optimizer that a node has been modified
282 // Node: This assumes that escape analysis is run before
283 // PhaseIterGVN creation
284 void record_for_optimizer(Node *n) {
285 _compile->record_for_igvn(n);
286 }
287
288 // Set the escape state of a node
289 void set_escape_state(uint ni, PointsToNode::EscapeState es);
290
291 // bypass any casts and return the node they refer to
292 Node * skip_casts(Node *n);
293
294 // Get Compile object for current compilation.
295 Compile *C() const { return _compile; }
296
297 public:
298 ConnectionGraph(Compile *C);
299
300 // record a Phi for later processing.
301 void record_for_escape_analysis(Node *n);
302
303 // process a node and fill in its connection graph node
304 void record_escape(Node *n, PhaseTransform *phase);
305
306 // All nodes have been recorded, compute the escape information
307 void compute_escape();
308
309 // escape state of a node
310 PointsToNode::EscapeState escape_state(Node *n, PhaseTransform *phase);
311
312 bool hidden_alias(Node *n) {
313 if (_collecting)
314 return true;
315 PointsToNode ptn = _nodes->at_grow(n->_idx);
316 return (ptn.escape_state() != PointsToNode::NoEscape) || ptn._hidden_alias;
317 }
318
319 #ifndef PRODUCT
320 void dump();
321 #endif
322 };
323
|
1 #ifdef USE_PRAGMA_IDENT_HDR
2 #pragma ident "@(#)escape.hpp 1.9 07/05/17 15:58:25 JVM"
3 #endif
4 /*
5 * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved.
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7 *
8 * This code is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 only, as
10 * published by the Free Software Foundation.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
24 * have any questions.
25 *
26 */
27
28 //
29 // Adaptation for C2 of the escape analysis algorithm described in:
30 //
31 // [Choi99] Jong-Deok Shoi, Manish Gupta, Mauricio Seffano,
32 // Vugranam C. Sreedhar, Sam Midkiff,
33 // "Escape Analysis for Java", Procedings of ACM SIGPLAN
34 // OOPSLA Conference, November 1, 1999
35 //
36 // The flow-insensitive analysis described in the paper has been implemented.
37 //
38 // The analysis requires construction of a "connection graph" (CG) for
39 // the method being analyzed. The nodes of the connection graph are:
40 //
41 // - Java objects (JO)
42 // - Local variables (LV)
43 // - Fields of an object (OF), these also include array elements
44 //
45 // The CG contains 3 types of edges:
46 //
47 // - PointsTo (-P>) {LV, OF} to JO
48 // - Deferred (-D>) from {LV, OF} to {LV, OF}
49 // - Field (-F>) from JO to OF
50 //
51 // The following utility functions is used by the algorithm:
52 //
53 // PointsTo(n) - n is any CG node, it returns the set of JO that n could
54 // point to.
55 //
56 // The algorithm describes how to construct the connection graph
57 // in the following 4 cases:
58 //
59 // Case Edges Created
60 //
61 // (1) p = new T() LV -P> JO
62 // (2) p = q LV -D> LV
63 // (3) p.f = q JO -F> OF, OF -D> LV
64 // (4) p = q.f JO -F> OF, LV -D> OF
65 //
66 // In all these cases, p and q are local variables. For static field
67 // references, we can construct a local variable containing a reference
68 // to the static memory.
69 //
70 // C2 does not have local variables. However for the purposes of constructing
71 // the connection graph, the following IR nodes are treated as local variables:
72 // Phi (pointer values)
73 // LoadP
74 // Proj#5 (value returned from callnodes including allocations)
75 // CheckCastPP, CastPP
76 //
77 // The LoadP, Proj and CheckCastPP behave like variables assigned to only once.
78 // Only a Phi can have multiple assignments. Each input to a Phi is treated
79 // as an assignment to it.
80 //
81 // The following node types are JavaObject:
82 //
83 // top()
84 // Allocate
85 // AllocateArray
86 // Parm (for incoming arguments)
87 // CastX2P ("unsafe" operations)
88 // CreateEx
89 // ConP
90 // LoadKlass
91 // ThreadLocal
92 //
93 // AddP nodes are fields.
94 //
95 // After building the graph, a pass is made over the nodes, deleting deferred
96 // nodes and copying the edges from the target of the deferred edge to the
97 // source. This results in a graph with no deferred edges, only:
98 //
99 // LV -P> JO
100 // OF -P> JO (the object whose oop is stored in the field)
101 // JO -F> OF
102 //
103 // Then, for each node which is GlobalEscape, anything it could point to
104 // is marked GlobalEscape. Finally, for any node marked ArgEscape, anything
105 // it could point to is marked ArgEscape.
106 //
107
108 class Compile;
109 class Node;
110 class CallNode;
111 class PhiNode;
112 class PhaseTransform;
113 class Type;
114 class TypePtr;
115 class VectorSet;
116
117 class PointsToNode {
118 friend class ConnectionGraph;
119 public:
120 typedef enum {
121 UnknownType = 0,
122 JavaObject = 1,
123 LocalVar = 2,
124 Field = 3
125 } NodeType;
126
127 typedef enum {
128 UnknownEscape = 0,
129 NoEscape = 1, // A scalar replaceable object with unique type.
130 ArgEscape = 2, // An object passed as argument or referenced by
131 // argument (and not globally escape during call).
132 GlobalEscape = 3 // An object escapes the method and thread.
133 } EscapeState;
134
135 typedef enum {
136 UnknownEdge = 0,
137 PointsToEdge = 1,
138 DeferredEdge = 2,
139 FieldEdge = 3
140 } EdgeType;
141
142 private:
143 enum {
144 EdgeMask = 3,
145 EdgeShift = 2,
146
147 INITIAL_EDGE_COUNT = 4
148 };
149
150 NodeType _type;
151 EscapeState _escape;
152 GrowableArray<uint>* _edges; // outgoing edges
153
154 public:
155 Node* _node; // Ideal node corresponding to this PointsTo node.
156 int _offset; // Object fields offsets.
157 bool _scalar_replaceable;// Not escaped object could be replaced with scalar
158 bool _hidden_alias; // This node is an argument to a function.
159 // which may return it creating a hidden alias.
160
161 PointsToNode():
162 _type(UnknownType),
163 _escape(UnknownEscape),
164 _edges(NULL),
165 _node(NULL),
166 _offset(-1),
167 _scalar_replaceable(true),
168 _hidden_alias(false) {}
169
170
171 EscapeState escape_state() const { return _escape; }
172 NodeType node_type() const { return _type;}
173 int offset() { return _offset;}
174
175 void set_offset(int offs) { _offset = offs;}
176 void set_escape_state(EscapeState state) { _escape = state; }
177 void set_node_type(NodeType ntype) {
178 assert(_type == UnknownType || _type == ntype, "Can't change node type");
179 _type = ntype;
180 }
181
182 // count of outgoing edges
183 uint edge_count() const { return (_edges == NULL) ? 0 : _edges->length(); }
184
185 // node index of target of outgoing edge "e"
186 uint edge_target(uint e) const {
187 assert(_edges != NULL, "valid edge index");
188 return (_edges->at(e) >> EdgeShift);
189 }
190 // type of outgoing edge "e"
191 EdgeType edge_type(uint e) const {
192 assert(_edges != NULL, "valid edge index");
193 return (EdgeType) (_edges->at(e) & EdgeMask);
194 }
195
196 // add a edge of the specified type pointing to the specified target
197 void add_edge(uint targIdx, EdgeType et);
198
199 // remove an edge of the specified type pointing to the specified target
200 void remove_edge(uint targIdx, EdgeType et);
201
202 #ifndef PRODUCT
203 void dump(bool print_state=true) const;
204 #endif
205
206 };
207
208 class ConnectionGraph: public ResourceObj {
209 private:
210 GrowableArray<PointsToNode> _nodes; // Connection graph nodes indexed
211 // by ideal node index.
212
213 Unique_Node_List _delayed_worklist; // Nodes to be processed before
214 // the call build_connection_graph().
215
216 VectorSet _processed; // Records which nodes have been
217 // processed.
218
219 bool _collecting; // Indicates whether escape information
220 // is still being collected. If false,
221 // no new nodes will be processed.
222
223 uint _phantom_object; // Index of globally escaping object
224 // that pointer values loaded from
225 // a field which has not been set
226 // are assumed to point to.
227 uint _oop_null; // ConP(#NULL)
228 uint _noop_null; // ConN(#NULL)
229
230 Compile * _compile; // Compile object for current compilation
231
232 // Address of an element in _nodes. Used when the element is to be modified
233 PointsToNode *ptnode_adr(uint idx) const {
234 // There should be no new ideal nodes during ConnectionGraph build,
235 // growableArray::adr_at() will throw assert otherwise.
236 return _nodes.adr_at(idx);
237 }
238 uint nodes_size() const { return _nodes.length(); }
239
240 // Add node to ConnectionGraph.
241 void add_node(Node *n, PointsToNode::NodeType nt, PointsToNode::EscapeState es, bool done);
242
243 // offset of a field reference
244 int address_offset(Node* adr, PhaseTransform *phase);
245
246 // compute the escape state for arguments to a call
247 void process_call_arguments(CallNode *call, PhaseTransform *phase);
248
249 // compute the escape state for the return value of a call
250 void process_call_result(ProjNode *resproj, PhaseTransform *phase);
251
252 // Populate Connection Graph with Ideal nodes.
253 void record_for_escape_analysis(Node *n, PhaseTransform *phase);
254
255 // Build Connection Graph and set nodes escape state.
256 void build_connection_graph(Node *n, PhaseTransform *phase);
257
258 // walk the connection graph starting at the node corresponding to "n" and
259 // add the index of everything it could point to, to "ptset". This may cause
260 // Phi's encountered to get (re)processed (which requires "phase".)
261 void PointsTo(VectorSet &ptset, Node * n, PhaseTransform *phase);
262
263 // Edge manipulation. The "from_i" and "to_i" arguments are the
264 // node indices of the source and destination of the edge
265 void add_pointsto_edge(uint from_i, uint to_i);
266 void add_deferred_edge(uint from_i, uint to_i);
267 void add_field_edge(uint from_i, uint to_i, int offs);
268
269
270 // Add an edge to node given by "to_i" from any field of adr_i whose offset
271 // matches "offset" A deferred edge is added if to_i is a LocalVar, and
272 // a pointsto edge is added if it is a JavaObject
273 void add_edge_from_fields(uint adr, uint to_i, int offs);
274
275 // Add a deferred edge from node given by "from_i" to any field
276 // of adr_i whose offset matches "offset"
277 void add_deferred_edge_to_fields(uint from_i, uint adr, int offs);
278
279
280 // Remove outgoing deferred edges from the node referenced by "ni".
281 // Any outgoing edges from the target of the deferred edge are copied
282 // to "ni".
283 void remove_deferred(uint ni, GrowableArray<uint>* deferred_edges, VectorSet* visited);
284
285 Node_Array _node_map; // used for bookeeping during type splitting
286 // Used for the following purposes:
287 // Memory Phi - most recent unique Phi split out
288 // from this Phi
289 // MemNode - new memory input for this node
290 // ChecCastPP - allocation that this is a cast of
291 // allocation - CheckCastPP of the allocation
292 bool split_AddP(Node *addp, Node *base, PhaseGVN *igvn);
293 PhiNode *create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *> &orig_phi_worklist, PhaseGVN *igvn, bool &new_created);
294 PhiNode *split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *> &orig_phi_worklist, PhaseGVN *igvn);
295 Node *find_mem(Node *mem, int alias_idx, PhaseGVN *igvn);
296 Node *find_inst_mem(Node *mem, int alias_idx,GrowableArray<PhiNode *> &orig_phi_worklist, PhaseGVN *igvn);
297
298 // Propagate unique types created for unescaped allocated objects
299 // through the graph
300 void split_unique_types(GrowableArray<Node *> &alloc_worklist);
301
302 // manage entries in _node_map
303 void set_map(int idx, Node *n) { _node_map.map(idx, n); }
304 void set_map_phi(int idx, PhiNode *p) { _node_map.map(idx, (Node *) p); }
305 Node *get_map(int idx) { return _node_map[idx]; }
306 PhiNode *get_map_phi(int idx) {
307 Node *phi = _node_map[idx];
308 return (phi == NULL) ? NULL : phi->as_Phi();
309 }
310
311 // Notify optimizer that a node has been modified
312 // Node: This assumes that escape analysis is run before
313 // PhaseIterGVN creation
314 void record_for_optimizer(Node *n) {
315 _compile->record_for_igvn(n);
316 }
317
318 // Set the escape state of a node
319 void set_escape_state(uint ni, PointsToNode::EscapeState es);
320
321 public:
322 ConnectionGraph(Compile *C);
323
324 // Check for non-escaping candidates
325 static bool has_candidates(Compile *C);
326
327 // Compute the escape information
328 bool compute_escape();
329
330 // escape state of a node
331 PointsToNode::EscapeState escape_state(Node *n, PhaseTransform *phase);
332 // other information we have collected
333 bool is_scalar_replaceable(Node *n) {
334 if (_collecting || (n->_idx >= nodes_size()))
335 return false;
336 PointsToNode* ptn = ptnode_adr(n->_idx);
337 return ptn->escape_state() == PointsToNode::NoEscape && ptn->_scalar_replaceable;
338 }
339
340 bool hidden_alias(Node *n) {
341 if (_collecting || (n->_idx >= nodes_size()))
342 return true;
343 PointsToNode* ptn = ptnode_adr(n->_idx);
344 return (ptn->escape_state() != PointsToNode::NoEscape) || ptn->_hidden_alias;
345 }
346
347 #ifndef PRODUCT
348 void dump();
349 #endif
350 };
351
|