< 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 >