comparison src/share/vm/opto/escape.cpp @ 253:b0fe4deeb9fb

6726999: nsk/stress/jck12a/jck12a010 assert(n != null,"Bad immediate dominator info.") Summary: Escape Analysis fixes. Reviewed-by: never, rasbold
author kvn
date Mon, 28 Jul 2008 17:12:52 -0700
parents 02a35ad4adf8
children c3e045194476
comparison
equal deleted inserted replaced
252:be7facf71163 253:b0fe4deeb9fb
60 "P", // PointsToEdge 60 "P", // PointsToEdge
61 "D", // DeferredEdge 61 "D", // DeferredEdge
62 "F" // FieldEdge 62 "F" // FieldEdge
63 }; 63 };
64 64
65 void PointsToNode::dump() const { 65 void PointsToNode::dump(bool print_state) const {
66 NodeType nt = node_type(); 66 NodeType nt = node_type();
67 EscapeState es = escape_state(); 67 tty->print("%s ", node_type_names[(int) nt]);
68 tty->print("%s %s %s [[", node_type_names[(int) nt], esc_names[(int) es], _scalar_replaceable ? "" : "NSR"); 68 if (print_state) {
69 EscapeState es = escape_state();
70 tty->print("%s %s ", esc_names[(int) es], _scalar_replaceable ? "":"NSR");
71 }
72 tty->print("[[");
69 for (uint i = 0; i < edge_count(); i++) { 73 for (uint i = 0; i < edge_count(); i++) {
70 tty->print(" %d%s", edge_target(i), edge_type_suffix[(int) edge_type(i)]); 74 tty->print(" %d%s", edge_target(i), edge_type_suffix[(int) edge_type(i)]);
71 } 75 }
72 tty->print("]] "); 76 tty->print("]] ");
73 if (_node == NULL) 77 if (_node == NULL)
82 _processed(C->comp_arena()), 86 _processed(C->comp_arena()),
83 _collecting(true), 87 _collecting(true),
84 _compile(C), 88 _compile(C),
85 _node_map(C->comp_arena()) { 89 _node_map(C->comp_arena()) {
86 90
87 _phantom_object = C->top()->_idx; 91 _phantom_object = C->top()->_idx,
88 PointsToNode *phn = ptnode_adr(_phantom_object); 92 add_node(C->top(), PointsToNode::JavaObject, PointsToNode::GlobalEscape,true);
89 phn->_node = C->top(); 93
90 phn->set_node_type(PointsToNode::JavaObject); 94 // Add ConP(#NULL) and ConN(#NULL) nodes.
91 phn->set_escape_state(PointsToNode::GlobalEscape); 95 PhaseGVN* igvn = C->initial_gvn();
96 Node* oop_null = igvn->zerocon(T_OBJECT);
97 _oop_null = oop_null->_idx;
98 assert(_oop_null < C->unique(), "should be created already");
99 add_node(oop_null, PointsToNode::JavaObject, PointsToNode::NoEscape, true);
100
101 if (UseCompressedOops) {
102 Node* noop_null = igvn->zerocon(T_NARROWOOP);
103 _noop_null = noop_null->_idx;
104 assert(_noop_null < C->unique(), "should be created already");
105 add_node(noop_null, PointsToNode::JavaObject, PointsToNode::NoEscape, true);
106 }
92 } 107 }
93 108
94 void ConnectionGraph::add_pointsto_edge(uint from_i, uint to_i) { 109 void ConnectionGraph::add_pointsto_edge(uint from_i, uint to_i) {
95 PointsToNode *f = ptnode_adr(from_i); 110 PointsToNode *f = ptnode_adr(from_i);
96 PointsToNode *t = ptnode_adr(to_i); 111 PointsToNode *t = ptnode_adr(to_i);
498 // for the instance type 513 // for the instance type
499 int alias_idx = _compile->get_alias_index(tinst); 514 int alias_idx = _compile->get_alias_index(tinst);
500 igvn->set_type(addp, tinst); 515 igvn->set_type(addp, tinst);
501 // record the allocation in the node map 516 // record the allocation in the node map
502 set_map(addp->_idx, get_map(base->_idx)); 517 set_map(addp->_idx, get_map(base->_idx));
503 // if the Address input is not the appropriate instance type 518
504 // (due to intervening casts,) insert a cast 519 // Set addp's Base and Address to 'base'.
505 Node *adr = addp->in(AddPNode::Address); 520 Node *abase = addp->in(AddPNode::Base);
506 const TypeOopPtr *atype = igvn->type(adr)->isa_oopptr(); 521 Node *adr = addp->in(AddPNode::Address);
507 if (atype != NULL && atype->instance_id() != inst_id) { 522 if (adr->is_Proj() && adr->in(0)->is_Allocate() &&
508 assert(!atype->is_known_instance(), "no conflicting instances"); 523 adr->in(0)->_idx == (uint)inst_id) {
509 const TypeOopPtr *new_atype = base_t->add_offset(atype->offset())->isa_oopptr(); 524 // Skip AddP cases #3 and #5.
510 Node *acast = new (_compile, 2) CastPPNode(adr, new_atype); 525 } else {
511 acast->set_req(0, adr->in(0)); 526 assert(!abase->is_top(), "sanity"); // AddP case #3
512 igvn->set_type(acast, new_atype); 527 if (abase != base) {
513 record_for_optimizer(acast); 528 igvn->hash_delete(addp);
514 Node *bcast = acast; 529 addp->set_req(AddPNode::Base, base);
515 Node *abase = addp->in(AddPNode::Base); 530 if (abase == adr) {
516 if (abase != adr) { 531 addp->set_req(AddPNode::Address, base);
517 bcast = new (_compile, 2) CastPPNode(abase, base_t); 532 } else {
518 bcast->set_req(0, abase->in(0)); 533 // AddP case #4 (adr is array's element offset AddP node)
519 igvn->set_type(bcast, base_t); 534 #ifdef ASSERT
520 record_for_optimizer(bcast); 535 const TypeOopPtr *atype = igvn->type(adr)->isa_oopptr();
521 } 536 assert(adr->is_AddP() && atype != NULL &&
522 igvn->hash_delete(addp); 537 atype->instance_id() == inst_id, "array's element offset should be processed first");
523 addp->set_req(AddPNode::Base, bcast); 538 #endif
524 addp->set_req(AddPNode::Address, acast); 539 }
525 igvn->hash_insert(addp); 540 igvn->hash_insert(addp);
541 }
526 } 542 }
527 // Put on IGVN worklist since at least addp's type was changed above. 543 // Put on IGVN worklist since at least addp's type was changed above.
528 record_for_optimizer(addp); 544 record_for_optimizer(addp);
529 } 545 }
530 546
658 if (orig_mem == NULL) 674 if (orig_mem == NULL)
659 return orig_mem; 675 return orig_mem;
660 Compile* C = phase->C; 676 Compile* C = phase->C;
661 const TypeOopPtr *tinst = C->get_adr_type(alias_idx)->isa_oopptr(); 677 const TypeOopPtr *tinst = C->get_adr_type(alias_idx)->isa_oopptr();
662 bool is_instance = (tinst != NULL) && tinst->is_known_instance(); 678 bool is_instance = (tinst != NULL) && tinst->is_known_instance();
679 Node *start_mem = C->start()->proj_out(TypeFunc::Memory);
663 Node *prev = NULL; 680 Node *prev = NULL;
664 Node *result = orig_mem; 681 Node *result = orig_mem;
665 while (prev != result) { 682 while (prev != result) {
666 prev = result; 683 prev = result;
684 if (result == start_mem)
685 break; // hit one of our sentinals
667 if (result->is_Mem()) { 686 if (result->is_Mem()) {
668 MemNode *mem = result->as_Mem(); 687 const Type *at = phase->type(result->in(MemNode::Address));
669 const Type *at = phase->type(mem->in(MemNode::Address));
670 if (at != Type::TOP) { 688 if (at != Type::TOP) {
671 assert (at->isa_ptr() != NULL, "pointer type required."); 689 assert (at->isa_ptr() != NULL, "pointer type required.");
672 int idx = C->get_alias_index(at->is_ptr()); 690 int idx = C->get_alias_index(at->is_ptr());
673 if (idx == alias_idx) 691 if (idx == alias_idx)
674 break; 692 break;
675 } 693 }
676 result = mem->in(MemNode::Memory); 694 result = result->in(MemNode::Memory);
677 } 695 }
678 if (!is_instance) 696 if (!is_instance)
679 continue; // don't search further for non-instance types 697 continue; // don't search further for non-instance types
680 // skip over a call which does not affect this memory slice 698 // skip over a call which does not affect this memory slice
681 if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) { 699 if (result->is_Proj() && result->as_Proj()->_con == TypeFunc::Memory) {
682 Node *proj_in = result->in(0); 700 Node *proj_in = result->in(0);
683 if (proj_in->is_Call()) { 701 if (proj_in->is_Allocate() && proj_in->_idx == (uint)tinst->instance_id()) {
702 break; // hit one of our sentinals
703 } else if (proj_in->is_Call()) {
684 CallNode *call = proj_in->as_Call(); 704 CallNode *call = proj_in->as_Call();
685 if (!call->may_modify(tinst, phase)) { 705 if (!call->may_modify(tinst, phase)) {
686 result = call->in(TypeFunc::Memory); 706 result = call->in(TypeFunc::Memory);
687 } 707 }
688 } else if (proj_in->is_Initialize()) { 708 } else if (proj_in->is_Initialize()) {
1004 memnode_worklist.append_if_missing(use); 1024 memnode_worklist.append_if_missing(use);
1005 } else if (use->is_Initialize()) { 1025 } else if (use->is_Initialize()) {
1006 memnode_worklist.append_if_missing(use); 1026 memnode_worklist.append_if_missing(use);
1007 } else if (use->is_MergeMem()) { 1027 } else if (use->is_MergeMem()) {
1008 mergemem_worklist.append_if_missing(use); 1028 mergemem_worklist.append_if_missing(use);
1009 } else if (use->is_Call() && tinst != NULL) { 1029 } else if (use->is_SafePoint() && tinst != NULL) {
1010 // Look for MergeMem nodes for calls which reference unique allocation 1030 // Look for MergeMem nodes for calls which reference unique allocation
1011 // (through CheckCastPP nodes) even for debug info. 1031 // (through CheckCastPP nodes) even for debug info.
1012 Node* m = use->in(TypeFunc::Memory); 1032 Node* m = use->in(TypeFunc::Memory);
1013 uint iid = tinst->instance_id(); 1033 uint iid = tinst->instance_id();
1014 while (m->is_Proj() && m->in(0)->is_Call() && 1034 while (m->is_Proj() && m->in(0)->is_SafePoint() &&
1015 m->in(0) != use && !m->in(0)->_idx != iid) { 1035 m->in(0) != use && !m->in(0)->_idx != iid) {
1016 m = m->in(0)->in(TypeFunc::Memory); 1036 m = m->in(0)->in(TypeFunc::Memory);
1017 } 1037 }
1018 if (m->is_MergeMem()) { 1038 if (m->is_MergeMem()) {
1019 mergemem_worklist.append_if_missing(m); 1039 mergemem_worklist.append_if_missing(m);
1346 PointsToNode::NodeType nt = ptn->node_type(); 1366 PointsToNode::NodeType nt = ptn->node_type();
1347 if (nt == PointsToNode::LocalVar || nt == PointsToNode::Field) { 1367 if (nt == PointsToNode::LocalVar || nt == PointsToNode::Field) {
1348 remove_deferred(ni, &deferred_edges, &visited); 1368 remove_deferred(ni, &deferred_edges, &visited);
1349 Node *n = ptn->_node; 1369 Node *n = ptn->_node;
1350 if (n->is_AddP()) { 1370 if (n->is_AddP()) {
1351 // If this AddP computes an address which may point to more that one 1371 // Search for objects which are not scalar replaceable.
1352 // object or more then one field (array's element), nothing the address 1372 // Mark their escape state as ArgEscape to propagate the state
1353 // points to can be scalar replaceable. 1373 // to referenced objects.
1374 // Note: currently there are no difference in compiler optimizations
1375 // for ArgEscape objects and NoEscape objects which are not
1376 // scalar replaceable.
1377
1378 int offset = ptn->offset();
1354 Node *base = get_addp_base(n); 1379 Node *base = get_addp_base(n);
1355 ptset.Clear(); 1380 ptset.Clear();
1356 PointsTo(ptset, base, igvn); 1381 PointsTo(ptset, base, igvn);
1357 if (ptset.Size() > 1 || 1382 int ptset_size = ptset.Size();
1358 (ptset.Size() != 0 && ptn->offset() == Type::OffsetBot)) { 1383
1384 // Check if a field's initializing value is recorded and add
1385 // a corresponding NULL field's value if it is not recorded.
1386 // Connection Graph does not record a default initialization by NULL
1387 // captured by Initialize node.
1388 //
1389 // Note: it will disable scalar replacement in some cases:
1390 //
1391 // Point p[] = new Point[1];
1392 // p[0] = new Point(); // Will be not scalar replaced
1393 //
1394 // but it will save us from incorrect optimizations in next cases:
1395 //
1396 // Point p[] = new Point[1];
1397 // if ( x ) p[0] = new Point(); // Will be not scalar replaced
1398 //
1399 // Without a control flow analysis we can't distinguish above cases.
1400 //
1401 if (offset != Type::OffsetBot && ptset_size == 1) {
1402 uint elem = ptset.getelem(); // Allocation node's index
1403 // It does not matter if it is not Allocation node since
1404 // only non-escaping allocations are scalar replaced.
1405 if (ptnode_adr(elem)->_node->is_Allocate() &&
1406 ptnode_adr(elem)->escape_state() == PointsToNode::NoEscape) {
1407 AllocateNode* alloc = ptnode_adr(elem)->_node->as_Allocate();
1408 InitializeNode* ini = alloc->initialization();
1409 Node* value = NULL;
1410 if (ini != NULL) {
1411 BasicType ft = UseCompressedOops ? T_NARROWOOP : T_OBJECT;
1412 Node* store = ini->find_captured_store(offset, type2aelembytes(ft), igvn);
1413 if (store != NULL && store->is_Store())
1414 value = store->in(MemNode::ValueIn);
1415 }
1416 if (value == NULL || value != ptnode_adr(value->_idx)->_node) {
1417 // A field's initializing value was not recorded. Add NULL.
1418 uint null_idx = UseCompressedOops ? _noop_null : _oop_null;
1419 add_pointsto_edge(ni, null_idx);
1420 }
1421 }
1422 }
1423
1424 // An object is not scalar replaceable if the field which may point
1425 // to it has unknown offset (unknown element of an array of objects).
1426 //
1427 if (offset == Type::OffsetBot) {
1428 uint e_cnt = ptn->edge_count();
1429 for (uint ei = 0; ei < e_cnt; ei++) {
1430 uint npi = ptn->edge_target(ei);
1431 set_escape_state(npi, PointsToNode::ArgEscape);
1432 ptnode_adr(npi)->_scalar_replaceable = false;
1433 }
1434 }
1435
1436 // Currently an object is not scalar replaceable if a LoadStore node
1437 // access its field since the field value is unknown after it.
1438 //
1439 bool has_LoadStore = false;
1440 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
1441 Node *use = n->fast_out(i);
1442 if (use->is_LoadStore()) {
1443 has_LoadStore = true;
1444 break;
1445 }
1446 }
1447 // An object is not scalar replaceable if the address points
1448 // to unknown field (unknown element for arrays, offset is OffsetBot).
1449 //
1450 // Or the address may point to more then one object. This may produce
1451 // the false positive result (set scalar_replaceable to false)
1452 // since the flow-insensitive escape analysis can't separate
1453 // the case when stores overwrite the field's value from the case
1454 // when stores happened on different control branches.
1455 //
1456 if (ptset_size > 1 || ptset_size != 0 &&
1457 (has_LoadStore || offset == Type::OffsetBot)) {
1359 for( VectorSetI j(&ptset); j.test(); ++j ) { 1458 for( VectorSetI j(&ptset); j.test(); ++j ) {
1459 set_escape_state(j.elem, PointsToNode::ArgEscape);
1360 ptnode_adr(j.elem)->_scalar_replaceable = false; 1460 ptnode_adr(j.elem)->_scalar_replaceable = false;
1361 } 1461 }
1362 } 1462 }
1363 } 1463 }
1364 } 1464 }
1853 } 1953 }
1854 case Op_LoadP: 1954 case Op_LoadP:
1855 case Op_LoadN: 1955 case Op_LoadN:
1856 { 1956 {
1857 const Type *t = phase->type(n); 1957 const Type *t = phase->type(n);
1858 if (!t->isa_narrowoop() && t->isa_ptr() == NULL) { 1958 if (t->make_ptr() == NULL) {
1859 _processed.set(n->_idx); 1959 _processed.set(n->_idx);
1860 return; 1960 return;
1861 } 1961 }
1862 add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false); 1962 add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false);
1863 break; 1963 break;
1876 add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, false); 1976 add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, false);
1877 break; 1977 break;
1878 } 1978 }
1879 case Op_Phi: 1979 case Op_Phi:
1880 { 1980 {
1881 if (n->as_Phi()->type()->isa_ptr() == NULL) { 1981 const Type *t = n->as_Phi()->type();
1882 // nothing to do if not an oop 1982 if (t->make_ptr() == NULL) {
1983 // nothing to do if not an oop or narrow oop
1883 _processed.set(n->_idx); 1984 _processed.set(n->_idx);
1884 return; 1985 return;
1885 } 1986 }
1886 add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false); 1987 add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false);
1887 uint i; 1988 uint i;
2065 case Op_LoadP: 2166 case Op_LoadP:
2066 case Op_LoadN: 2167 case Op_LoadN:
2067 { 2168 {
2068 const Type *t = phase->type(n); 2169 const Type *t = phase->type(n);
2069 #ifdef ASSERT 2170 #ifdef ASSERT
2070 if (!t->isa_narrowoop() && t->isa_ptr() == NULL) 2171 if (t->make_ptr() == NULL)
2071 assert(false, "Op_LoadP"); 2172 assert(false, "Op_LoadP");
2072 #endif 2173 #endif
2073 2174
2074 Node* adr = n->in(MemNode::Address)->uncast(); 2175 Node* adr = n->in(MemNode::Address)->uncast();
2075 const Type *adr_type = phase->type(adr); 2176 const Type *adr_type = phase->type(adr);
2097 break; 2198 break;
2098 } 2199 }
2099 case Op_Phi: 2200 case Op_Phi:
2100 { 2201 {
2101 #ifdef ASSERT 2202 #ifdef ASSERT
2102 if (n->as_Phi()->type()->isa_ptr() == NULL) 2203 const Type *t = n->as_Phi()->type();
2204 if (t->make_ptr() == NULL)
2103 assert(false, "Op_Phi"); 2205 assert(false, "Op_Phi");
2104 #endif 2206 #endif
2105 for (uint i = 1; i < n->req() ; i++) { 2207 for (uint i = 1; i < n->req() ; i++) {
2106 Node* in = n->in(i); 2208 Node* in = n->in(i);
2107 if (in == NULL) 2209 if (in == NULL)
2211 for (uint li = ni; li < size; li++) { 2313 for (uint li = ni; li < size; li++) {
2212 PointsToNode *ptn_loc = ptnode_adr(li); 2314 PointsToNode *ptn_loc = ptnode_adr(li);
2213 PointsToNode::NodeType ptn_loc_type = ptn_loc->node_type(); 2315 PointsToNode::NodeType ptn_loc_type = ptn_loc->node_type();
2214 if ( ptn_loc_type == PointsToNode::LocalVar && ptn_loc->_node != NULL && 2316 if ( ptn_loc_type == PointsToNode::LocalVar && ptn_loc->_node != NULL &&
2215 ptn_loc->edge_count() == 1 && ptn_loc->edge_target(0) == ni ) { 2317 ptn_loc->edge_count() == 1 && ptn_loc->edge_target(0) == ni ) {
2216 tty->print("%6d LocalVar [[%d]]", li, ni); 2318 ptnode_adr(li)->dump(false);
2217 ptnode_adr(li)->_node->dump();
2218 } 2319 }
2219 } 2320 }
2220 if (Verbose) { 2321 if (Verbose) {
2221 // Print all fields which reference this allocation 2322 // Print all fields which reference this allocation
2222 for (uint i = 0; i < ptn->edge_count(); i++) { 2323 for (uint i = 0; i < ptn->edge_count(); i++) {
2223 uint ei = ptn->edge_target(i); 2324 uint ei = ptn->edge_target(i);
2224 tty->print("%6d Field [[%d]]", ei, ni); 2325 ptnode_adr(ei)->dump(false);
2225 ptnode_adr(ei)->_node->dump();
2226 } 2326 }
2227 } 2327 }
2228 tty->cr(); 2328 tty->cr();
2229 } 2329 }
2230 } 2330 }