143 UnknownEdge = 0,
144 PointsToEdge = 1,
145 DeferredEdge = 2,
146 FieldEdge = 3
147 } EdgeType;
148
149 private:
150 enum {
151 EdgeMask = 3,
152 EdgeShift = 2,
153
154 INITIAL_EDGE_COUNT = 4
155 };
156
157 NodeType _type;
158 EscapeState _escape;
159 GrowableArray<uint>* _edges; // outgoing edges
160 Node* _node; // Ideal node corresponding to this PointsTo node.
161 int _offset; // Object fields offsets.
162 bool _scalar_replaceable; // Not escaped object could be replaced with scalar
163
164 public:
165 PointsToNode():
166 _type(UnknownType),
167 _escape(UnknownEscape),
168 _edges(NULL),
169 _node(NULL),
170 _offset(-1),
171 _scalar_replaceable(true) {}
172
173
174 EscapeState escape_state() const { return _escape; }
175 NodeType node_type() const { return _type;}
176 int offset() { return _offset;}
177 bool scalar_replaceable() { return _scalar_replaceable;}
178
179 void set_offset(int offs) { _offset = offs;}
180 void set_escape_state(EscapeState state) { _escape = state; }
181 void set_node_type(NodeType ntype) {
182 assert(_type == UnknownType || _type == ntype, "Can't change node type");
183 _type = ntype;
184 }
185 void set_scalar_replaceable(bool v) { _scalar_replaceable = v; }
186
187 // count of outgoing edges
188 uint edge_count() const { return (_edges == NULL) ? 0 : _edges->length(); }
189
190 // node index of target of outgoing edge "e"
191 uint edge_target(uint e) const {
192 assert(_edges != NULL, "valid edge index");
193 return (_edges->at(e) >> EdgeShift);
194 }
195 // type of outgoing edge "e"
196 EdgeType edge_type(uint e) const {
197 assert(_edges != NULL, "valid edge index");
198 return (EdgeType) (_edges->at(e) & EdgeMask);
199 }
200
201 // add a edge of the specified type pointing to the specified target
202 void add_edge(uint targIdx, EdgeType et);
203
204 // remove an edge of the specified type pointing to the specified target
205 void remove_edge(uint targIdx, EdgeType et);
233 uint _phantom_object; // Index of globally escaping object
234 // that pointer values loaded from
235 // a field which has not been set
236 // are assumed to point to.
237 uint _oop_null; // ConP(#NULL)->_idx
238 uint _noop_null; // ConN(#NULL)->_idx
239 Node* _pcmp_neq; // ConI(#CC_GT)
240 Node* _pcmp_eq; // ConI(#CC_EQ)
241
242 Compile * _compile; // Compile object for current compilation
243 PhaseIterGVN * _igvn; // Value numbering
244
245 // Address of an element in _nodes. Used when the element is to be modified
246 PointsToNode *ptnode_adr(uint idx) const {
247 // There should be no new ideal nodes during ConnectionGraph build,
248 // growableArray::adr_at() will throw assert otherwise.
249 return _nodes.adr_at(idx);
250 }
251 uint nodes_size() const { return _nodes.length(); }
252
253 // Add node to ConnectionGraph.
254 void add_node(Node *n, PointsToNode::NodeType nt, PointsToNode::EscapeState es, bool done);
255
256 // offset of a field reference
257 int address_offset(Node* adr, PhaseTransform *phase);
258
259 // compute the escape state for arguments to a call
260 void process_call_arguments(CallNode *call, PhaseTransform *phase);
261
262 // compute the escape state for the return value of a call
263 void process_call_result(ProjNode *resproj, PhaseTransform *phase);
264
265 // Populate Connection Graph with Ideal nodes.
266 void record_for_escape_analysis(Node *n, PhaseTransform *phase);
267
268 // Build Connection Graph and set nodes escape state.
269 void build_connection_graph(Node *n, PhaseTransform *phase);
270
271 // walk the connection graph starting at the node corresponding to "n" and
272 // add the index of everything it could point to, to "ptset". This may cause
316 // allocation - CheckCastPP of the allocation
317 bool split_AddP(Node *addp, Node *base, PhaseGVN *igvn);
318 PhiNode *create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *> &orig_phi_worklist, PhaseGVN *igvn, bool &new_created);
319 PhiNode *split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *> &orig_phi_worklist, PhaseGVN *igvn);
320 void move_inst_mem(Node* n, GrowableArray<PhiNode *> &orig_phis, PhaseGVN *igvn);
321 Node *find_inst_mem(Node *mem, int alias_idx,GrowableArray<PhiNode *> &orig_phi_worklist, PhaseGVN *igvn);
322
323 // Propagate unique types created for unescaped allocated objects
324 // through the graph
325 void split_unique_types(GrowableArray<Node *> &alloc_worklist);
326
327 // manage entries in _node_map
328 void set_map(int idx, Node *n) { _node_map.map(idx, n); }
329 Node *get_map(int idx) { return _node_map[idx]; }
330 PhiNode *get_map_phi(int idx) {
331 Node *phi = _node_map[idx];
332 return (phi == NULL) ? NULL : phi->as_Phi();
333 }
334
335 // Notify optimizer that a node has been modified
336 // Node: This assumes that escape analysis is run before
337 // PhaseIterGVN creation
338 void record_for_optimizer(Node *n) {
339 _igvn->_worklist.push(n);
340 }
341
342 // Set the escape state of a node
343 void set_escape_state(uint ni, PointsToNode::EscapeState es);
344
345 // Find fields initializing values for allocations.
346 void find_init_values(Node* n, VectorSet* visited, PhaseTransform* phase);
347
348 // Adjust escape state after Connection Graph is built.
349 void adjust_escape_state(Node* n);
350
351 // Propagate escape states to referenced nodes.
352 bool propagate_escape_state(GrowableArray<int>* cg_worklist,
353 GrowableArray<uint>* worklist,
354 PointsToNode::EscapeState esc_state);
355
356 // Optimize objects compare.
357 Node* optimize_ptr_compare(Node* n);
358
359 // Compute the escape information
|
143 UnknownEdge = 0,
144 PointsToEdge = 1,
145 DeferredEdge = 2,
146 FieldEdge = 3
147 } EdgeType;
148
149 private:
150 enum {
151 EdgeMask = 3,
152 EdgeShift = 2,
153
154 INITIAL_EDGE_COUNT = 4
155 };
156
157 NodeType _type;
158 EscapeState _escape;
159 GrowableArray<uint>* _edges; // outgoing edges
160 Node* _node; // Ideal node corresponding to this PointsTo node.
161 int _offset; // Object fields offsets.
162 bool _scalar_replaceable; // Not escaped object could be replaced with scalar
163 bool _has_unknown_ptr; // Has edge to phantom_object
164
165 public:
166 PointsToNode():
167 _type(UnknownType),
168 _escape(UnknownEscape),
169 _edges(NULL),
170 _node(NULL),
171 _offset(-1),
172 _has_unknown_ptr(false),
173 _scalar_replaceable(true) {}
174
175
176 EscapeState escape_state() const { return _escape; }
177 NodeType node_type() const { return _type;}
178 int offset() { return _offset;}
179 bool scalar_replaceable() { return _scalar_replaceable;}
180 bool has_unknown_ptr() { return _has_unknown_ptr;}
181
182 void set_offset(int offs) { _offset = offs;}
183 void set_escape_state(EscapeState state) { _escape = state; }
184 void set_node_type(NodeType ntype) {
185 assert(_type == UnknownType || _type == ntype, "Can't change node type");
186 _type = ntype;
187 }
188 void set_scalar_replaceable(bool v) { _scalar_replaceable = v; }
189 void set_has_unknown_ptr() { _has_unknown_ptr = true; }
190
191 // count of outgoing edges
192 uint edge_count() const { return (_edges == NULL) ? 0 : _edges->length(); }
193
194 // node index of target of outgoing edge "e"
195 uint edge_target(uint e) const {
196 assert(_edges != NULL, "valid edge index");
197 return (_edges->at(e) >> EdgeShift);
198 }
199 // type of outgoing edge "e"
200 EdgeType edge_type(uint e) const {
201 assert(_edges != NULL, "valid edge index");
202 return (EdgeType) (_edges->at(e) & EdgeMask);
203 }
204
205 // add a edge of the specified type pointing to the specified target
206 void add_edge(uint targIdx, EdgeType et);
207
208 // remove an edge of the specified type pointing to the specified target
209 void remove_edge(uint targIdx, EdgeType et);
237 uint _phantom_object; // Index of globally escaping object
238 // that pointer values loaded from
239 // a field which has not been set
240 // are assumed to point to.
241 uint _oop_null; // ConP(#NULL)->_idx
242 uint _noop_null; // ConN(#NULL)->_idx
243 Node* _pcmp_neq; // ConI(#CC_GT)
244 Node* _pcmp_eq; // ConI(#CC_EQ)
245
246 Compile * _compile; // Compile object for current compilation
247 PhaseIterGVN * _igvn; // Value numbering
248
249 // Address of an element in _nodes. Used when the element is to be modified
250 PointsToNode *ptnode_adr(uint idx) const {
251 // There should be no new ideal nodes during ConnectionGraph build,
252 // growableArray::adr_at() will throw assert otherwise.
253 return _nodes.adr_at(idx);
254 }
255 uint nodes_size() const { return _nodes.length(); }
256
257 bool is_null_ptr(uint idx) const { return (idx == _noop_null || idx == _oop_null); }
258
259 // Add node to ConnectionGraph.
260 void add_node(Node *n, PointsToNode::NodeType nt, PointsToNode::EscapeState es, bool done);
261
262 // offset of a field reference
263 int address_offset(Node* adr, PhaseTransform *phase);
264
265 // compute the escape state for arguments to a call
266 void process_call_arguments(CallNode *call, PhaseTransform *phase);
267
268 // compute the escape state for the return value of a call
269 void process_call_result(ProjNode *resproj, PhaseTransform *phase);
270
271 // Populate Connection Graph with Ideal nodes.
272 void record_for_escape_analysis(Node *n, PhaseTransform *phase);
273
274 // Build Connection Graph and set nodes escape state.
275 void build_connection_graph(Node *n, PhaseTransform *phase);
276
277 // walk the connection graph starting at the node corresponding to "n" and
278 // add the index of everything it could point to, to "ptset". This may cause
322 // allocation - CheckCastPP of the allocation
323 bool split_AddP(Node *addp, Node *base, PhaseGVN *igvn);
324 PhiNode *create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *> &orig_phi_worklist, PhaseGVN *igvn, bool &new_created);
325 PhiNode *split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *> &orig_phi_worklist, PhaseGVN *igvn);
326 void move_inst_mem(Node* n, GrowableArray<PhiNode *> &orig_phis, PhaseGVN *igvn);
327 Node *find_inst_mem(Node *mem, int alias_idx,GrowableArray<PhiNode *> &orig_phi_worklist, PhaseGVN *igvn);
328
329 // Propagate unique types created for unescaped allocated objects
330 // through the graph
331 void split_unique_types(GrowableArray<Node *> &alloc_worklist);
332
333 // manage entries in _node_map
334 void set_map(int idx, Node *n) { _node_map.map(idx, n); }
335 Node *get_map(int idx) { return _node_map[idx]; }
336 PhiNode *get_map_phi(int idx) {
337 Node *phi = _node_map[idx];
338 return (phi == NULL) ? NULL : phi->as_Phi();
339 }
340
341 // Notify optimizer that a node has been modified
342 void record_for_optimizer(Node *n) {
343 _igvn->_worklist.push(n);
344 _igvn->add_users_to_worklist(n);
345 }
346
347 // Set the escape state of a node
348 void set_escape_state(uint ni, PointsToNode::EscapeState es);
349
350 // Find fields initializing values for allocations.
351 void find_init_values(Node* n, VectorSet* visited, PhaseTransform* phase);
352
353 // Adjust escape state after Connection Graph is built.
354 void adjust_escape_state(Node* n);
355
356 // Propagate escape states to referenced nodes.
357 bool propagate_escape_state(GrowableArray<int>* cg_worklist,
358 GrowableArray<uint>* worklist,
359 PointsToNode::EscapeState esc_state);
360
361 // Optimize objects compare.
362 Node* optimize_ptr_compare(Node* n);
363
364 // Compute the escape information
|