< prev index next >

src/hotspot/share/opto/graphKit.cpp

Print this page

        

*** 1389,1399 **** ld = LoadNode::make(_gvn, ctl, mem, adr, adr_type, t, bt, mo, control_dependency, unaligned, mismatched); } ld = _gvn.transform(ld); if (bt == T_VALUETYPE) { // Loading a non-flattened value type from memory requires a null check. ! ld = ValueTypeNode::make(this, ld, true /* null check */); } else if (((bt == T_OBJECT) && C->do_escape_analysis()) || C->eliminate_boxing()) { // Improve graph before escape analysis and boxing elimination. record_for_igvn(ld); } return ld; --- 1389,1399 ---- ld = LoadNode::make(_gvn, ctl, mem, adr, adr_type, t, bt, mo, control_dependency, unaligned, mismatched); } ld = _gvn.transform(ld); if (bt == T_VALUETYPE) { // Loading a non-flattened value type from memory requires a null check. ! ld = ValueTypeNode::make_from_oop(this, ld, true /* null check */); } else if (((bt == T_OBJECT) && C->do_escape_analysis()) || C->eliminate_boxing()) { // Improve graph before escape analysis and boxing elimination. record_for_igvn(ld); } return ld;
*** 1713,1725 **** // Return of multiple values (value type fields): we create a // ValueType node, each field is a projection from the call. const TypeTuple* range_sig = call->tf()->range_sig(); const Type* t = range_sig->field_at(TypeFunc::Parms); assert(t->isa_valuetypeptr(), "only value types for multiple return values"); ! ciValueKlass* vk = t->is_valuetypeptr()->value_type()->value_klass(); Node* ctl = control(); ! ret = ValueTypeNode::make(_gvn, ctl, merged_memory(), call, vk, TypeFunc::Parms+1, false); set_control(ctl); } } return ret; --- 1713,1725 ---- // Return of multiple values (value type fields): we create a // ValueType node, each field is a projection from the call. const TypeTuple* range_sig = call->tf()->range_sig(); const Type* t = range_sig->field_at(TypeFunc::Parms); assert(t->isa_valuetypeptr(), "only value types for multiple return values"); ! ciValueKlass* vk = t->is_valuetypeptr()->value_klass(); Node* ctl = control(); ! ret = ValueTypeNode::make_from_multi(_gvn, ctl, merged_memory(), call, vk, TypeFunc::Parms+1, false); set_control(ctl); } } return ret;
*** 3676,3747 **** if (stopped()) { set_control(null_ctl); // Always zero return; } - // Prepare for merging control and IO RegionNode* res_ctl = new RegionNode(3); - res_ctl->init_req(1, null_ctl); gvn().set_type(res_ctl, Type::CONTROL); record_for_igvn(res_ctl); ! Node* res_io = PhiNode::make(res_ctl, i_o(), Type::ABIO); gvn().set_type(res_io, Type::ABIO); record_for_igvn(res_io); ! // TODO comment ! SafePointNode* loop_map = NULL; ! { ! PreserveJVMState pjvms(this); ! // Create default value type and store it to memory Node* oop = ValueTypeNode::make_default(gvn(), vk); oop = oop->as_ValueType()->allocate(this)->get_oop(); - length = SubI(length, intcon(1)); add_predicate(nargs); RegionNode* loop = new RegionNode(3); loop->init_req(1, control()); ! gvn().set_type(loop, Type::CONTROL); ! record_for_igvn(loop); ! Node* index = new PhiNode(loop, TypeInt::INT); ! index->init_req(1, intcon(0)); gvn().set_type(index, TypeInt::INT); - record_for_igvn(index); - - // TODO explain why we need to capture all memory - PhiNode* mem = new PhiNode(loop, Type::MEMORY, TypePtr::BOTTOM); - mem->init_req(1, reset_memory()); gvn().set_type(mem, Type::MEMORY); record_for_igvn(mem); set_control(loop); set_all_memory(mem); - // Initialize array element Node* adr = array_element_address(array, index, T_OBJECT); const TypeOopPtr* elemtype = TypeValueTypePtr::make(TypePtr::NotNull, vk); ! Node* store = store_oop_to_array(control(), array, adr, TypeAryPtr::OOPS, oop, elemtype, T_OBJECT, MemNode::release); IfNode* iff = create_and_map_if(control(), Bool(CmpI(index, length), BoolTest::lt), PROB_FAIR, COUNT_UNKNOWN); loop->init_req(2, IfTrue(iff)); - mem->init_req(2, merged_memory()); index->init_req(2, AddI(index, intcon(1))); res_ctl->init_req(2, IfFalse(iff)); res_io->set_req(2, i_o()); ! loop_map = stop(); ! } // Set merged control, IO and memory set_control(res_ctl); set_i_o(res_io); ! merge_memory(loop_map->merged_memory(), res_ctl, 2); ! ! // Transform new memory Phis. ! for (MergeMemStream mms(merged_memory()); mms.next_non_empty();) { ! Node* phi = mms.memory(); ! if (phi->is_Phi() && phi->in(0) == res_ctl) { ! mms.set_memory(gvn().transform(phi)); ! } ! } } // The following "Ideal_foo" functions are placed here because they recognize // the graph shapes created by the functions immediately above. --- 3676,3740 ---- if (stopped()) { set_control(null_ctl); // Always zero return; } RegionNode* res_ctl = new RegionNode(3); gvn().set_type(res_ctl, Type::CONTROL); record_for_igvn(res_ctl); ! ! // Length is zero: don't execute initialization loop ! res_ctl->init_req(1, null_ctl); ! PhiNode* res_io = PhiNode::make(res_ctl, i_o(), Type::ABIO); ! PhiNode* res_mem = PhiNode::make(res_ctl, merged_memory(), Type::MEMORY, TypePtr::BOTTOM); gvn().set_type(res_io, Type::ABIO); + gvn().set_type(res_mem, Type::MEMORY); record_for_igvn(res_io); + record_for_igvn(res_mem); ! // Length is non-zero: execute a loop that initializes the array with the default value type Node* oop = ValueTypeNode::make_default(gvn(), vk); oop = oop->as_ValueType()->allocate(this)->get_oop(); add_predicate(nargs); RegionNode* loop = new RegionNode(3); loop->init_req(1, control()); ! PhiNode* index = PhiNode::make(loop, intcon(0), TypeInt::INT); ! PhiNode* mem = PhiNode::make(loop, reset_memory(), Type::MEMORY, TypePtr::BOTTOM); ! gvn().set_type(loop, Type::CONTROL); gvn().set_type(index, TypeInt::INT); gvn().set_type(mem, Type::MEMORY); + record_for_igvn(loop); + record_for_igvn(index); record_for_igvn(mem); + + // Loop body: initialize array element at 'index' set_control(loop); set_all_memory(mem); Node* adr = array_element_address(array, index, T_OBJECT); const TypeOopPtr* elemtype = TypeValueTypePtr::make(TypePtr::NotNull, vk); ! store_oop_to_array(control(), array, adr, TypeAryPtr::OOPS, oop, elemtype, T_VALUETYPE, MemNode::release); + // Check if we need to execute another loop iteration + length = SubI(length, intcon(1)); IfNode* iff = create_and_map_if(control(), Bool(CmpI(index, length), BoolTest::lt), PROB_FAIR, COUNT_UNKNOWN); + + // Continue with next iteration loop->init_req(2, IfTrue(iff)); index->init_req(2, AddI(index, intcon(1))); + mem->init_req(2, merged_memory()); + // Exit loop res_ctl->init_req(2, IfFalse(iff)); res_io->set_req(2, i_o()); ! res_mem->set_req(2, reset_memory()); ! // Set merged control, IO and memory set_control(res_ctl); set_i_o(res_io); ! set_all_memory(res_mem); } // The following "Ideal_foo" functions are placed here because they recognize // the graph shapes created by the functions immediately above.
*** 4562,4572 **** /*is_unsigned_load=*/false); if (con_type != NULL) { Node* con = makecon(con_type); if (field->layout_type() == T_VALUETYPE) { // Load value type from constant oop ! con = ValueTypeNode::make(this, con); } return con; } return NULL; } --- 4555,4565 ---- /*is_unsigned_load=*/false); if (con_type != NULL) { Node* con = makecon(con_type); if (field->layout_type() == T_VALUETYPE) { // Load value type from constant oop ! con = ValueTypeNode::make_from_oop(this, con); } return con; } return NULL; }
< prev index next >