479 int offset = adr_t->offset();
480 int instance_id = adr_t->instance_id();
481
482 // Check if an appropriate value phi already exists.
483 Node* region = mem->in(0);
484 for (DUIterator_Fast kmax, k = region->fast_outs(kmax); k < kmax; k++) {
485 Node* phi = region->fast_out(k);
486 if (phi->is_Phi() && phi != mem &&
487 phi->as_Phi()->is_same_inst_field(phi_type, (int)mem->_idx, instance_id, alias_idx, offset)) {
488 return phi;
489 }
490 }
491 // Check if an appropriate new value phi already exists.
492 Node* new_phi = value_phis->find(mem->_idx);
493 if (new_phi != NULL)
494 return new_phi;
495
496 if (level <= 0) {
497 return NULL; // Give up: phi tree too deep
498 }
499 Node *start_mem = C->start()->proj_out(TypeFunc::Memory);
500 Node *alloc_mem = alloc->in(TypeFunc::Memory);
501
502 uint length = mem->req();
503 GrowableArray <Node *> values(length, length, NULL, false);
504
505 // create a new Phi for the value
506 PhiNode *phi = new PhiNode(mem->in(0), phi_type, NULL, mem->_idx, instance_id, alias_idx, offset);
507 transform_later(phi);
508 value_phis->push(phi, mem->_idx);
509
510 for (uint j = 1; j < length; j++) {
511 Node *in = mem->in(j);
512 if (in == NULL || in->is_top()) {
513 values.at_put(j, in);
514 } else {
515 Node *val = scan_mem_chain(in, alias_idx, offset, start_mem, alloc, &_igvn);
516 if (val == start_mem || val == alloc_mem) {
517 // hit a sentinel, return appropriate 0 value
518 values.at_put(j, _igvn.zerocon(ft));
519 continue;
559 }
560 // Set Phi's inputs
561 for (uint j = 1; j < length; j++) {
562 if (values.at(j) == mem) {
563 phi->init_req(j, phi);
564 } else {
565 phi->init_req(j, values.at(j));
566 }
567 }
568 return phi;
569 }
570
571 // Search the last value stored into the object's field.
572 Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, Node *sfpt_ctl, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, AllocateNode *alloc) {
573 assert(adr_t->is_known_instance_field(), "instance required");
574 int instance_id = adr_t->instance_id();
575 assert((uint)instance_id == alloc->_idx, "wrong allocation");
576
577 int alias_idx = C->get_alias_index(adr_t);
578 int offset = adr_t->offset();
579 Node *start_mem = C->start()->proj_out(TypeFunc::Memory);
580 Node *alloc_ctrl = alloc->in(TypeFunc::Control);
581 Node *alloc_mem = alloc->in(TypeFunc::Memory);
582 Arena *a = Thread::current()->resource_area();
583 VectorSet visited(a);
584
585
586 bool done = sfpt_mem == alloc_mem;
587 Node *mem = sfpt_mem;
588 while (!done) {
589 if (visited.test_set(mem->_idx)) {
590 return NULL; // found a loop, give up
591 }
592 mem = scan_mem_chain(mem, alias_idx, offset, start_mem, alloc, &_igvn);
593 if (mem == start_mem || mem == alloc_mem) {
594 done = true; // hit a sentinel, return appropriate 0 value
595 } else if (mem->is_Initialize()) {
596 mem = mem->as_Initialize()->find_captured_store(offset, type2aelembytes(ft), &_igvn);
597 if (mem == NULL) {
598 done = true; // Something go wrong.
599 } else if (mem->is_Store()) {
957 } else {
958 field_val = transform_later(new DecodeNNode(field_val, field_val->get_ptr_type()));
959 }
960 }
961 sfpt->add_req(field_val);
962 }
963 JVMState *jvms = sfpt->jvms();
964 jvms->set_endoff(sfpt->req());
965 // Now make a pass over the debug information replacing any references
966 // to the allocated object with "sobj"
967 int start = jvms->debug_start();
968 int end = jvms->debug_end();
969 sfpt->replace_edges_in_range(res, sobj, start, end);
970 _igvn._worklist.push(sfpt);
971 safepoints_done.append_if_missing(sfpt); // keep it for rollback
972 }
973 return true;
974 }
975
976 static void disconnect_projections(MultiNode* n, PhaseIterGVN& igvn) {
977 Node* ctl_proj = n->proj_out(TypeFunc::Control);
978 Node* mem_proj = n->proj_out(TypeFunc::Memory);
979 if (ctl_proj != NULL) {
980 igvn.replace_node(ctl_proj, n->in(0));
981 }
982 if (mem_proj != NULL) {
983 igvn.replace_node(mem_proj, n->in(TypeFunc::Memory));
984 }
985 }
986
987 // Process users of eliminated allocation.
988 void PhaseMacroExpand::process_users_of_allocation(CallNode *alloc) {
989 Node* res = alloc->result_cast();
990 if (res != NULL) {
991 for (DUIterator_Last jmin, j = res->last_outs(jmin); j >= jmin; ) {
992 Node *use = res->last_out(j);
993 uint oc1 = res->outcnt();
994
995 if (use->is_AddP()) {
996 for (DUIterator_Last kmin, k = use->last_outs(kmin); k >= kmin; ) {
997 Node *n = use->last_out(k);
998 uint oc2 = use->outcnt();
1069 //
1070 if (_resproj != NULL && _resproj->outcnt() != 0) {
1071 // First disconnect stores captured by Initialize node.
1072 // If Initialize node is eliminated first in the following code,
1073 // it will kill such stores and DUIterator_Last will assert.
1074 for (DUIterator_Fast jmax, j = _resproj->fast_outs(jmax); j < jmax; j++) {
1075 Node *use = _resproj->fast_out(j);
1076 if (use->is_AddP()) {
1077 // raw memory addresses used only by the initialization
1078 _igvn.replace_node(use, C->top());
1079 --j; --jmax;
1080 }
1081 }
1082 for (DUIterator_Last jmin, j = _resproj->last_outs(jmin); j >= jmin; ) {
1083 Node *use = _resproj->last_out(j);
1084 uint oc1 = _resproj->outcnt();
1085 if (use->is_Initialize()) {
1086 // Eliminate Initialize node.
1087 InitializeNode *init = use->as_Initialize();
1088 assert(init->outcnt() <= 2, "only a control and memory projection expected");
1089 Node *ctrl_proj = init->proj_out(TypeFunc::Control);
1090 if (ctrl_proj != NULL) {
1091 assert(init->in(TypeFunc::Control) == _fallthroughcatchproj, "allocation control projection");
1092 _igvn.replace_node(ctrl_proj, _fallthroughcatchproj);
1093 }
1094 Node *mem_proj = init->proj_out(TypeFunc::Memory);
1095 if (mem_proj != NULL) {
1096 Node *mem = init->in(TypeFunc::Memory);
1097 #ifdef ASSERT
1098 if (mem->is_MergeMem()) {
1099 assert(mem->in(TypeFunc::Memory) == _memproj_fallthrough, "allocation memory projection");
1100 } else {
1101 assert(mem == _memproj_fallthrough, "allocation memory projection");
1102 }
1103 #endif
1104 _igvn.replace_node(mem_proj, mem);
1105 }
1106 } else {
1107 assert(false, "only Initialize or AddP expected");
1108 }
1109 j -= (oc1 - _resproj->outcnt());
1110 }
1111 }
1112 if (_fallthroughcatchproj != NULL) {
1113 _igvn.replace_node(_fallthroughcatchproj, alloc->in(TypeFunc::Control));
1114 }
1181 }
1182 log->tail("eliminate_allocation");
1183 }
1184
1185 process_users_of_allocation(alloc);
1186
1187 #ifndef PRODUCT
1188 if (PrintEliminateAllocations) {
1189 if (alloc->is_AllocateArray())
1190 tty->print_cr("++++ Eliminated: %d AllocateArray", alloc->_idx);
1191 else
1192 tty->print_cr("++++ Eliminated: %d Allocate", alloc->_idx);
1193 }
1194 #endif
1195
1196 return true;
1197 }
1198
1199 bool PhaseMacroExpand::eliminate_boxing_node(CallStaticJavaNode *boxing) {
1200 // EA should remove all uses of non-escaping boxing node.
1201 if (!C->eliminate_boxing() || boxing->proj_out(TypeFunc::Parms) != NULL) {
1202 return false;
1203 }
1204
1205 assert(boxing->result_cast() == NULL, "unexpected boxing node result");
1206
1207 extract_call_projections(boxing);
1208
1209 const TypeTuple* r = boxing->tf()->range();
1210 assert(r->cnt() > TypeFunc::Parms, "sanity");
1211 const TypeInstPtr* t = r->field_at(TypeFunc::Parms)->isa_instptr();
1212 assert(t != NULL, "sanity");
1213
1214 CompileLog* log = C->log();
1215 if (log != NULL) {
1216 log->head("eliminate_boxing type='%d'",
1217 log->identify(t->klass()));
1218 JVMState* p = boxing->jvms();
1219 while (p != NULL) {
1220 log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
1221 p = p->caller();
1563 (init == NULL || !init->is_complete_with_arraycopy())) {
1564 if (init == NULL || init->req() < InitializeNode::RawStores) {
1565 // No InitializeNode or no stores captured by zeroing
1566 // elimination. Simply add the MemBarStoreStore after object
1567 // initialization.
1568 MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot);
1569 transform_later(mb);
1570
1571 mb->init_req(TypeFunc::Memory, fast_oop_rawmem);
1572 mb->init_req(TypeFunc::Control, fast_oop_ctrl);
1573 fast_oop_ctrl = new ProjNode(mb,TypeFunc::Control);
1574 transform_later(fast_oop_ctrl);
1575 fast_oop_rawmem = new ProjNode(mb,TypeFunc::Memory);
1576 transform_later(fast_oop_rawmem);
1577 } else {
1578 // Add the MemBarStoreStore after the InitializeNode so that
1579 // all stores performing the initialization that were moved
1580 // before the InitializeNode happen before the storestore
1581 // barrier.
1582
1583 Node* init_ctrl = init->proj_out(TypeFunc::Control);
1584 Node* init_mem = init->proj_out(TypeFunc::Memory);
1585
1586 MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot);
1587 transform_later(mb);
1588
1589 Node* ctrl = new ProjNode(init,TypeFunc::Control);
1590 transform_later(ctrl);
1591 Node* mem = new ProjNode(init,TypeFunc::Memory);
1592 transform_later(mem);
1593
1594 // The MemBarStoreStore depends on control and memory coming
1595 // from the InitializeNode
1596 mb->init_req(TypeFunc::Memory, mem);
1597 mb->init_req(TypeFunc::Control, ctrl);
1598
1599 ctrl = new ProjNode(mb,TypeFunc::Control);
1600 transform_later(ctrl);
1601 mem = new ProjNode(mb,TypeFunc::Memory);
1602 transform_later(mem);
1603
1604 // All nodes that depended on the InitializeNode for control
|
479 int offset = adr_t->offset();
480 int instance_id = adr_t->instance_id();
481
482 // Check if an appropriate value phi already exists.
483 Node* region = mem->in(0);
484 for (DUIterator_Fast kmax, k = region->fast_outs(kmax); k < kmax; k++) {
485 Node* phi = region->fast_out(k);
486 if (phi->is_Phi() && phi != mem &&
487 phi->as_Phi()->is_same_inst_field(phi_type, (int)mem->_idx, instance_id, alias_idx, offset)) {
488 return phi;
489 }
490 }
491 // Check if an appropriate new value phi already exists.
492 Node* new_phi = value_phis->find(mem->_idx);
493 if (new_phi != NULL)
494 return new_phi;
495
496 if (level <= 0) {
497 return NULL; // Give up: phi tree too deep
498 }
499 Node *start_mem = C->start()->proj_out_or_null(TypeFunc::Memory);
500 Node *alloc_mem = alloc->in(TypeFunc::Memory);
501
502 uint length = mem->req();
503 GrowableArray <Node *> values(length, length, NULL, false);
504
505 // create a new Phi for the value
506 PhiNode *phi = new PhiNode(mem->in(0), phi_type, NULL, mem->_idx, instance_id, alias_idx, offset);
507 transform_later(phi);
508 value_phis->push(phi, mem->_idx);
509
510 for (uint j = 1; j < length; j++) {
511 Node *in = mem->in(j);
512 if (in == NULL || in->is_top()) {
513 values.at_put(j, in);
514 } else {
515 Node *val = scan_mem_chain(in, alias_idx, offset, start_mem, alloc, &_igvn);
516 if (val == start_mem || val == alloc_mem) {
517 // hit a sentinel, return appropriate 0 value
518 values.at_put(j, _igvn.zerocon(ft));
519 continue;
559 }
560 // Set Phi's inputs
561 for (uint j = 1; j < length; j++) {
562 if (values.at(j) == mem) {
563 phi->init_req(j, phi);
564 } else {
565 phi->init_req(j, values.at(j));
566 }
567 }
568 return phi;
569 }
570
571 // Search the last value stored into the object's field.
572 Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, Node *sfpt_ctl, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, AllocateNode *alloc) {
573 assert(adr_t->is_known_instance_field(), "instance required");
574 int instance_id = adr_t->instance_id();
575 assert((uint)instance_id == alloc->_idx, "wrong allocation");
576
577 int alias_idx = C->get_alias_index(adr_t);
578 int offset = adr_t->offset();
579 Node *start_mem = C->start()->proj_out_or_null(TypeFunc::Memory);
580 Node *alloc_ctrl = alloc->in(TypeFunc::Control);
581 Node *alloc_mem = alloc->in(TypeFunc::Memory);
582 Arena *a = Thread::current()->resource_area();
583 VectorSet visited(a);
584
585
586 bool done = sfpt_mem == alloc_mem;
587 Node *mem = sfpt_mem;
588 while (!done) {
589 if (visited.test_set(mem->_idx)) {
590 return NULL; // found a loop, give up
591 }
592 mem = scan_mem_chain(mem, alias_idx, offset, start_mem, alloc, &_igvn);
593 if (mem == start_mem || mem == alloc_mem) {
594 done = true; // hit a sentinel, return appropriate 0 value
595 } else if (mem->is_Initialize()) {
596 mem = mem->as_Initialize()->find_captured_store(offset, type2aelembytes(ft), &_igvn);
597 if (mem == NULL) {
598 done = true; // Something go wrong.
599 } else if (mem->is_Store()) {
957 } else {
958 field_val = transform_later(new DecodeNNode(field_val, field_val->get_ptr_type()));
959 }
960 }
961 sfpt->add_req(field_val);
962 }
963 JVMState *jvms = sfpt->jvms();
964 jvms->set_endoff(sfpt->req());
965 // Now make a pass over the debug information replacing any references
966 // to the allocated object with "sobj"
967 int start = jvms->debug_start();
968 int end = jvms->debug_end();
969 sfpt->replace_edges_in_range(res, sobj, start, end);
970 _igvn._worklist.push(sfpt);
971 safepoints_done.append_if_missing(sfpt); // keep it for rollback
972 }
973 return true;
974 }
975
976 static void disconnect_projections(MultiNode* n, PhaseIterGVN& igvn) {
977 Node* ctl_proj = n->proj_out_or_null(TypeFunc::Control);
978 Node* mem_proj = n->proj_out_or_null(TypeFunc::Memory);
979 if (ctl_proj != NULL) {
980 igvn.replace_node(ctl_proj, n->in(0));
981 }
982 if (mem_proj != NULL) {
983 igvn.replace_node(mem_proj, n->in(TypeFunc::Memory));
984 }
985 }
986
987 // Process users of eliminated allocation.
988 void PhaseMacroExpand::process_users_of_allocation(CallNode *alloc) {
989 Node* res = alloc->result_cast();
990 if (res != NULL) {
991 for (DUIterator_Last jmin, j = res->last_outs(jmin); j >= jmin; ) {
992 Node *use = res->last_out(j);
993 uint oc1 = res->outcnt();
994
995 if (use->is_AddP()) {
996 for (DUIterator_Last kmin, k = use->last_outs(kmin); k >= kmin; ) {
997 Node *n = use->last_out(k);
998 uint oc2 = use->outcnt();
1069 //
1070 if (_resproj != NULL && _resproj->outcnt() != 0) {
1071 // First disconnect stores captured by Initialize node.
1072 // If Initialize node is eliminated first in the following code,
1073 // it will kill such stores and DUIterator_Last will assert.
1074 for (DUIterator_Fast jmax, j = _resproj->fast_outs(jmax); j < jmax; j++) {
1075 Node *use = _resproj->fast_out(j);
1076 if (use->is_AddP()) {
1077 // raw memory addresses used only by the initialization
1078 _igvn.replace_node(use, C->top());
1079 --j; --jmax;
1080 }
1081 }
1082 for (DUIterator_Last jmin, j = _resproj->last_outs(jmin); j >= jmin; ) {
1083 Node *use = _resproj->last_out(j);
1084 uint oc1 = _resproj->outcnt();
1085 if (use->is_Initialize()) {
1086 // Eliminate Initialize node.
1087 InitializeNode *init = use->as_Initialize();
1088 assert(init->outcnt() <= 2, "only a control and memory projection expected");
1089 Node *ctrl_proj = init->proj_out_or_null(TypeFunc::Control);
1090 if (ctrl_proj != NULL) {
1091 assert(init->in(TypeFunc::Control) == _fallthroughcatchproj, "allocation control projection");
1092 _igvn.replace_node(ctrl_proj, _fallthroughcatchproj);
1093 }
1094 Node *mem_proj = init->proj_out_or_null(TypeFunc::Memory);
1095 if (mem_proj != NULL) {
1096 Node *mem = init->in(TypeFunc::Memory);
1097 #ifdef ASSERT
1098 if (mem->is_MergeMem()) {
1099 assert(mem->in(TypeFunc::Memory) == _memproj_fallthrough, "allocation memory projection");
1100 } else {
1101 assert(mem == _memproj_fallthrough, "allocation memory projection");
1102 }
1103 #endif
1104 _igvn.replace_node(mem_proj, mem);
1105 }
1106 } else {
1107 assert(false, "only Initialize or AddP expected");
1108 }
1109 j -= (oc1 - _resproj->outcnt());
1110 }
1111 }
1112 if (_fallthroughcatchproj != NULL) {
1113 _igvn.replace_node(_fallthroughcatchproj, alloc->in(TypeFunc::Control));
1114 }
1181 }
1182 log->tail("eliminate_allocation");
1183 }
1184
1185 process_users_of_allocation(alloc);
1186
1187 #ifndef PRODUCT
1188 if (PrintEliminateAllocations) {
1189 if (alloc->is_AllocateArray())
1190 tty->print_cr("++++ Eliminated: %d AllocateArray", alloc->_idx);
1191 else
1192 tty->print_cr("++++ Eliminated: %d Allocate", alloc->_idx);
1193 }
1194 #endif
1195
1196 return true;
1197 }
1198
1199 bool PhaseMacroExpand::eliminate_boxing_node(CallStaticJavaNode *boxing) {
1200 // EA should remove all uses of non-escaping boxing node.
1201 if (!C->eliminate_boxing() || boxing->proj_out_or_null(TypeFunc::Parms) != NULL) {
1202 return false;
1203 }
1204
1205 assert(boxing->result_cast() == NULL, "unexpected boxing node result");
1206
1207 extract_call_projections(boxing);
1208
1209 const TypeTuple* r = boxing->tf()->range();
1210 assert(r->cnt() > TypeFunc::Parms, "sanity");
1211 const TypeInstPtr* t = r->field_at(TypeFunc::Parms)->isa_instptr();
1212 assert(t != NULL, "sanity");
1213
1214 CompileLog* log = C->log();
1215 if (log != NULL) {
1216 log->head("eliminate_boxing type='%d'",
1217 log->identify(t->klass()));
1218 JVMState* p = boxing->jvms();
1219 while (p != NULL) {
1220 log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method()));
1221 p = p->caller();
1563 (init == NULL || !init->is_complete_with_arraycopy())) {
1564 if (init == NULL || init->req() < InitializeNode::RawStores) {
1565 // No InitializeNode or no stores captured by zeroing
1566 // elimination. Simply add the MemBarStoreStore after object
1567 // initialization.
1568 MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot);
1569 transform_later(mb);
1570
1571 mb->init_req(TypeFunc::Memory, fast_oop_rawmem);
1572 mb->init_req(TypeFunc::Control, fast_oop_ctrl);
1573 fast_oop_ctrl = new ProjNode(mb,TypeFunc::Control);
1574 transform_later(fast_oop_ctrl);
1575 fast_oop_rawmem = new ProjNode(mb,TypeFunc::Memory);
1576 transform_later(fast_oop_rawmem);
1577 } else {
1578 // Add the MemBarStoreStore after the InitializeNode so that
1579 // all stores performing the initialization that were moved
1580 // before the InitializeNode happen before the storestore
1581 // barrier.
1582
1583 Node* init_ctrl = init->proj_out_or_null(TypeFunc::Control);
1584 Node* init_mem = init->proj_out_or_null(TypeFunc::Memory);
1585
1586 MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot);
1587 transform_later(mb);
1588
1589 Node* ctrl = new ProjNode(init,TypeFunc::Control);
1590 transform_later(ctrl);
1591 Node* mem = new ProjNode(init,TypeFunc::Memory);
1592 transform_later(mem);
1593
1594 // The MemBarStoreStore depends on control and memory coming
1595 // from the InitializeNode
1596 mb->init_req(TypeFunc::Memory, mem);
1597 mb->init_req(TypeFunc::Control, ctrl);
1598
1599 ctrl = new ProjNode(mb,TypeFunc::Control);
1600 transform_later(ctrl);
1601 mem = new ProjNode(mb,TypeFunc::Memory);
1602 transform_later(mem);
1603
1604 // All nodes that depended on the InitializeNode for control
|