--- old/src/share/vm/opto/parse1.cpp 2016-11-16 09:06:12.870498600 +0100 +++ new/src/share/vm/opto/parse1.cpp 2016-11-16 09:06:12.806498598 +0100 @@ -1745,32 +1745,17 @@ ValueTypeNode* vtm = m->as_ValueType(); // Current value type ValueTypeNode* vtn = n->as_ValueType(); // Incoming value type if (TraceOptoParse) { - tty->print_cr("Merging value types"); #ifdef ASSERT + tty->print_cr("\nMerging value types"); tty->print_cr("Current:"); - vtm->dump(1); + vtm->dump(2); tty->print_cr("Incoming:"); - vtn->dump(1); + vtn->dump(2); + tty->cr(); #endif } - // Merge oop inputs - phi = vtm->get_oop()->as_Phi(); - phi->set_req(pnum, vtn->get_oop()); - if (pnum == PhiNode::Input) { - // Last merge - vtm->set_oop(_gvn.transform_no_reclaim(phi)); - record_for_igvn(phi); - } - // Merge field values - for (uint index = 0; index < vtm->field_count(); ++index) { - phi = vtm->get_field_value(index)->as_Phi(); - phi->set_req(pnum, vtn->get_field_value(index)); - if (pnum == PhiNode::Input) { - // Last merge - vtm->set_field_value(index, _gvn.transform_no_reclaim(phi)); - record_for_igvn(phi); - } - } + // Do the merge + map()->set_req(j, vtm->merge_with(this, vtn, pnum)); } else if (phi != NULL) { assert(n != top() || r->in(pnum) == top(), "live value must not be garbage"); assert(phi->region() == r, ""); @@ -1968,8 +1953,16 @@ } ValueTypeNode* vt = o->isa_ValueType(); - if (vt != NULL && vt->get_oop()->is_Phi() && vt->get_oop()->as_Phi()->region() == region) { - // ValueTypeNode already has Phi inputs + if (vt != NULL) { + // Value types are merged by merging their field values + if (vt->get_oop()->is_Phi() && vt->get_oop()->as_Phi()->region() == region) { + // ValueTypeNode already has Phi inputs + return NULL; + } + // Create a cloned ValueTypeNode with phi inputs that + // represents the merged value type and update the map. + vt = vt->clone_with_phis(gvn(), region); + map->set_req(idx, vt); return NULL; } @@ -2005,31 +1998,6 @@ return NULL; } - // Value types are merged by merging their field values - if (vt != NULL) { - // Create new ValueTypeNode that represents the merged value type - vt = vt->clone()->as_ValueType(); - - // Create a PhiNode for merging the oop - const TypeValueTypePtr* vtptr = TypeValueTypePtr::make(t->is_valuetype()); - PhiNode* oop = PhiNode::make(region, vt->get_oop(), vtptr); - gvn().set_type(oop, vtptr); - vt->set_oop(oop); - - // Create a PhiNode for merging each field value - for (uint i = 0; i < vt->field_count(); ++i) { - const Type* field_type = Type::get_const_basic_type(vt->get_field_type(i)); - PhiNode* phi = PhiNode::make(region, vt->get_field_value(i), field_type); - gvn().set_type(phi, field_type); - vt->set_field_value(i, phi); - } - - // Update map to use cloned value type - gvn().set_type(vt, t); - map->set_req(idx, vt); - return NULL; - } - PhiNode* phi = PhiNode::make(region, o, t); gvn().set_type(phi, t); if (C->do_escape_analysis()) record_for_igvn(phi);