6723160: Nightly failure: Error: meet not symmetric

Add missing _instance_id settings and other EA fixes.

Reviewed-by: rasbold
This commit is contained in:
Vladimir Kozlov 2008-07-16 16:04:39 -07:00
parent a8fc1db8c1
commit fae39068e8
11 changed files with 224 additions and 129 deletions

View file

@ -231,8 +231,7 @@ static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_me
} else {
return mem;
}
if (mem == orig_mem)
return mem;
assert(mem != orig_mem, "dead memory loop");
}
}
@ -241,21 +240,44 @@ static Node *scan_mem_chain(Node *mem, int alias_idx, int offset, Node *start_me
// on the input paths.
// Note: this function is recursive, its depth is limied by the "level" argument
// Returns the computed Phi, or NULL if it cannot compute it.
Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type *phi_type, const TypeOopPtr *adr_t, Node *alloc, int level) {
if (level <= 0) {
return NULL;
}
Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type *phi_type, const TypeOopPtr *adr_t, Node *alloc, Node_Stack *value_phis, int level) {
assert(mem->is_Phi(), "sanity");
int alias_idx = C->get_alias_index(adr_t);
int offset = adr_t->offset();
int instance_id = adr_t->instance_id();
// Check if an appropriate value phi already exists.
Node* region = mem->in(0);
for (DUIterator_Fast kmax, k = region->fast_outs(kmax); k < kmax; k++) {
Node* phi = region->fast_out(k);
if (phi->is_Phi() && phi != mem &&
phi->as_Phi()->is_same_inst_field(phi_type, instance_id, alias_idx, offset)) {
return phi;
}
}
// Check if an appropriate new value phi already exists.
Node* new_phi = NULL;
uint size = value_phis->size();
for (uint i=0; i < size; i++) {
if ( mem->_idx == value_phis->index_at(i) ) {
return value_phis->node_at(i);
}
}
if (level <= 0) {
return NULL;
}
Node *start_mem = C->start()->proj_out(TypeFunc::Memory);
Node *alloc_mem = alloc->in(TypeFunc::Memory);
uint length = mem->req();
GrowableArray <Node *> values(length, length, NULL);
// create a new Phi for the value
PhiNode *phi = new (C, length) PhiNode(mem->in(0), phi_type, NULL, instance_id, alias_idx, offset);
transform_later(phi);
value_phis->push(phi, mem->_idx);
for (uint j = 1; j < length; j++) {
Node *in = mem->in(j);
if (in == NULL || in->is_top()) {
@ -280,33 +302,17 @@ Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type *
} else if(val->is_Proj() && val->in(0) == alloc) {
values.at_put(j, _igvn.zerocon(ft));
} else if (val->is_Phi()) {
// Check if an appropriate node already exists.
Node* region = val->in(0);
Node* old_phi = NULL;
for (DUIterator_Fast kmax, k = region->fast_outs(kmax); k < kmax; k++) {
Node* phi = region->fast_out(k);
if (phi->is_Phi() && phi != val &&
phi->as_Phi()->is_same_inst_field(phi_type, instance_id, alias_idx, offset)) {
old_phi = phi;
break;
}
}
if (old_phi == NULL) {
val = value_from_mem_phi(val, ft, phi_type, adr_t, alloc, level-1);
if (val == NULL) {
return NULL;
}
values.at_put(j, val);
} else {
values.at_put(j, old_phi);
val = value_from_mem_phi(val, ft, phi_type, adr_t, alloc, value_phis, level-1);
if (val == NULL) {
return NULL;
}
values.at_put(j, val);
} else {
return NULL; // unknown node on this path
}
}
}
// create a new Phi for the value
PhiNode *phi = new (C, length) PhiNode(mem->in(0), phi_type, NULL, instance_id, alias_idx, offset);
// Set Phi's inputs
for (uint j = 1; j < length; j++) {
if (values.at(j) == mem) {
phi->init_req(j, phi);
@ -314,7 +320,6 @@ Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type *
phi->init_req(j, values.at(j));
}
}
transform_later(phi);
return phi;
}
@ -329,7 +334,8 @@ Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, BasicType ft, const Type
Node *start_mem = C->start()->proj_out(TypeFunc::Memory);
Node *alloc_ctrl = alloc->in(TypeFunc::Control);
Node *alloc_mem = alloc->in(TypeFunc::Memory);
VectorSet visited(Thread::current()->resource_area());
Arena *a = Thread::current()->resource_area();
VectorSet visited(a);
bool done = sfpt_mem == alloc_mem;
@ -389,9 +395,18 @@ Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, BasicType ft, const Type
return mem->in(MemNode::ValueIn);
} else if (mem->is_Phi()) {
// attempt to produce a Phi reflecting the values on the input paths of the Phi
Node * phi = value_from_mem_phi(mem, ft, ftype, adr_t, alloc, 8);
Node_Stack value_phis(a, 8);
Node * phi = value_from_mem_phi(mem, ft, ftype, adr_t, alloc, &value_phis, 8);
if (phi != NULL) {
return phi;
} else {
// Kill all new Phis
while(value_phis.is_nonempty()) {
Node* n = value_phis.node();
_igvn.hash_delete(n);
_igvn.subsume_node(n, C->top());
value_phis.pop();
}
}
}
}