comparison src/share/vm/opto/escape.cpp @ 244:524eca34ea76

6684714: Optimize EA Connection Graph build performance Summary: switch on EA by default, optimize Connection Graph construction Reviewed-by: rasbold, never
author kvn
date Thu, 03 Jul 2008 18:02:47 -0700
parents 1dd146f17531
children 4a4c365f777d
comparison
equal deleted inserted replaced
231:72c3e8693c9a 244:524eca34ea76
23 */ 23 */
24 24
25 #include "incls/_precompiled.incl" 25 #include "incls/_precompiled.incl"
26 #include "incls/_escape.cpp.incl" 26 #include "incls/_escape.cpp.incl"
27 27
28 uint PointsToNode::edge_target(uint e) const {
29 assert(_edges != NULL && e < (uint)_edges->length(), "valid edge index");
30 return (_edges->at(e) >> EdgeShift);
31 }
32
33 PointsToNode::EdgeType PointsToNode::edge_type(uint e) const {
34 assert(_edges != NULL && e < (uint)_edges->length(), "valid edge index");
35 return (EdgeType) (_edges->at(e) & EdgeMask);
36 }
37
38 void PointsToNode::add_edge(uint targIdx, PointsToNode::EdgeType et) { 28 void PointsToNode::add_edge(uint targIdx, PointsToNode::EdgeType et) {
39 uint v = (targIdx << EdgeShift) + ((uint) et); 29 uint v = (targIdx << EdgeShift) + ((uint) et);
40 if (_edges == NULL) { 30 if (_edges == NULL) {
41 Arena *a = Compile::current()->comp_arena(); 31 Arena *a = Compile::current()->comp_arena();
42 _edges = new(a) GrowableArray<uint>(a, INITIAL_EDGE_COUNT, 0, 0); 32 _edges = new(a) GrowableArray<uint>(a, INITIAL_EDGE_COUNT, 0, 0);
85 else 75 else
86 _node->dump(); 76 _node->dump();
87 } 77 }
88 #endif 78 #endif
89 79
90 ConnectionGraph::ConnectionGraph(Compile * C) : _processed(C->comp_arena()), _node_map(C->comp_arena()) { 80 ConnectionGraph::ConnectionGraph(Compile * C) :
91 _collecting = true; 81 _nodes(C->comp_arena(), C->unique(), C->unique(), PointsToNode()),
92 this->_compile = C; 82 _processed(C->comp_arena()),
93 const PointsToNode &dummy = PointsToNode(); 83 _collecting(true),
94 int sz = C->unique(); 84 _compile(C),
95 _nodes = new(C->comp_arena()) GrowableArray<PointsToNode>(C->comp_arena(), sz, sz, dummy); 85 _node_map(C->comp_arena()) {
86
96 _phantom_object = C->top()->_idx; 87 _phantom_object = C->top()->_idx;
97 PointsToNode *phn = ptnode_adr(_phantom_object); 88 PointsToNode *phn = ptnode_adr(_phantom_object);
98 phn->_node = C->top(); 89 phn->_node = C->top();
99 phn->set_node_type(PointsToNode::JavaObject); 90 phn->set_node_type(PointsToNode::JavaObject);
100 phn->set_escape_state(PointsToNode::GlobalEscape); 91 phn->set_escape_state(PointsToNode::GlobalEscape);
180 uint idx = n->_idx; 171 uint idx = n->_idx;
181 PointsToNode::EscapeState es; 172 PointsToNode::EscapeState es;
182 173
183 // If we are still collecting or there were no non-escaping allocations 174 // If we are still collecting or there were no non-escaping allocations
184 // we don't know the answer yet 175 // we don't know the answer yet
185 if (_collecting || !_has_allocations) 176 if (_collecting)
186 return PointsToNode::UnknownEscape; 177 return PointsToNode::UnknownEscape;
187 178
188 // if the node was created after the escape computation, return 179 // if the node was created after the escape computation, return
189 // UnknownEscape 180 // UnknownEscape
190 if (idx >= (uint)_nodes->length()) 181 if (idx >= nodes_size())
191 return PointsToNode::UnknownEscape; 182 return PointsToNode::UnknownEscape;
192 183
193 es = _nodes->at_grow(idx).escape_state(); 184 es = ptnode_adr(idx)->escape_state();
194 185
195 // if we have already computed a value, return it 186 // if we have already computed a value, return it
196 if (es != PointsToNode::UnknownEscape) 187 if (es != PointsToNode::UnknownEscape)
197 return es; 188 return es;
189
190 // PointsTo() calls n->uncast() which can return a new ideal node.
191 if (n->uncast()->_idx >= nodes_size())
192 return PointsToNode::UnknownEscape;
198 193
199 // compute max escape state of anything this node could point to 194 // compute max escape state of anything this node could point to
200 VectorSet ptset(Thread::current()->resource_area()); 195 VectorSet ptset(Thread::current()->resource_area());
201 PointsTo(ptset, n, phase); 196 PointsTo(ptset, n, phase);
202 for(VectorSetI i(&ptset); i.test() && es != PointsToNode::GlobalEscape; ++i) { 197 for(VectorSetI i(&ptset); i.test() && es != PointsToNode::GlobalEscape; ++i) {
203 uint pt = i.elem; 198 uint pt = i.elem;
204 PointsToNode::EscapeState pes = _nodes->adr_at(pt)->escape_state(); 199 PointsToNode::EscapeState pes = ptnode_adr(pt)->escape_state();
205 if (pes > es) 200 if (pes > es)
206 es = pes; 201 es = pes;
207 } 202 }
208 // cache the computed escape state 203 // cache the computed escape state
209 assert(es != PointsToNode::UnknownEscape, "should have computed an escape state"); 204 assert(es != PointsToNode::UnknownEscape, "should have computed an escape state");
210 _nodes->adr_at(idx)->set_escape_state(es); 205 ptnode_adr(idx)->set_escape_state(es);
211 return es; 206 return es;
212 } 207 }
213 208
214 void ConnectionGraph::PointsTo(VectorSet &ptset, Node * n, PhaseTransform *phase) { 209 void ConnectionGraph::PointsTo(VectorSet &ptset, Node * n, PhaseTransform *phase) {
215 VectorSet visited(Thread::current()->resource_area()); 210 VectorSet visited(Thread::current()->resource_area());
218 #ifdef ASSERT 213 #ifdef ASSERT
219 Node *orig_n = n; 214 Node *orig_n = n;
220 #endif 215 #endif
221 216
222 n = n->uncast(); 217 n = n->uncast();
223 PointsToNode npt = _nodes->at_grow(n->_idx); 218 PointsToNode* npt = ptnode_adr(n->_idx);
224 219
225 // If we have a JavaObject, return just that object 220 // If we have a JavaObject, return just that object
226 if (npt.node_type() == PointsToNode::JavaObject) { 221 if (npt->node_type() == PointsToNode::JavaObject) {
227 ptset.set(n->_idx); 222 ptset.set(n->_idx);
228 return; 223 return;
229 } 224 }
230 #ifdef ASSERT 225 #ifdef ASSERT
231 if (npt._node == NULL) { 226 if (npt->_node == NULL) {
232 if (orig_n != n) 227 if (orig_n != n)
233 orig_n->dump(); 228 orig_n->dump();
234 n->dump(); 229 n->dump();
235 assert(npt._node != NULL, "unregistered node"); 230 assert(npt->_node != NULL, "unregistered node");
236 } 231 }
237 #endif 232 #endif
238 worklist.push(n->_idx); 233 worklist.push(n->_idx);
239 while(worklist.length() > 0) { 234 while(worklist.length() > 0) {
240 int ni = worklist.pop(); 235 int ni = worklist.pop();
241 PointsToNode pn = _nodes->at_grow(ni); 236 if (visited.test_set(ni))
242 if (!visited.test_set(ni)) { 237 continue;
243 // ensure that all inputs of a Phi have been processed 238
244 assert(!_collecting || !pn._node->is_Phi() || _processed.test(ni),""); 239 PointsToNode* pn = ptnode_adr(ni);
245 240 // ensure that all inputs of a Phi have been processed
246 int edges_processed = 0; 241 assert(!_collecting || !pn->_node->is_Phi() || _processed.test(ni),"");
247 for (uint e = 0; e < pn.edge_count(); e++) { 242
248 uint etgt = pn.edge_target(e); 243 int edges_processed = 0;
249 PointsToNode::EdgeType et = pn.edge_type(e); 244 uint e_cnt = pn->edge_count();
250 if (et == PointsToNode::PointsToEdge) { 245 for (uint e = 0; e < e_cnt; e++) {
251 ptset.set(etgt); 246 uint etgt = pn->edge_target(e);
252 edges_processed++; 247 PointsToNode::EdgeType et = pn->edge_type(e);
253 } else if (et == PointsToNode::DeferredEdge) { 248 if (et == PointsToNode::PointsToEdge) {
254 worklist.push(etgt); 249 ptset.set(etgt);
255 edges_processed++; 250 edges_processed++;
256 } else { 251 } else if (et == PointsToNode::DeferredEdge) {
257 assert(false,"neither PointsToEdge or DeferredEdge"); 252 worklist.push(etgt);
258 } 253 edges_processed++;
259 } 254 } else {
260 if (edges_processed == 0) { 255 assert(false,"neither PointsToEdge or DeferredEdge");
261 // no deferred or pointsto edges found. Assume the value was set 256 }
262 // outside this method. Add the phantom object to the pointsto set. 257 }
263 ptset.set(_phantom_object); 258 if (edges_processed == 0) {
264 } 259 // no deferred or pointsto edges found. Assume the value was set
260 // outside this method. Add the phantom object to the pointsto set.
261 ptset.set(_phantom_object);
265 } 262 }
266 } 263 }
267 } 264 }
268 265
269 void ConnectionGraph::remove_deferred(uint ni, GrowableArray<uint>* deferred_edges, VectorSet* visited) { 266 void ConnectionGraph::remove_deferred(uint ni, GrowableArray<uint>* deferred_edges, VectorSet* visited) {
270 // This method is most expensive during ConnectionGraph construction. 267 // This method is most expensive during ConnectionGraph construction.
271 // Reuse vectorSet and an additional growable array for deferred edges. 268 // Reuse vectorSet and an additional growable array for deferred edges.
272 deferred_edges->clear(); 269 deferred_edges->clear();
273 visited->Clear(); 270 visited->Clear();
274 271
275 uint i = 0; 272 visited->set(ni);
276 PointsToNode *ptn = ptnode_adr(ni); 273 PointsToNode *ptn = ptnode_adr(ni);
277 274
278 // Mark current edges as visited and move deferred edges to separate array. 275 // Mark current edges as visited and move deferred edges to separate array.
279 while (i < ptn->edge_count()) { 276 for (uint i = 0; i < ptn->edge_count(); ) {
280 uint t = ptn->edge_target(i); 277 uint t = ptn->edge_target(i);
281 #ifdef ASSERT 278 #ifdef ASSERT
282 assert(!visited->test_set(t), "expecting no duplications"); 279 assert(!visited->test_set(t), "expecting no duplications");
283 #else 280 #else
284 visited->set(t); 281 visited->set(t);
291 } 288 }
292 } 289 }
293 for (int next = 0; next < deferred_edges->length(); ++next) { 290 for (int next = 0; next < deferred_edges->length(); ++next) {
294 uint t = deferred_edges->at(next); 291 uint t = deferred_edges->at(next);
295 PointsToNode *ptt = ptnode_adr(t); 292 PointsToNode *ptt = ptnode_adr(t);
296 for (uint j = 0; j < ptt->edge_count(); j++) { 293 uint e_cnt = ptt->edge_count();
297 uint n1 = ptt->edge_target(j); 294 for (uint e = 0; e < e_cnt; e++) {
298 if (visited->test_set(n1)) 295 uint etgt = ptt->edge_target(e);
296 if (visited->test_set(etgt))
299 continue; 297 continue;
300 switch(ptt->edge_type(j)) { 298
301 case PointsToNode::PointsToEdge: 299 PointsToNode::EdgeType et = ptt->edge_type(e);
302 add_pointsto_edge(ni, n1); 300 if (et == PointsToNode::PointsToEdge) {
303 if(n1 == _phantom_object) { 301 add_pointsto_edge(ni, etgt);
304 // Special case - field set outside (globally escaping). 302 if(etgt == _phantom_object) {
305 ptn->set_escape_state(PointsToNode::GlobalEscape); 303 // Special case - field set outside (globally escaping).
306 } 304 ptn->set_escape_state(PointsToNode::GlobalEscape);
307 break; 305 }
308 case PointsToNode::DeferredEdge: 306 } else if (et == PointsToNode::DeferredEdge) {
309 deferred_edges->append(n1); 307 deferred_edges->append(etgt);
310 break; 308 } else {
311 case PointsToNode::FieldEdge: 309 assert(false,"invalid connection graph");
312 assert(false, "invalid connection graph");
313 break;
314 } 310 }
315 } 311 }
316 } 312 }
317 } 313 }
318 314
320 // Add an edge to node given by "to_i" from any field of adr_i whose offset 316 // Add an edge to node given by "to_i" from any field of adr_i whose offset
321 // matches "offset" A deferred edge is added if to_i is a LocalVar, and 317 // matches "offset" A deferred edge is added if to_i is a LocalVar, and
322 // a pointsto edge is added if it is a JavaObject 318 // a pointsto edge is added if it is a JavaObject
323 319
324 void ConnectionGraph::add_edge_from_fields(uint adr_i, uint to_i, int offs) { 320 void ConnectionGraph::add_edge_from_fields(uint adr_i, uint to_i, int offs) {
325 PointsToNode an = _nodes->at_grow(adr_i); 321 PointsToNode* an = ptnode_adr(adr_i);
326 PointsToNode to = _nodes->at_grow(to_i); 322 PointsToNode* to = ptnode_adr(to_i);
327 bool deferred = (to.node_type() == PointsToNode::LocalVar); 323 bool deferred = (to->node_type() == PointsToNode::LocalVar);
328 324
329 for (uint fe = 0; fe < an.edge_count(); fe++) { 325 for (uint fe = 0; fe < an->edge_count(); fe++) {
330 assert(an.edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge"); 326 assert(an->edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge");
331 int fi = an.edge_target(fe); 327 int fi = an->edge_target(fe);
332 PointsToNode pf = _nodes->at_grow(fi); 328 PointsToNode* pf = ptnode_adr(fi);
333 int po = pf.offset(); 329 int po = pf->offset();
334 if (po == offs || po == Type::OffsetBot || offs == Type::OffsetBot) { 330 if (po == offs || po == Type::OffsetBot || offs == Type::OffsetBot) {
335 if (deferred) 331 if (deferred)
336 add_deferred_edge(fi, to_i); 332 add_deferred_edge(fi, to_i);
337 else 333 else
338 add_pointsto_edge(fi, to_i); 334 add_pointsto_edge(fi, to_i);
341 } 337 }
342 338
343 // Add a deferred edge from node given by "from_i" to any field of adr_i 339 // Add a deferred edge from node given by "from_i" to any field of adr_i
344 // whose offset matches "offset". 340 // whose offset matches "offset".
345 void ConnectionGraph::add_deferred_edge_to_fields(uint from_i, uint adr_i, int offs) { 341 void ConnectionGraph::add_deferred_edge_to_fields(uint from_i, uint adr_i, int offs) {
346 PointsToNode an = _nodes->at_grow(adr_i); 342 PointsToNode* an = ptnode_adr(adr_i);
347 for (uint fe = 0; fe < an.edge_count(); fe++) { 343 for (uint fe = 0; fe < an->edge_count(); fe++) {
348 assert(an.edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge"); 344 assert(an->edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge");
349 int fi = an.edge_target(fe); 345 int fi = an->edge_target(fe);
350 PointsToNode pf = _nodes->at_grow(fi); 346 PointsToNode* pf = ptnode_adr(fi);
351 int po = pf.offset(); 347 int po = pf->offset();
352 if (pf.edge_count() == 0) { 348 if (pf->edge_count() == 0) {
353 // we have not seen any stores to this field, assume it was set outside this method 349 // we have not seen any stores to this field, assume it was set outside this method
354 add_pointsto_edge(fi, _phantom_object); 350 add_pointsto_edge(fi, _phantom_object);
355 } 351 }
356 if (po == offs || po == Type::OffsetBot || offs == Type::OffsetBot) { 352 if (po == offs || po == Type::OffsetBot || offs == Type::OffsetBot) {
357 add_deferred_edge(from_i, fi); 353 add_deferred_edge(from_i, fi);
833 VectorSet ptset(Thread::current()->resource_area()); 829 VectorSet ptset(Thread::current()->resource_area());
834 830
835 831
836 // Phase 1: Process possible allocations from alloc_worklist. 832 // Phase 1: Process possible allocations from alloc_worklist.
837 // Create instance types for the CheckCastPP for allocations where possible. 833 // Create instance types for the CheckCastPP for allocations where possible.
834 //
835 // (Note: don't forget to change the order of the second AddP node on
836 // the alloc_worklist if the order of the worklist processing is changed,
837 // see the comment in find_second_addp().)
838 //
838 while (alloc_worklist.length() != 0) { 839 while (alloc_worklist.length() != 0) {
839 Node *n = alloc_worklist.pop(); 840 Node *n = alloc_worklist.pop();
840 uint ni = n->_idx; 841 uint ni = n->_idx;
841 const TypeOopPtr* tinst = NULL; 842 const TypeOopPtr* tinst = NULL;
842 if (n->is_Call()) { 843 if (n->is_Call()) {
843 CallNode *alloc = n->as_Call(); 844 CallNode *alloc = n->as_Call();
844 // copy escape information to call node 845 // copy escape information to call node
845 PointsToNode* ptn = _nodes->adr_at(alloc->_idx); 846 PointsToNode* ptn = ptnode_adr(alloc->_idx);
846 PointsToNode::EscapeState es = escape_state(alloc, igvn); 847 PointsToNode::EscapeState es = escape_state(alloc, igvn);
847 // We have an allocation or call which returns a Java object, 848 // We have an allocation or call which returns a Java object,
848 // see if it is unescaped. 849 // see if it is unescaped.
849 if (es != PointsToNode::NoEscape || !ptn->_scalar_replaceable) 850 if (es != PointsToNode::NoEscape || !ptn->_scalar_replaceable)
850 continue; 851 continue;
897 (t->isa_instptr() || t->isa_aryptr())) { 898 (t->isa_instptr() || t->isa_aryptr())) {
898 899
899 // First, put on the worklist all Field edges from Connection Graph 900 // First, put on the worklist all Field edges from Connection Graph
900 // which is more accurate then putting immediate users from Ideal Graph. 901 // which is more accurate then putting immediate users from Ideal Graph.
901 for (uint e = 0; e < ptn->edge_count(); e++) { 902 for (uint e = 0; e < ptn->edge_count(); e++) {
902 Node *use = _nodes->adr_at(ptn->edge_target(e))->_node; 903 Node *use = ptnode_adr(ptn->edge_target(e))->_node;
903 assert(ptn->edge_type(e) == PointsToNode::FieldEdge && use->is_AddP(), 904 assert(ptn->edge_type(e) == PointsToNode::FieldEdge && use->is_AddP(),
904 "only AddP nodes are Field edges in CG"); 905 "only AddP nodes are Field edges in CG");
905 if (use->outcnt() > 0) { // Don't process dead nodes 906 if (use->outcnt() > 0) { // Don't process dead nodes
906 Node* addp2 = find_second_addp(use, use->in(AddPNode::Base)); 907 Node* addp2 = find_second_addp(use, use->in(AddPNode::Base));
907 if (addp2 != NULL) { 908 if (addp2 != NULL) {
1060 if (_compile->failing()) { 1061 if (_compile->failing()) {
1061 return; 1062 return;
1062 } 1063 }
1063 if (mem != n->in(MemNode::Memory)) { 1064 if (mem != n->in(MemNode::Memory)) {
1064 set_map(n->_idx, mem); 1065 set_map(n->_idx, mem);
1065 _nodes->adr_at(n->_idx)->_node = n; 1066 ptnode_adr(n->_idx)->_node = n;
1066 } 1067 }
1067 if (n->is_Load()) { 1068 if (n->is_Load()) {
1068 continue; // don't push users 1069 continue; // don't push users
1069 } else if (n->is_LoadStore()) { 1070 } else if (n->is_LoadStore()) {
1070 // get the memory projection 1071 // get the memory projection
1221 record_for_optimizer(phi); 1222 record_for_optimizer(phi);
1222 } 1223 }
1223 1224
1224 // Update the memory inputs of MemNodes with the value we computed 1225 // Update the memory inputs of MemNodes with the value we computed
1225 // in Phase 2. 1226 // in Phase 2.
1226 for (int i = 0; i < _nodes->length(); i++) { 1227 for (uint i = 0; i < nodes_size(); i++) {
1227 Node *nmem = get_map(i); 1228 Node *nmem = get_map(i);
1228 if (nmem != NULL) { 1229 if (nmem != NULL) {
1229 Node *n = _nodes->adr_at(i)->_node; 1230 Node *n = ptnode_adr(i)->_node;
1230 if (n != NULL && n->is_Mem()) { 1231 if (n != NULL && n->is_Mem()) {
1231 igvn->hash_delete(n); 1232 igvn->hash_delete(n);
1232 n->set_req(MemNode::Memory, nmem); 1233 n->set_req(MemNode::Memory, nmem);
1233 igvn->hash_insert(n); 1234 igvn->hash_insert(n);
1234 record_for_optimizer(n); 1235 record_for_optimizer(n);
1235 } 1236 }
1236 } 1237 }
1237 } 1238 }
1238 } 1239 }
1239 1240
1240 void ConnectionGraph::compute_escape() { 1241 bool ConnectionGraph::has_candidates(Compile *C) {
1242 // EA brings benefits only when the code has allocations and/or locks which
1243 // are represented by ideal Macro nodes.
1244 int cnt = C->macro_count();
1245 for( int i=0; i < cnt; i++ ) {
1246 Node *n = C->macro_node(i);
1247 if ( n->is_Allocate() )
1248 return true;
1249 if( n->is_Lock() ) {
1250 Node* obj = n->as_Lock()->obj_node()->uncast();
1251 if( !(obj->is_Parm() || obj->is_Con()) )
1252 return true;
1253 }
1254 }
1255 return false;
1256 }
1257
1258 bool ConnectionGraph::compute_escape() {
1259 Compile* C = _compile;
1241 1260
1242 // 1. Populate Connection Graph (CG) with Ideal nodes. 1261 // 1. Populate Connection Graph (CG) with Ideal nodes.
1243 1262
1244 Unique_Node_List worklist_init; 1263 Unique_Node_List worklist_init;
1245 worklist_init.map(_compile->unique(), NULL); // preallocate space 1264 worklist_init.map(C->unique(), NULL); // preallocate space
1246 1265
1247 // Initialize worklist 1266 // Initialize worklist
1248 if (_compile->root() != NULL) { 1267 if (C->root() != NULL) {
1249 worklist_init.push(_compile->root()); 1268 worklist_init.push(C->root());
1250 } 1269 }
1251 1270
1252 GrowableArray<int> cg_worklist; 1271 GrowableArray<int> cg_worklist;
1253 PhaseGVN* igvn = _compile->initial_gvn(); 1272 PhaseGVN* igvn = C->initial_gvn();
1254 bool has_allocations = false; 1273 bool has_allocations = false;
1255 1274
1256 // Push all useful nodes onto CG list and set their type. 1275 // Push all useful nodes onto CG list and set their type.
1257 for( uint next = 0; next < worklist_init.size(); ++next ) { 1276 for( uint next = 0; next < worklist_init.size(); ++next ) {
1258 Node* n = worklist_init.at(next); 1277 Node* n = worklist_init.at(next);
1259 record_for_escape_analysis(n, igvn); 1278 record_for_escape_analysis(n, igvn);
1260 if (n->is_Call() && 1279 // Only allocations and java static calls results are checked
1261 _nodes->adr_at(n->_idx)->node_type() == PointsToNode::JavaObject) { 1280 // for an escape status. See process_call_result() below.
1281 if (n->is_Allocate() || n->is_CallStaticJava() &&
1282 ptnode_adr(n->_idx)->node_type() == PointsToNode::JavaObject) {
1262 has_allocations = true; 1283 has_allocations = true;
1263 } 1284 }
1264 if(n->is_AddP()) 1285 if(n->is_AddP())
1265 cg_worklist.append(n->_idx); 1286 cg_worklist.append(n->_idx);
1266 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { 1287 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
1267 Node* m = n->fast_out(i); // Get user 1288 Node* m = n->fast_out(i); // Get user
1268 worklist_init.push(m); 1289 worklist_init.push(m);
1269 } 1290 }
1270 } 1291 }
1271 1292
1272 if (has_allocations) { 1293 if (!has_allocations) {
1273 _has_allocations = true;
1274 } else {
1275 _has_allocations = false;
1276 _collecting = false; 1294 _collecting = false;
1277 return; // Nothing to do. 1295 return false; // Nothing to do.
1278 } 1296 }
1279 1297
1280 // 2. First pass to create simple CG edges (doesn't require to walk CG). 1298 // 2. First pass to create simple CG edges (doesn't require to walk CG).
1281 for( uint next = 0; next < _delayed_worklist.size(); ++next ) { 1299 uint delayed_size = _delayed_worklist.size();
1300 for( uint next = 0; next < delayed_size; ++next ) {
1282 Node* n = _delayed_worklist.at(next); 1301 Node* n = _delayed_worklist.at(next);
1283 build_connection_graph(n, igvn); 1302 build_connection_graph(n, igvn);
1284 } 1303 }
1285 1304
1286 // 3. Pass to create fields edges (Allocate -F-> AddP). 1305 // 3. Pass to create fields edges (Allocate -F-> AddP).
1287 for( int next = 0; next < cg_worklist.length(); ++next ) { 1306 uint cg_length = cg_worklist.length();
1307 for( uint next = 0; next < cg_length; ++next ) {
1288 int ni = cg_worklist.at(next); 1308 int ni = cg_worklist.at(next);
1289 build_connection_graph(_nodes->adr_at(ni)->_node, igvn); 1309 build_connection_graph(ptnode_adr(ni)->_node, igvn);
1290 } 1310 }
1291 1311
1292 cg_worklist.clear(); 1312 cg_worklist.clear();
1293 cg_worklist.append(_phantom_object); 1313 cg_worklist.append(_phantom_object);
1294 1314
1295 // 4. Build Connection Graph which need 1315 // 4. Build Connection Graph which need
1296 // to walk the connection graph. 1316 // to walk the connection graph.
1297 for (uint ni = 0; ni < (uint)_nodes->length(); ni++) { 1317 for (uint ni = 0; ni < nodes_size(); ni++) {
1298 PointsToNode* ptn = _nodes->adr_at(ni); 1318 PointsToNode* ptn = ptnode_adr(ni);
1299 Node *n = ptn->_node; 1319 Node *n = ptn->_node;
1300 if (n != NULL) { // Call, AddP, LoadP, StoreP 1320 if (n != NULL) { // Call, AddP, LoadP, StoreP
1301 build_connection_graph(n, igvn); 1321 build_connection_graph(n, igvn);
1302 if (ptn->node_type() != PointsToNode::UnknownType) 1322 if (ptn->node_type() != PointsToNode::UnknownType)
1303 cg_worklist.append(n->_idx); // Collect CG nodes 1323 cg_worklist.append(n->_idx); // Collect CG nodes
1304 } 1324 }
1305 } 1325 }
1306 1326
1307 VectorSet ptset(Thread::current()->resource_area()); 1327 VectorSet ptset(Thread::current()->resource_area());
1308 GrowableArray<Node*> alloc_worklist;
1309 GrowableArray<int> worklist;
1310 GrowableArray<uint> deferred_edges; 1328 GrowableArray<uint> deferred_edges;
1311 VectorSet visited(Thread::current()->resource_area()); 1329 VectorSet visited(Thread::current()->resource_area());
1312 1330
1313 // remove deferred edges from the graph and collect 1331 // 5. Remove deferred edges from the graph and collect
1314 // information we will need for type splitting 1332 // information needed for type splitting.
1315 for( int next = 0; next < cg_worklist.length(); ++next ) { 1333 cg_length = cg_worklist.length();
1334 for( uint next = 0; next < cg_length; ++next ) {
1316 int ni = cg_worklist.at(next); 1335 int ni = cg_worklist.at(next);
1317 PointsToNode* ptn = _nodes->adr_at(ni); 1336 PointsToNode* ptn = ptnode_adr(ni);
1318 PointsToNode::NodeType nt = ptn->node_type(); 1337 PointsToNode::NodeType nt = ptn->node_type();
1319 Node *n = ptn->_node;
1320 if (nt == PointsToNode::LocalVar || nt == PointsToNode::Field) { 1338 if (nt == PointsToNode::LocalVar || nt == PointsToNode::Field) {
1321 remove_deferred(ni, &deferred_edges, &visited); 1339 remove_deferred(ni, &deferred_edges, &visited);
1340 Node *n = ptn->_node;
1322 if (n->is_AddP()) { 1341 if (n->is_AddP()) {
1323 // If this AddP computes an address which may point to more that one 1342 // If this AddP computes an address which may point to more that one
1324 // object or more then one field (array's element), nothing the address 1343 // object or more then one field (array's element), nothing the address
1325 // points to can be scalar replaceable. 1344 // points to can be scalar replaceable.
1326 Node *base = get_addp_base(n); 1345 Node *base = get_addp_base(n);
1327 ptset.Clear(); 1346 ptset.Clear();
1328 PointsTo(ptset, base, igvn); 1347 PointsTo(ptset, base, igvn);
1329 if (ptset.Size() > 1 || 1348 if (ptset.Size() > 1 ||
1330 (ptset.Size() != 0 && ptn->offset() == Type::OffsetBot)) { 1349 (ptset.Size() != 0 && ptn->offset() == Type::OffsetBot)) {
1331 for( VectorSetI j(&ptset); j.test(); ++j ) { 1350 for( VectorSetI j(&ptset); j.test(); ++j ) {
1332 uint pt = j.elem; 1351 ptnode_adr(j.elem)->_scalar_replaceable = false;
1333 ptnode_adr(pt)->_scalar_replaceable = false;
1334 } 1352 }
1335 } 1353 }
1336 } 1354 }
1337 } else if (nt == PointsToNode::JavaObject && n->is_Call()) { 1355 }
1338 // Push call on alloc_worlist (alocations are calls) 1356 }
1339 // for processing by split_unique_types(). 1357
1340 alloc_worklist.append(n); 1358 // 6. Propagate escape states.
1341 } 1359 GrowableArray<int> worklist;
1342 } 1360 bool has_non_escaping_obj = false;
1343 1361
1344 // push all GlobalEscape nodes on the worklist 1362 // push all GlobalEscape nodes on the worklist
1345 for( int next = 0; next < cg_worklist.length(); ++next ) { 1363 for( uint next = 0; next < cg_length; ++next ) {
1346 int nk = cg_worklist.at(next); 1364 int nk = cg_worklist.at(next);
1347 if (_nodes->adr_at(nk)->escape_state() == PointsToNode::GlobalEscape) 1365 if (ptnode_adr(nk)->escape_state() == PointsToNode::GlobalEscape)
1348 worklist.append(nk); 1366 worklist.push(nk);
1349 } 1367 }
1350 // mark all node reachable from GlobalEscape nodes 1368 // mark all nodes reachable from GlobalEscape nodes
1351 while(worklist.length() > 0) { 1369 while(worklist.length() > 0) {
1352 PointsToNode n = _nodes->at(worklist.pop()); 1370 PointsToNode* ptn = ptnode_adr(worklist.pop());
1353 for (uint ei = 0; ei < n.edge_count(); ei++) { 1371 uint e_cnt = ptn->edge_count();
1354 uint npi = n.edge_target(ei); 1372 for (uint ei = 0; ei < e_cnt; ei++) {
1373 uint npi = ptn->edge_target(ei);
1355 PointsToNode *np = ptnode_adr(npi); 1374 PointsToNode *np = ptnode_adr(npi);
1356 if (np->escape_state() < PointsToNode::GlobalEscape) { 1375 if (np->escape_state() < PointsToNode::GlobalEscape) {
1357 np->set_escape_state(PointsToNode::GlobalEscape); 1376 np->set_escape_state(PointsToNode::GlobalEscape);
1358 worklist.append_if_missing(npi); 1377 worklist.push(npi);
1359 } 1378 }
1360 } 1379 }
1361 } 1380 }
1362 1381
1363 // push all ArgEscape nodes on the worklist 1382 // push all ArgEscape nodes on the worklist
1364 for( int next = 0; next < cg_worklist.length(); ++next ) { 1383 for( uint next = 0; next < cg_length; ++next ) {
1365 int nk = cg_worklist.at(next); 1384 int nk = cg_worklist.at(next);
1366 if (_nodes->adr_at(nk)->escape_state() == PointsToNode::ArgEscape) 1385 if (ptnode_adr(nk)->escape_state() == PointsToNode::ArgEscape)
1367 worklist.push(nk); 1386 worklist.push(nk);
1368 } 1387 }
1369 // mark all node reachable from ArgEscape nodes 1388 // mark all nodes reachable from ArgEscape nodes
1370 while(worklist.length() > 0) { 1389 while(worklist.length() > 0) {
1371 PointsToNode n = _nodes->at(worklist.pop()); 1390 PointsToNode* ptn = ptnode_adr(worklist.pop());
1372 for (uint ei = 0; ei < n.edge_count(); ei++) { 1391 if (ptn->node_type() == PointsToNode::JavaObject)
1373 uint npi = n.edge_target(ei); 1392 has_non_escaping_obj = true; // Non GlobalEscape
1393 uint e_cnt = ptn->edge_count();
1394 for (uint ei = 0; ei < e_cnt; ei++) {
1395 uint npi = ptn->edge_target(ei);
1374 PointsToNode *np = ptnode_adr(npi); 1396 PointsToNode *np = ptnode_adr(npi);
1375 if (np->escape_state() < PointsToNode::ArgEscape) { 1397 if (np->escape_state() < PointsToNode::ArgEscape) {
1376 np->set_escape_state(PointsToNode::ArgEscape); 1398 np->set_escape_state(PointsToNode::ArgEscape);
1377 worklist.append_if_missing(npi); 1399 worklist.push(npi);
1378 } 1400 }
1379 } 1401 }
1380 } 1402 }
1403
1404 GrowableArray<Node*> alloc_worklist;
1381 1405
1382 // push all NoEscape nodes on the worklist 1406 // push all NoEscape nodes on the worklist
1383 for( int next = 0; next < cg_worklist.length(); ++next ) { 1407 for( uint next = 0; next < cg_length; ++next ) {
1384 int nk = cg_worklist.at(next); 1408 int nk = cg_worklist.at(next);
1385 if (_nodes->adr_at(nk)->escape_state() == PointsToNode::NoEscape) 1409 if (ptnode_adr(nk)->escape_state() == PointsToNode::NoEscape)
1386 worklist.push(nk); 1410 worklist.push(nk);
1387 } 1411 }
1388 // mark all node reachable from NoEscape nodes 1412 // mark all nodes reachable from NoEscape nodes
1389 while(worklist.length() > 0) { 1413 while(worklist.length() > 0) {
1390 PointsToNode n = _nodes->at(worklist.pop()); 1414 PointsToNode* ptn = ptnode_adr(worklist.pop());
1391 for (uint ei = 0; ei < n.edge_count(); ei++) { 1415 if (ptn->node_type() == PointsToNode::JavaObject)
1392 uint npi = n.edge_target(ei); 1416 has_non_escaping_obj = true; // Non GlobalEscape
1417 Node* n = ptn->_node;
1418 if (n->is_Allocate() && ptn->_scalar_replaceable ) {
1419 // Push scalar replaceable alocations on alloc_worklist
1420 // for processing in split_unique_types().
1421 alloc_worklist.append(n);
1422 }
1423 uint e_cnt = ptn->edge_count();
1424 for (uint ei = 0; ei < e_cnt; ei++) {
1425 uint npi = ptn->edge_target(ei);
1393 PointsToNode *np = ptnode_adr(npi); 1426 PointsToNode *np = ptnode_adr(npi);
1394 if (np->escape_state() < PointsToNode::NoEscape) { 1427 if (np->escape_state() < PointsToNode::NoEscape) {
1395 np->set_escape_state(PointsToNode::NoEscape); 1428 np->set_escape_state(PointsToNode::NoEscape);
1396 worklist.append_if_missing(npi); 1429 worklist.push(npi);
1397 } 1430 }
1398 } 1431 }
1399 } 1432 }
1400 1433
1401 _collecting = false; 1434 _collecting = false;
1402 1435 assert(C->unique() == nodes_size(), "there should be no new ideal nodes during ConnectionGraph build");
1403 has_allocations = false; // Are there scalar replaceable allocations? 1436
1404 1437 bool has_scalar_replaceable_candidates = alloc_worklist.length() > 0;
1405 for( int next = 0; next < alloc_worklist.length(); ++next ) { 1438 if ( has_scalar_replaceable_candidates &&
1406 Node* n = alloc_worklist.at(next); 1439 C->AliasLevel() >= 3 && EliminateAllocations ) {
1407 uint ni = n->_idx; 1440
1408 PointsToNode* ptn = _nodes->adr_at(ni);
1409 PointsToNode::EscapeState es = ptn->escape_state();
1410 if (ptn->escape_state() == PointsToNode::NoEscape &&
1411 ptn->_scalar_replaceable) {
1412 has_allocations = true;
1413 break;
1414 }
1415 }
1416 if (!has_allocations) {
1417 return; // Nothing to do.
1418 }
1419
1420 if(_compile->AliasLevel() >= 3 && EliminateAllocations) {
1421 // Now use the escape information to create unique types for 1441 // Now use the escape information to create unique types for
1422 // unescaped objects 1442 // scalar replaceable objects.
1423 split_unique_types(alloc_worklist); 1443 split_unique_types(alloc_worklist);
1424 if (_compile->failing()) return; 1444
1445 if (C->failing()) return false;
1425 1446
1426 // Clean up after split unique types. 1447 // Clean up after split unique types.
1427 ResourceMark rm; 1448 ResourceMark rm;
1428 PhaseRemoveUseless pru(_compile->initial_gvn(), _compile->for_igvn()); 1449 PhaseRemoveUseless pru(C->initial_gvn(), C->for_igvn());
1450
1451 C->print_method("After Escape Analysis", 2);
1429 1452
1430 #ifdef ASSERT 1453 #ifdef ASSERT
1431 } else if (PrintEscapeAnalysis || PrintEliminateAllocations) { 1454 } else if (Verbose && (PrintEscapeAnalysis || PrintEliminateAllocations)) {
1432 tty->print("=== No allocations eliminated for "); 1455 tty->print("=== No allocations eliminated for ");
1433 C()->method()->print_short_name(); 1456 C->method()->print_short_name();
1434 if(!EliminateAllocations) { 1457 if(!EliminateAllocations) {
1435 tty->print(" since EliminateAllocations is off ==="); 1458 tty->print(" since EliminateAllocations is off ===");
1436 } else if(_compile->AliasLevel() < 3) { 1459 } else if(!has_scalar_replaceable_candidates) {
1460 tty->print(" since there are no scalar replaceable candidates ===");
1461 } else if(C->AliasLevel() < 3) {
1437 tty->print(" since AliasLevel < 3 ==="); 1462 tty->print(" since AliasLevel < 3 ===");
1438 } 1463 }
1439 tty->cr(); 1464 tty->cr();
1440 #endif 1465 #endif
1441 } 1466 }
1467 return has_non_escaping_obj;
1442 } 1468 }
1443 1469
1444 void ConnectionGraph::process_call_arguments(CallNode *call, PhaseTransform *phase) { 1470 void ConnectionGraph::process_call_arguments(CallNode *call, PhaseTransform *phase) {
1445 1471
1446 switch (call->Opcode()) { 1472 switch (call->Opcode()) {
1536 } 1562 }
1537 } 1563 }
1538 } 1564 }
1539 } 1565 }
1540 if (copy_dependencies) 1566 if (copy_dependencies)
1541 call_analyzer->copy_dependencies(C()->dependencies()); 1567 call_analyzer->copy_dependencies(_compile->dependencies());
1542 break; 1568 break;
1543 } 1569 }
1544 } 1570 }
1545 1571
1546 default: 1572 default:
1559 ptset.Clear(); 1585 ptset.Clear();
1560 PointsTo(ptset, arg, phase); 1586 PointsTo(ptset, arg, phase);
1561 for( VectorSetI j(&ptset); j.test(); ++j ) { 1587 for( VectorSetI j(&ptset); j.test(); ++j ) {
1562 uint pt = j.elem; 1588 uint pt = j.elem;
1563 set_escape_state(pt, PointsToNode::GlobalEscape); 1589 set_escape_state(pt, PointsToNode::GlobalEscape);
1564 PointsToNode *ptadr = ptnode_adr(pt);
1565 } 1590 }
1566 } 1591 }
1567 } 1592 }
1568 } 1593 }
1569 } 1594 }
1570 } 1595 }
1571 void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *phase) { 1596 void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *phase) {
1572 PointsToNode *ptadr = ptnode_adr(resproj->_idx); 1597 CallNode *call = resproj->in(0)->as_Call();
1573 1598 uint call_idx = call->_idx;
1574 CallNode *call = resproj->in(0)->as_Call(); 1599 uint resproj_idx = resproj->_idx;
1600
1575 switch (call->Opcode()) { 1601 switch (call->Opcode()) {
1576 case Op_Allocate: 1602 case Op_Allocate:
1577 { 1603 {
1578 Node *k = call->in(AllocateNode::KlassNode); 1604 Node *k = call->in(AllocateNode::KlassNode);
1579 const TypeKlassPtr *kt; 1605 const TypeKlassPtr *kt;
1585 } 1611 }
1586 assert(kt != NULL, "TypeKlassPtr required."); 1612 assert(kt != NULL, "TypeKlassPtr required.");
1587 ciKlass* cik = kt->klass(); 1613 ciKlass* cik = kt->klass();
1588 ciInstanceKlass* ciik = cik->as_instance_klass(); 1614 ciInstanceKlass* ciik = cik->as_instance_klass();
1589 1615
1590 PointsToNode *ptadr = ptnode_adr(call->_idx);
1591 PointsToNode::EscapeState es; 1616 PointsToNode::EscapeState es;
1592 uint edge_to; 1617 uint edge_to;
1593 if (cik->is_subclass_of(_compile->env()->Thread_klass()) || ciik->has_finalizer()) { 1618 if (cik->is_subclass_of(_compile->env()->Thread_klass()) || ciik->has_finalizer()) {
1594 es = PointsToNode::GlobalEscape; 1619 es = PointsToNode::GlobalEscape;
1595 edge_to = _phantom_object; // Could not be worse 1620 edge_to = _phantom_object; // Could not be worse
1596 } else { 1621 } else {
1597 es = PointsToNode::NoEscape; 1622 es = PointsToNode::NoEscape;
1598 edge_to = call->_idx; 1623 edge_to = call_idx;
1599 } 1624 }
1600 set_escape_state(call->_idx, es); 1625 set_escape_state(call_idx, es);
1601 add_pointsto_edge(resproj->_idx, edge_to); 1626 add_pointsto_edge(resproj_idx, edge_to);
1602 _processed.set(resproj->_idx); 1627 _processed.set(resproj_idx);
1603 break; 1628 break;
1604 } 1629 }
1605 1630
1606 case Op_AllocateArray: 1631 case Op_AllocateArray:
1607 { 1632 {
1608 PointsToNode *ptadr = ptnode_adr(call->_idx);
1609 int length = call->in(AllocateNode::ALength)->find_int_con(-1); 1633 int length = call->in(AllocateNode::ALength)->find_int_con(-1);
1610 if (length < 0 || length > EliminateAllocationArraySizeLimit) { 1634 if (length < 0 || length > EliminateAllocationArraySizeLimit) {
1611 // Not scalar replaceable if the length is not constant or too big. 1635 // Not scalar replaceable if the length is not constant or too big.
1612 ptadr->_scalar_replaceable = false; 1636 ptnode_adr(call_idx)->_scalar_replaceable = false;
1613 } 1637 }
1614 set_escape_state(call->_idx, PointsToNode::NoEscape); 1638 set_escape_state(call_idx, PointsToNode::NoEscape);
1615 add_pointsto_edge(resproj->_idx, call->_idx); 1639 add_pointsto_edge(resproj_idx, call_idx);
1616 _processed.set(resproj->_idx); 1640 _processed.set(resproj_idx);
1617 break; 1641 break;
1618 } 1642 }
1619 1643
1620 case Op_CallStaticJava: 1644 case Op_CallStaticJava:
1621 // For a static call, we know exactly what method is being called. 1645 // For a static call, we know exactly what method is being called.
1629 ret_type = r->field_at(TypeFunc::Parms); 1653 ret_type = r->field_at(TypeFunc::Parms);
1630 1654
1631 // Note: we use isa_ptr() instead of isa_oopptr() here because the 1655 // Note: we use isa_ptr() instead of isa_oopptr() here because the
1632 // _multianewarray functions return a TypeRawPtr. 1656 // _multianewarray functions return a TypeRawPtr.
1633 if (ret_type == NULL || ret_type->isa_ptr() == NULL) { 1657 if (ret_type == NULL || ret_type->isa_ptr() == NULL) {
1634 _processed.set(resproj->_idx); 1658 _processed.set(resproj_idx);
1635 break; // doesn't return a pointer type 1659 break; // doesn't return a pointer type
1636 } 1660 }
1637 ciMethod *meth = call->as_CallJava()->method(); 1661 ciMethod *meth = call->as_CallJava()->method();
1638 const TypeTuple * d = call->tf()->domain(); 1662 const TypeTuple * d = call->tf()->domain();
1639 if (meth == NULL) { 1663 if (meth == NULL) {
1640 // not a Java method, assume global escape 1664 // not a Java method, assume global escape
1641 set_escape_state(call->_idx, PointsToNode::GlobalEscape); 1665 set_escape_state(call_idx, PointsToNode::GlobalEscape);
1642 if (resproj != NULL) 1666 add_pointsto_edge(resproj_idx, _phantom_object);
1643 add_pointsto_edge(resproj->_idx, _phantom_object);
1644 } else { 1667 } else {
1645 BCEscapeAnalyzer *call_analyzer = meth->get_bcea(); 1668 BCEscapeAnalyzer *call_analyzer = meth->get_bcea();
1646 VectorSet ptset(Thread::current()->resource_area());
1647 bool copy_dependencies = false; 1669 bool copy_dependencies = false;
1648 1670
1649 if (call_analyzer->is_return_allocated()) { 1671 if (call_analyzer->is_return_allocated()) {
1650 // Returns a newly allocated unescaped object, simply 1672 // Returns a newly allocated unescaped object, simply
1651 // update dependency information. 1673 // update dependency information.
1652 // Mark it as NoEscape so that objects referenced by 1674 // Mark it as NoEscape so that objects referenced by
1653 // it's fields will be marked as NoEscape at least. 1675 // it's fields will be marked as NoEscape at least.
1654 set_escape_state(call->_idx, PointsToNode::NoEscape); 1676 set_escape_state(call_idx, PointsToNode::NoEscape);
1655 if (resproj != NULL) 1677 add_pointsto_edge(resproj_idx, call_idx);
1656 add_pointsto_edge(resproj->_idx, call->_idx);
1657 copy_dependencies = true; 1678 copy_dependencies = true;
1658 } else if (call_analyzer->is_return_local() && resproj != NULL) { 1679 } else if (call_analyzer->is_return_local()) {
1659 // determine whether any arguments are returned 1680 // determine whether any arguments are returned
1660 set_escape_state(call->_idx, PointsToNode::NoEscape); 1681 set_escape_state(call_idx, PointsToNode::NoEscape);
1661 for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { 1682 for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
1662 const Type* at = d->field_at(i); 1683 const Type* at = d->field_at(i);
1663 1684
1664 if (at->isa_oopptr() != NULL) { 1685 if (at->isa_oopptr() != NULL) {
1665 Node *arg = call->in(i)->uncast(); 1686 Node *arg = call->in(i)->uncast();
1666 1687
1667 if (call_analyzer->is_arg_returned(i - TypeFunc::Parms)) { 1688 if (call_analyzer->is_arg_returned(i - TypeFunc::Parms)) {
1668 PointsToNode *arg_esp = _nodes->adr_at(arg->_idx); 1689 PointsToNode *arg_esp = ptnode_adr(arg->_idx);
1669 if (arg_esp->node_type() == PointsToNode::UnknownType) 1690 if (arg_esp->node_type() == PointsToNode::UnknownType)
1670 done = false; 1691 done = false;
1671 else if (arg_esp->node_type() == PointsToNode::JavaObject) 1692 else if (arg_esp->node_type() == PointsToNode::JavaObject)
1672 add_pointsto_edge(resproj->_idx, arg->_idx); 1693 add_pointsto_edge(resproj_idx, arg->_idx);
1673 else 1694 else
1674 add_deferred_edge(resproj->_idx, arg->_idx); 1695 add_deferred_edge(resproj_idx, arg->_idx);
1675 arg_esp->_hidden_alias = true; 1696 arg_esp->_hidden_alias = true;
1676 } 1697 }
1677 } 1698 }
1678 } 1699 }
1679 copy_dependencies = true; 1700 copy_dependencies = true;
1680 } else { 1701 } else {
1681 set_escape_state(call->_idx, PointsToNode::GlobalEscape); 1702 set_escape_state(call_idx, PointsToNode::GlobalEscape);
1682 if (resproj != NULL) 1703 add_pointsto_edge(resproj_idx, _phantom_object);
1683 add_pointsto_edge(resproj->_idx, _phantom_object);
1684 for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { 1704 for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
1685 const Type* at = d->field_at(i); 1705 const Type* at = d->field_at(i);
1686 if (at->isa_oopptr() != NULL) { 1706 if (at->isa_oopptr() != NULL) {
1687 Node *arg = call->in(i)->uncast(); 1707 Node *arg = call->in(i)->uncast();
1688 PointsToNode *arg_esp = _nodes->adr_at(arg->_idx); 1708 PointsToNode *arg_esp = ptnode_adr(arg->_idx);
1689 arg_esp->_hidden_alias = true; 1709 arg_esp->_hidden_alias = true;
1690 } 1710 }
1691 } 1711 }
1692 } 1712 }
1693 if (copy_dependencies) 1713 if (copy_dependencies)
1694 call_analyzer->copy_dependencies(C()->dependencies()); 1714 call_analyzer->copy_dependencies(_compile->dependencies());
1695 } 1715 }
1696 if (done) 1716 if (done)
1697 _processed.set(resproj->_idx); 1717 _processed.set(resproj_idx);
1698 break; 1718 break;
1699 } 1719 }
1700 1720
1701 default: 1721 default:
1702 // Some other type of call, assume the worst case that the 1722 // Some other type of call, assume the worst case that the
1707 const Type* ret_type = r->field_at(TypeFunc::Parms); 1727 const Type* ret_type = r->field_at(TypeFunc::Parms);
1708 1728
1709 // Note: we use isa_ptr() instead of isa_oopptr() here because the 1729 // Note: we use isa_ptr() instead of isa_oopptr() here because the
1710 // _multianewarray functions return a TypeRawPtr. 1730 // _multianewarray functions return a TypeRawPtr.
1711 if (ret_type->isa_ptr() != NULL) { 1731 if (ret_type->isa_ptr() != NULL) {
1712 PointsToNode *ptadr = ptnode_adr(call->_idx); 1732 set_escape_state(call_idx, PointsToNode::GlobalEscape);
1713 set_escape_state(call->_idx, PointsToNode::GlobalEscape); 1733 add_pointsto_edge(resproj_idx, _phantom_object);
1714 if (resproj != NULL) 1734 }
1715 add_pointsto_edge(resproj->_idx, _phantom_object); 1735 }
1716 } 1736 _processed.set(resproj_idx);
1717 }
1718 _processed.set(resproj->_idx);
1719 } 1737 }
1720 } 1738 }
1721 } 1739 }
1722 1740
1723 // Populate Connection Graph with Ideal nodes and create simple 1741 // Populate Connection Graph with Ideal nodes and create simple
1741 // Have to process call's arguments first. 1759 // Have to process call's arguments first.
1742 PointsToNode::NodeType nt = PointsToNode::UnknownType; 1760 PointsToNode::NodeType nt = PointsToNode::UnknownType;
1743 1761
1744 // Check if a call returns an object. 1762 // Check if a call returns an object.
1745 const TypeTuple *r = n->as_Call()->tf()->range(); 1763 const TypeTuple *r = n->as_Call()->tf()->range();
1746 if (r->cnt() > TypeFunc::Parms && 1764 if (n->is_CallStaticJava() && r->cnt() > TypeFunc::Parms &&
1747 n->as_Call()->proj_out(TypeFunc::Parms) != NULL) { 1765 n->as_Call()->proj_out(TypeFunc::Parms) != NULL) {
1748 // Note: use isa_ptr() instead of isa_oopptr() here because 1766 // Note: use isa_ptr() instead of isa_oopptr() here because
1749 // the _multianewarray functions return a TypeRawPtr. 1767 // the _multianewarray functions return a TypeRawPtr.
1750 if (r->field_at(TypeFunc::Parms)->isa_ptr() != NULL) { 1768 if (r->field_at(TypeFunc::Parms)->isa_ptr() != NULL) {
1751 nt = PointsToNode::JavaObject; 1769 nt = PointsToNode::JavaObject;
1774 case Op_EncodeP: 1792 case Op_EncodeP:
1775 case Op_DecodeN: 1793 case Op_DecodeN:
1776 { 1794 {
1777 add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false); 1795 add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false);
1778 int ti = n->in(1)->_idx; 1796 int ti = n->in(1)->_idx;
1779 PointsToNode::NodeType nt = _nodes->adr_at(ti)->node_type(); 1797 PointsToNode::NodeType nt = ptnode_adr(ti)->node_type();
1780 if (nt == PointsToNode::UnknownType) { 1798 if (nt == PointsToNode::UnknownType) {
1781 _delayed_worklist.push(n); // Process it later. 1799 _delayed_worklist.push(n); // Process it later.
1782 break; 1800 break;
1783 } else if (nt == PointsToNode::JavaObject) { 1801 } else if (nt == PointsToNode::JavaObject) {
1784 add_pointsto_edge(n->_idx, ti); 1802 add_pointsto_edge(n->_idx, ti);
1864 continue; // ignore NULL 1882 continue; // ignore NULL
1865 in = in->uncast(); 1883 in = in->uncast();
1866 if (in->is_top() || in == n) 1884 if (in->is_top() || in == n)
1867 continue; // ignore top or inputs which go back this node 1885 continue; // ignore top or inputs which go back this node
1868 int ti = in->_idx; 1886 int ti = in->_idx;
1869 PointsToNode::NodeType nt = _nodes->adr_at(ti)->node_type(); 1887 PointsToNode::NodeType nt = ptnode_adr(ti)->node_type();
1870 if (nt == PointsToNode::UnknownType) { 1888 if (nt == PointsToNode::UnknownType) {
1871 break; 1889 break;
1872 } else if (nt == PointsToNode::JavaObject) { 1890 } else if (nt == PointsToNode::JavaObject) {
1873 add_pointsto_edge(n->_idx, ti); 1891 add_pointsto_edge(n->_idx, ti);
1874 } else { 1892 } else {
1902 if( n->req() > TypeFunc::Parms && 1920 if( n->req() > TypeFunc::Parms &&
1903 phase->type(n->in(TypeFunc::Parms))->isa_oopptr() ) { 1921 phase->type(n->in(TypeFunc::Parms))->isa_oopptr() ) {
1904 // Treat Return value as LocalVar with GlobalEscape escape state. 1922 // Treat Return value as LocalVar with GlobalEscape escape state.
1905 add_node(n, PointsToNode::LocalVar, PointsToNode::GlobalEscape, false); 1923 add_node(n, PointsToNode::LocalVar, PointsToNode::GlobalEscape, false);
1906 int ti = n->in(TypeFunc::Parms)->_idx; 1924 int ti = n->in(TypeFunc::Parms)->_idx;
1907 PointsToNode::NodeType nt = _nodes->adr_at(ti)->node_type(); 1925 PointsToNode::NodeType nt = ptnode_adr(ti)->node_type();
1908 if (nt == PointsToNode::UnknownType) { 1926 if (nt == PointsToNode::UnknownType) {
1909 _delayed_worklist.push(n); // Process it later. 1927 _delayed_worklist.push(n); // Process it later.
1910 break; 1928 break;
1911 } else if (nt == PointsToNode::JavaObject) { 1929 } else if (nt == PointsToNode::JavaObject) {
1912 add_pointsto_edge(n->_idx, ti); 1930 add_pointsto_edge(n->_idx, ti);
1966 } 1984 }
1967 return; 1985 return;
1968 } 1986 }
1969 1987
1970 void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) { 1988 void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) {
1989 uint n_idx = n->_idx;
1990
1971 // Don't set processed bit for AddP, LoadP, StoreP since 1991 // Don't set processed bit for AddP, LoadP, StoreP since
1972 // they may need more then one pass to process. 1992 // they may need more then one pass to process.
1973 if (_processed.test(n->_idx)) 1993 if (_processed.test(n_idx))
1974 return; // No need to redefine node's state. 1994 return; // No need to redefine node's state.
1975
1976 PointsToNode *ptadr = ptnode_adr(n->_idx);
1977 1995
1978 if (n->is_Call()) { 1996 if (n->is_Call()) {
1979 CallNode *call = n->as_Call(); 1997 CallNode *call = n->as_Call();
1980 process_call_arguments(call, phase); 1998 process_call_arguments(call, phase);
1981 _processed.set(n->_idx); 1999 _processed.set(n_idx);
1982 return; 2000 return;
1983 } 2001 }
1984 2002
1985 switch (n->Opcode()) { 2003 switch (n->Opcode()) {
1986 case Op_AddP: 2004 case Op_AddP:
1989 // Create a field edge to this node from everything base could point to. 2007 // Create a field edge to this node from everything base could point to.
1990 VectorSet ptset(Thread::current()->resource_area()); 2008 VectorSet ptset(Thread::current()->resource_area());
1991 PointsTo(ptset, base, phase); 2009 PointsTo(ptset, base, phase);
1992 for( VectorSetI i(&ptset); i.test(); ++i ) { 2010 for( VectorSetI i(&ptset); i.test(); ++i ) {
1993 uint pt = i.elem; 2011 uint pt = i.elem;
1994 add_field_edge(pt, n->_idx, address_offset(n, phase)); 2012 add_field_edge(pt, n_idx, address_offset(n, phase));
1995 } 2013 }
1996 break; 2014 break;
1997 } 2015 }
1998 case Op_CastX2P: 2016 case Op_CastX2P:
1999 { 2017 {
2004 case Op_CheckCastPP: 2022 case Op_CheckCastPP:
2005 case Op_EncodeP: 2023 case Op_EncodeP:
2006 case Op_DecodeN: 2024 case Op_DecodeN:
2007 { 2025 {
2008 int ti = n->in(1)->_idx; 2026 int ti = n->in(1)->_idx;
2009 if (_nodes->adr_at(ti)->node_type() == PointsToNode::JavaObject) { 2027 if (ptnode_adr(ti)->node_type() == PointsToNode::JavaObject) {
2010 add_pointsto_edge(n->_idx, ti); 2028 add_pointsto_edge(n_idx, ti);
2011 } else { 2029 } else {
2012 add_deferred_edge(n->_idx, ti); 2030 add_deferred_edge(n_idx, ti);
2013 } 2031 }
2014 _processed.set(n->_idx); 2032 _processed.set(n_idx);
2015 break; 2033 break;
2016 } 2034 }
2017 case Op_ConP: 2035 case Op_ConP:
2018 { 2036 {
2019 assert(false, "Op_ConP"); 2037 assert(false, "Op_ConP");
2058 VectorSet ptset(Thread::current()->resource_area()); 2076 VectorSet ptset(Thread::current()->resource_area());
2059 PointsTo(ptset, adr_base, phase); 2077 PointsTo(ptset, adr_base, phase);
2060 int offset = address_offset(adr, phase); 2078 int offset = address_offset(adr, phase);
2061 for( VectorSetI i(&ptset); i.test(); ++i ) { 2079 for( VectorSetI i(&ptset); i.test(); ++i ) {
2062 uint pt = i.elem; 2080 uint pt = i.elem;
2063 add_deferred_edge_to_fields(n->_idx, pt, offset); 2081 add_deferred_edge_to_fields(n_idx, pt, offset);
2064 } 2082 }
2065 break; 2083 break;
2066 } 2084 }
2067 case Op_Parm: 2085 case Op_Parm:
2068 { 2086 {
2081 continue; // ignore NULL 2099 continue; // ignore NULL
2082 in = in->uncast(); 2100 in = in->uncast();
2083 if (in->is_top() || in == n) 2101 if (in->is_top() || in == n)
2084 continue; // ignore top or inputs which go back this node 2102 continue; // ignore top or inputs which go back this node
2085 int ti = in->_idx; 2103 int ti = in->_idx;
2086 if (_nodes->adr_at(in->_idx)->node_type() == PointsToNode::JavaObject) { 2104 if (ptnode_adr(in->_idx)->node_type() == PointsToNode::JavaObject) {
2087 add_pointsto_edge(n->_idx, ti); 2105 add_pointsto_edge(n_idx, ti);
2088 } else { 2106 } else {
2089 add_deferred_edge(n->_idx, ti); 2107 add_deferred_edge(n_idx, ti);
2090 } 2108 }
2091 } 2109 }
2092 _processed.set(n->_idx); 2110 _processed.set(n_idx);
2093 break; 2111 break;
2094 } 2112 }
2095 case Op_Proj: 2113 case Op_Proj:
2096 { 2114 {
2097 // we are only interested in the result projection from a call 2115 // we are only interested in the result projection from a call
2098 if (n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->is_Call() ) { 2116 if (n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->is_Call() ) {
2099 process_call_result(n->as_Proj(), phase); 2117 process_call_result(n->as_Proj(), phase);
2100 assert(_processed.test(n->_idx), "all call results should be processed"); 2118 assert(_processed.test(n_idx), "all call results should be processed");
2101 } else { 2119 } else {
2102 assert(false, "Op_Proj"); 2120 assert(false, "Op_Proj");
2103 } 2121 }
2104 break; 2122 break;
2105 } 2123 }
2110 !phase->type(n->in(TypeFunc::Parms))->isa_oopptr() ) { 2128 !phase->type(n->in(TypeFunc::Parms))->isa_oopptr() ) {
2111 assert(false, "Op_Return"); 2129 assert(false, "Op_Return");
2112 } 2130 }
2113 #endif 2131 #endif
2114 int ti = n->in(TypeFunc::Parms)->_idx; 2132 int ti = n->in(TypeFunc::Parms)->_idx;
2115 if (_nodes->adr_at(ti)->node_type() == PointsToNode::JavaObject) { 2133 if (ptnode_adr(ti)->node_type() == PointsToNode::JavaObject) {
2116 add_pointsto_edge(n->_idx, ti); 2134 add_pointsto_edge(n_idx, ti);
2117 } else { 2135 } else {
2118 add_deferred_edge(n->_idx, ti); 2136 add_deferred_edge(n_idx, ti);
2119 } 2137 }
2120 _processed.set(n->_idx); 2138 _processed.set(n_idx);
2121 break; 2139 break;
2122 } 2140 }
2123 case Op_StoreP: 2141 case Op_StoreP:
2124 case Op_StoreN: 2142 case Op_StoreN:
2125 case Op_StorePConditional: 2143 case Op_StorePConditional:
2160 #ifndef PRODUCT 2178 #ifndef PRODUCT
2161 void ConnectionGraph::dump() { 2179 void ConnectionGraph::dump() {
2162 PhaseGVN *igvn = _compile->initial_gvn(); 2180 PhaseGVN *igvn = _compile->initial_gvn();
2163 bool first = true; 2181 bool first = true;
2164 2182
2165 uint size = (uint)_nodes->length(); 2183 uint size = nodes_size();
2166 for (uint ni = 0; ni < size; ni++) { 2184 for (uint ni = 0; ni < size; ni++) {
2167 PointsToNode *ptn = _nodes->adr_at(ni); 2185 PointsToNode *ptn = ptnode_adr(ni);
2168 PointsToNode::NodeType ptn_type = ptn->node_type(); 2186 PointsToNode::NodeType ptn_type = ptn->node_type();
2169 2187
2170 if (ptn_type != PointsToNode::JavaObject || ptn->_node == NULL) 2188 if (ptn_type != PointsToNode::JavaObject || ptn->_node == NULL)
2171 continue; 2189 continue;
2172 PointsToNode::EscapeState es = escape_state(ptn->_node, igvn); 2190 PointsToNode::EscapeState es = escape_state(ptn->_node, igvn);
2173 if (ptn->_node->is_Allocate() && (es == PointsToNode::NoEscape || Verbose)) { 2191 if (ptn->_node->is_Allocate() && (es == PointsToNode::NoEscape || Verbose)) {
2174 if (first) { 2192 if (first) {
2175 tty->cr(); 2193 tty->cr();
2176 tty->print("======== Connection graph for "); 2194 tty->print("======== Connection graph for ");
2177 C()->method()->print_short_name(); 2195 _compile->method()->print_short_name();
2178 tty->cr(); 2196 tty->cr();
2179 first = false; 2197 first = false;
2180 } 2198 }
2181 tty->print("%6d ", ni); 2199 tty->print("%6d ", ni);
2182 ptn->dump(); 2200 ptn->dump();
2183 // Print all locals which reference this allocation 2201 // Print all locals which reference this allocation
2184 for (uint li = ni; li < size; li++) { 2202 for (uint li = ni; li < size; li++) {
2185 PointsToNode *ptn_loc = _nodes->adr_at(li); 2203 PointsToNode *ptn_loc = ptnode_adr(li);
2186 PointsToNode::NodeType ptn_loc_type = ptn_loc->node_type(); 2204 PointsToNode::NodeType ptn_loc_type = ptn_loc->node_type();
2187 if ( ptn_loc_type == PointsToNode::LocalVar && ptn_loc->_node != NULL && 2205 if ( ptn_loc_type == PointsToNode::LocalVar && ptn_loc->_node != NULL &&
2188 ptn_loc->edge_count() == 1 && ptn_loc->edge_target(0) == ni ) { 2206 ptn_loc->edge_count() == 1 && ptn_loc->edge_target(0) == ni ) {
2189 tty->print("%6d LocalVar [[%d]]", li, ni); 2207 tty->print("%6d LocalVar [[%d]]", li, ni);
2190 _nodes->adr_at(li)->_node->dump(); 2208 ptnode_adr(li)->_node->dump();
2191 } 2209 }
2192 } 2210 }
2193 if (Verbose) { 2211 if (Verbose) {
2194 // Print all fields which reference this allocation 2212 // Print all fields which reference this allocation
2195 for (uint i = 0; i < ptn->edge_count(); i++) { 2213 for (uint i = 0; i < ptn->edge_count(); i++) {
2196 uint ei = ptn->edge_target(i); 2214 uint ei = ptn->edge_target(i);
2197 tty->print("%6d Field [[%d]]", ei, ni); 2215 tty->print("%6d Field [[%d]]", ei, ni);
2198 _nodes->adr_at(ei)->_node->dump(); 2216 ptnode_adr(ei)->_node->dump();
2199 } 2217 }
2200 } 2218 }
2201 tty->cr(); 2219 tty->cr();
2202 } 2220 }
2203 } 2221 }