提交 e95e1dc1 编写于 作者: K kvn

6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot...

6711117: Assertion in 64bit server vm (flat != TypePtr::BOTTOM,"cannot alias-analyze an untyped ptr")
Summary: Delay a memory node transformation if its control or address on IGVN worklist.
Reviewed-by: never
上级 87e0faa4
...@@ -806,8 +806,7 @@ void PhaseMacroExpand::process_users_of_allocation(AllocateNode *alloc) { ...@@ -806,8 +806,7 @@ void PhaseMacroExpand::process_users_of_allocation(AllocateNode *alloc) {
} }
} else if (use->is_AddP()) { } else if (use->is_AddP()) {
// raw memory addresses used only by the initialization // raw memory addresses used only by the initialization
_igvn.hash_delete(use); _igvn.replace_node(use, C->top());
_igvn.subsume_node(use, C->top());
} else { } else {
assert(false, "only Initialize or AddP expected"); assert(false, "only Initialize or AddP expected");
} }
...@@ -1291,8 +1290,7 @@ void PhaseMacroExpand::expand_allocate_common( ...@@ -1291,8 +1290,7 @@ void PhaseMacroExpand::expand_allocate_common(
if (_fallthroughcatchproj != NULL) { if (_fallthroughcatchproj != NULL) {
ctrl = _fallthroughcatchproj->clone(); ctrl = _fallthroughcatchproj->clone();
transform_later(ctrl); transform_later(ctrl);
_igvn.hash_delete(_fallthroughcatchproj); _igvn.replace_node(_fallthroughcatchproj, result_region);
_igvn.subsume_node(_fallthroughcatchproj, result_region);
} else { } else {
ctrl = top(); ctrl = top();
} }
...@@ -1303,8 +1301,7 @@ void PhaseMacroExpand::expand_allocate_common( ...@@ -1303,8 +1301,7 @@ void PhaseMacroExpand::expand_allocate_common(
} else { } else {
slow_result = _resproj->clone(); slow_result = _resproj->clone();
transform_later(slow_result); transform_later(slow_result);
_igvn.hash_delete(_resproj); _igvn.replace_node(_resproj, result_phi_rawoop);
_igvn.subsume_node(_resproj, result_phi_rawoop);
} }
// Plug slow-path into result merge point // Plug slow-path into result merge point
...@@ -1613,18 +1610,15 @@ bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) { ...@@ -1613,18 +1610,15 @@ bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) {
assert(membar != NULL && membar->Opcode() == Op_MemBarAcquire, ""); assert(membar != NULL && membar->Opcode() == Op_MemBarAcquire, "");
Node* ctrlproj = membar->proj_out(TypeFunc::Control); Node* ctrlproj = membar->proj_out(TypeFunc::Control);
Node* memproj = membar->proj_out(TypeFunc::Memory); Node* memproj = membar->proj_out(TypeFunc::Memory);
_igvn.hash_delete(ctrlproj); _igvn.replace_node(ctrlproj, fallthroughproj);
_igvn.subsume_node(ctrlproj, fallthroughproj); _igvn.replace_node(memproj, memproj_fallthrough);
_igvn.hash_delete(memproj);
_igvn.subsume_node(memproj, memproj_fallthrough);
// Delete FastLock node also if this Lock node is unique user // Delete FastLock node also if this Lock node is unique user
// (a loop peeling may clone a Lock node). // (a loop peeling may clone a Lock node).
Node* flock = alock->as_Lock()->fastlock_node(); Node* flock = alock->as_Lock()->fastlock_node();
if (flock->outcnt() == 1) { if (flock->outcnt() == 1) {
assert(flock->unique_out() == alock, "sanity"); assert(flock->unique_out() == alock, "sanity");
_igvn.hash_delete(flock); _igvn.replace_node(flock, top());
_igvn.subsume_node(flock, top());
} }
} }
...@@ -1634,20 +1628,16 @@ bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) { ...@@ -1634,20 +1628,16 @@ bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) {
MemBarNode* membar = ctrl->in(0)->as_MemBar(); MemBarNode* membar = ctrl->in(0)->as_MemBar();
assert(membar->Opcode() == Op_MemBarRelease && assert(membar->Opcode() == Op_MemBarRelease &&
mem->is_Proj() && membar == mem->in(0), ""); mem->is_Proj() && membar == mem->in(0), "");
_igvn.hash_delete(fallthroughproj); _igvn.replace_node(fallthroughproj, ctrl);
_igvn.subsume_node(fallthroughproj, ctrl); _igvn.replace_node(memproj_fallthrough, mem);
_igvn.hash_delete(memproj_fallthrough);
_igvn.subsume_node(memproj_fallthrough, mem);
fallthroughproj = ctrl; fallthroughproj = ctrl;
memproj_fallthrough = mem; memproj_fallthrough = mem;
ctrl = membar->in(TypeFunc::Control); ctrl = membar->in(TypeFunc::Control);
mem = membar->in(TypeFunc::Memory); mem = membar->in(TypeFunc::Memory);
} }
_igvn.hash_delete(fallthroughproj); _igvn.replace_node(fallthroughproj, ctrl);
_igvn.subsume_node(fallthroughproj, ctrl); _igvn.replace_node(memproj_fallthrough, mem);
_igvn.hash_delete(memproj_fallthrough);
_igvn.subsume_node(memproj_fallthrough, mem);
return true; return true;
} }
...@@ -1879,13 +1869,12 @@ void PhaseMacroExpand::expand_lock_node(LockNode *lock) { ...@@ -1879,13 +1869,12 @@ void PhaseMacroExpand::expand_lock_node(LockNode *lock) {
region->init_req(1, slow_ctrl); region->init_req(1, slow_ctrl);
// region inputs are now complete // region inputs are now complete
transform_later(region); transform_later(region);
_igvn.subsume_node(_fallthroughproj, region); _igvn.replace_node(_fallthroughproj, region);
Node *memproj = transform_later( new(C, 1) ProjNode(call, TypeFunc::Memory) ); Node *memproj = transform_later( new(C, 1) ProjNode(call, TypeFunc::Memory) );
mem_phi->init_req(1, memproj ); mem_phi->init_req(1, memproj );
transform_later(mem_phi); transform_later(mem_phi);
_igvn.hash_delete(_memproj_fallthrough); _igvn.replace_node(_memproj_fallthrough, mem_phi);
_igvn.subsume_node(_memproj_fallthrough, mem_phi);
} }
//------------------------------expand_unlock_node---------------------- //------------------------------expand_unlock_node----------------------
...@@ -1943,14 +1932,13 @@ void PhaseMacroExpand::expand_unlock_node(UnlockNode *unlock) { ...@@ -1943,14 +1932,13 @@ void PhaseMacroExpand::expand_unlock_node(UnlockNode *unlock) {
region->init_req(1, slow_ctrl); region->init_req(1, slow_ctrl);
// region inputs are now complete // region inputs are now complete
transform_later(region); transform_later(region);
_igvn.subsume_node(_fallthroughproj, region); _igvn.replace_node(_fallthroughproj, region);
Node *memproj = transform_later( new(C, 1) ProjNode(call, TypeFunc::Memory) ); Node *memproj = transform_later( new(C, 1) ProjNode(call, TypeFunc::Memory) );
mem_phi->init_req(1, memproj ); mem_phi->init_req(1, memproj );
mem_phi->init_req(2, mem); mem_phi->init_req(2, mem);
transform_later(mem_phi); transform_later(mem_phi);
_igvn.hash_delete(_memproj_fallthrough); _igvn.replace_node(_memproj_fallthrough, mem_phi);
_igvn.subsume_node(_memproj_fallthrough, mem_phi);
} }
//------------------------------expand_macro_nodes---------------------- //------------------------------expand_macro_nodes----------------------
...@@ -1969,9 +1957,7 @@ bool PhaseMacroExpand::expand_macro_nodes() { ...@@ -1969,9 +1957,7 @@ bool PhaseMacroExpand::expand_macro_nodes() {
if (n->is_AbstractLock()) { if (n->is_AbstractLock()) {
success = eliminate_locking_node(n->as_AbstractLock()); success = eliminate_locking_node(n->as_AbstractLock());
} else if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) { } else if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) {
_igvn.add_users_to_worklist(n); _igvn.replace_node(n, n->in(1));
_igvn.hash_delete(n);
_igvn.subsume_node(n, n->in(1));
success = true; success = true;
} }
assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count"); assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
......
...@@ -218,6 +218,26 @@ Node *MemNode::Ideal_common(PhaseGVN *phase, bool can_reshape) { ...@@ -218,6 +218,26 @@ Node *MemNode::Ideal_common(PhaseGVN *phase, bool can_reshape) {
// Don't bother trying to transform a dead node // Don't bother trying to transform a dead node
if( ctl && ctl->is_top() ) return NodeSentinel; if( ctl && ctl->is_top() ) return NodeSentinel;
PhaseIterGVN *igvn = phase->is_IterGVN();
// Wait if control on the worklist.
if (ctl && can_reshape && igvn != NULL) {
Node* bol = NULL;
Node* cmp = NULL;
if (ctl->in(0)->is_If()) {
assert(ctl->is_IfTrue() || ctl->is_IfFalse(), "sanity");
bol = ctl->in(0)->in(1);
if (bol->is_Bool())
cmp = ctl->in(0)->in(1)->in(1);
}
if (igvn->_worklist.member(ctl) ||
(bol != NULL && igvn->_worklist.member(bol)) ||
(cmp != NULL && igvn->_worklist.member(cmp)) ) {
// This control path may be dead.
// Delay this memory node transformation until the control is processed.
phase->is_IterGVN()->_worklist.push(this);
return NodeSentinel; // caller will return NULL
}
}
// Ignore if memory is dead, or self-loop // Ignore if memory is dead, or self-loop
Node *mem = in(MemNode::Memory); Node *mem = in(MemNode::Memory);
if( phase->type( mem ) == Type::TOP ) return NodeSentinel; // caller will return NULL if( phase->type( mem ) == Type::TOP ) return NodeSentinel; // caller will return NULL
...@@ -227,14 +247,22 @@ Node *MemNode::Ideal_common(PhaseGVN *phase, bool can_reshape) { ...@@ -227,14 +247,22 @@ Node *MemNode::Ideal_common(PhaseGVN *phase, bool can_reshape) {
const Type *t_adr = phase->type( address ); const Type *t_adr = phase->type( address );
if( t_adr == Type::TOP ) return NodeSentinel; // caller will return NULL if( t_adr == Type::TOP ) return NodeSentinel; // caller will return NULL
PhaseIterGVN *igvn = phase->is_IterGVN(); if( can_reshape && igvn != NULL &&
if( can_reshape && igvn != NULL && igvn->_worklist.member(address) ) { (igvn->_worklist.member(address) || phase->type(address) != adr_type()) ) {
// The address's base and type may change when the address is processed. // The address's base and type may change when the address is processed.
// Delay this mem node transformation until the address is processed. // Delay this mem node transformation until the address is processed.
phase->is_IterGVN()->_worklist.push(this); phase->is_IterGVN()->_worklist.push(this);
return NodeSentinel; // caller will return NULL return NodeSentinel; // caller will return NULL
} }
#ifdef ASSERT
Node* base = NULL;
if (address->is_AddP())
base = address->in(AddPNode::Base);
assert(base == NULL || t_adr->isa_rawptr() ||
!phase->type(base)->higher_equal(TypePtr::NULL_PTR), "NULL+offs not RAW address?");
#endif
// Avoid independent memory operations // Avoid independent memory operations
Node* old_mem = mem; Node* old_mem = mem;
...@@ -1307,22 +1335,20 @@ Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) { ...@@ -1307,22 +1335,20 @@ Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) {
set_req(MemNode::Control,ctrl); set_req(MemNode::Control,ctrl);
} }
// Check for useless control edge in some common special cases intptr_t ignore = 0;
if (in(MemNode::Control) != NULL) { Node* base = AddPNode::Ideal_base_and_offset(address, phase, ignore);
intptr_t ignore = 0; if (base != NULL
Node* base = AddPNode::Ideal_base_and_offset(address, phase, ignore); && phase->C->get_alias_index(phase->type(address)->is_ptr()) != Compile::AliasIdxRaw) {
if (base != NULL // Check for useless control edge in some common special cases
if (in(MemNode::Control) != NULL
&& phase->type(base)->higher_equal(TypePtr::NOTNULL) && phase->type(base)->higher_equal(TypePtr::NOTNULL)
&& phase->C->get_alias_index(phase->type(address)->is_ptr()) != Compile::AliasIdxRaw
&& all_controls_dominate(base, phase->C->start())) { && all_controls_dominate(base, phase->C->start())) {
// A method-invariant, non-null address (constant or 'this' argument). // A method-invariant, non-null address (constant or 'this' argument).
set_req(MemNode::Control, NULL); set_req(MemNode::Control, NULL);
} }
}
if (EliminateAutoBox && can_reshape && in(Address)->is_AddP()) { if (EliminateAutoBox && can_reshape) {
Node* base = in(Address)->in(AddPNode::Base); assert(!phase->type(base)->higher_equal(TypePtr::NULL_PTR), "the autobox pointer should be non-null");
if (base != NULL) {
Compile::AliasType* atp = phase->C->alias_type(adr_type()); Compile::AliasType* atp = phase->C->alias_type(adr_type());
if (is_autobox_object(atp)) { if (is_autobox_object(atp)) {
Node* result = eliminate_autobox(phase); Node* result = eliminate_autobox(phase);
...@@ -1455,10 +1481,11 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const { ...@@ -1455,10 +1481,11 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const {
jt = _type; jt = _type;
} }
if (EliminateAutoBox) { if (EliminateAutoBox && adr->is_AddP()) {
// The pointers in the autobox arrays are always non-null // The pointers in the autobox arrays are always non-null
Node* base = in(Address)->in(AddPNode::Base); Node* base = adr->in(AddPNode::Base);
if (base != NULL) { if (base != NULL &&
!phase->type(base)->higher_equal(TypePtr::NULL_PTR)) {
Compile::AliasType* atp = phase->C->alias_type(base->adr_type()); Compile::AliasType* atp = phase->C->alias_type(base->adr_type());
if (is_autobox_cache(atp)) { if (is_autobox_cache(atp)) {
return jt->join(TypePtr::NOTNULL)->is_ptr(); return jt->join(TypePtr::NOTNULL)->is_ptr();
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册