193 // add a edge of the specified type pointing to the specified target 194 void add_edge(uint targIdx, EdgeType et); 195 196 // remove an edge of the specified type pointing to the specified target 197 void remove_edge(uint targIdx, EdgeType et); 198 199 #ifndef PRODUCT 200 void dump(bool print_state=true) const; 201 #endif 202 203 }; 204 205 class ConnectionGraph: public ResourceObj { 206 private: 207 GrowableArray<PointsToNode> _nodes; // Connection graph nodes indexed 208 // by ideal node index. 209 210 Unique_Node_List _delayed_worklist; // Nodes to be processed before 211 // the call build_connection_graph(). 212 213 VectorSet _processed; // Records which nodes have been 214 // processed. 215 216 bool _collecting; // Indicates whether escape information 217 // is still being collected. If false, 218 // no new nodes will be processed. 219 220 uint _phantom_object; // Index of globally escaping object 221 // that pointer values loaded from 222 // a field which has not been set 223 // are assumed to point to. 224 uint _oop_null; // ConP(#NULL) 225 uint _noop_null; // ConN(#NULL) 226 227 Compile * _compile; // Compile object for current compilation 228 229 // Address of an element in _nodes. Used when the element is to be modified 230 PointsToNode *ptnode_adr(uint idx) const { 231 // There should be no new ideal nodes during ConnectionGraph build, 232 // growableArray::adr_at() will throw assert otherwise. 298 299 // manage entries in _node_map 300 void set_map(int idx, Node *n) { _node_map.map(idx, n); } 301 void set_map_phi(int idx, PhiNode *p) { _node_map.map(idx, (Node *) p); } 302 Node *get_map(int idx) { return _node_map[idx]; } 303 PhiNode *get_map_phi(int idx) { 304 Node *phi = _node_map[idx]; 305 return (phi == NULL) ? NULL : phi->as_Phi(); 306 } 307 308 // Notify optimizer that a node has been modified 309 // Node: This assumes that escape analysis is run before 310 // PhaseIterGVN creation 311 void record_for_optimizer(Node *n) { 312 _compile->record_for_igvn(n); 313 } 314 315 // Set the escape state of a node 316 void set_escape_state(uint ni, PointsToNode::EscapeState es); 317 318 public: 319 ConnectionGraph(Compile *C); 320 321 // Check for non-escaping candidates 322 static bool has_candidates(Compile *C); 323 324 // Compute the escape information 325 bool compute_escape(); 326 327 // escape state of a node 328 PointsToNode::EscapeState escape_state(Node *n, PhaseTransform *phase); 329 // other information we have collected 330 bool is_scalar_replaceable(Node *n) { 331 if (_collecting || (n->_idx >= nodes_size())) 332 return false; 333 PointsToNode* ptn = ptnode_adr(n->_idx); 334 return ptn->escape_state() == PointsToNode::NoEscape && ptn->_scalar_replaceable; 335 } 336 337 bool hidden_alias(Node *n) { | 193 // add a edge of the specified type pointing to the specified target 194 void add_edge(uint targIdx, EdgeType et); 195 196 // remove an edge of the specified type pointing to the specified target 197 void remove_edge(uint targIdx, EdgeType et); 198 199 #ifndef PRODUCT 200 void dump(bool print_state=true) const; 201 #endif 202 203 }; 204 205 class ConnectionGraph: public ResourceObj { 206 private: 207 GrowableArray<PointsToNode> _nodes; // Connection graph nodes indexed 208 // by ideal node index. 209 210 Unique_Node_List _delayed_worklist; // Nodes to be processed before 211 // the call build_connection_graph(). 212 213 GrowableArray<MergeMemNode *> _mergemem_worklist; // List of all MergeMem nodes 214 215 VectorSet _processed; // Records which nodes have been 216 // processed. 217 218 bool _collecting; // Indicates whether escape information 219 // is still being collected. If false, 220 // no new nodes will be processed. 221 222 uint _phantom_object; // Index of globally escaping object 223 // that pointer values loaded from 224 // a field which has not been set 225 // are assumed to point to. 226 uint _oop_null; // ConP(#NULL) 227 uint _noop_null; // ConN(#NULL) 228 229 Compile * _compile; // Compile object for current compilation 230 231 // Address of an element in _nodes. Used when the element is to be modified 232 PointsToNode *ptnode_adr(uint idx) const { 233 // There should be no new ideal nodes during ConnectionGraph build, 234 // growableArray::adr_at() will throw assert otherwise. 300 301 // manage entries in _node_map 302 void set_map(int idx, Node *n) { _node_map.map(idx, n); } 303 void set_map_phi(int idx, PhiNode *p) { _node_map.map(idx, (Node *) p); } 304 Node *get_map(int idx) { return _node_map[idx]; } 305 PhiNode *get_map_phi(int idx) { 306 Node *phi = _node_map[idx]; 307 return (phi == NULL) ? NULL : phi->as_Phi(); 308 } 309 310 // Notify optimizer that a node has been modified 311 // Node: This assumes that escape analysis is run before 312 // PhaseIterGVN creation 313 void record_for_optimizer(Node *n) { 314 _compile->record_for_igvn(n); 315 } 316 317 // Set the escape state of a node 318 void set_escape_state(uint ni, PointsToNode::EscapeState es); 319 320 // Search for objects which are not scalar replaceable. 321 void verify_escape_state(int nidx, VectorSet& ptset, PhaseTransform* phase); 322 323 public: 324 ConnectionGraph(Compile *C); 325 326 // Check for non-escaping candidates 327 static bool has_candidates(Compile *C); 328 329 // Compute the escape information 330 bool compute_escape(); 331 332 // escape state of a node 333 PointsToNode::EscapeState escape_state(Node *n, PhaseTransform *phase); 334 // other information we have collected 335 bool is_scalar_replaceable(Node *n) { 336 if (_collecting || (n->_idx >= nodes_size())) 337 return false; 338 PointsToNode* ptn = ptnode_adr(n->_idx); 339 return ptn->escape_state() == PointsToNode::NoEscape && ptn->_scalar_replaceable; 340 } 341 342 bool hidden_alias(Node *n) { |