--- old/src/hotspot/share/opto/cfgnode.cpp 2019-03-11 14:26:37.046354728 +0100 +++ new/src/hotspot/share/opto/cfgnode.cpp 2019-03-11 14:26:36.838354731 +0100 @@ -43,6 +43,7 @@ #include "opto/regmask.hpp" #include "opto/runtime.hpp" #include "opto/subnode.hpp" +#include "opto/valuetypenode.hpp" #include "utilities/vmError.hpp" // Portions of code courtesy of Clifford Click @@ -372,7 +373,7 @@ return true; // The Region node is unreachable - it is dead. } -bool RegionNode::try_clean_mem_phi(PhaseGVN *phase) { +Node* PhiNode::try_clean_mem_phi(PhaseGVN *phase) { // Incremental inlining + PhaseStringOpts sometimes produce: // // cmpP with 1 top input @@ -392,27 +393,26 @@ // code below replaces the Phi with the MergeMem so that the Region // is simplified. - PhiNode* phi = has_unique_phi(); - if (phi && phi->type() == Type::MEMORY && req() == 3 && phi->is_diamond_phi(true)) { + if (type() == Type::MEMORY && is_diamond_phi(true)) { MergeMemNode* m = NULL; - assert(phi->req() == 3, "same as region"); + assert(req() == 3, "same as region"); + Node* r = in(0); for (uint i = 1; i < 3; ++i) { - Node *mem = phi->in(i); - if (mem && mem->is_MergeMem() && in(i)->outcnt() == 1) { + Node *mem = in(i); + if (mem && mem->is_MergeMem() && r->in(i)->outcnt() == 1) { // Nothing is control-dependent on path #i except the region itself. m = mem->as_MergeMem(); uint j = 3 - i; - Node* other = phi->in(j); + Node* other = in(j); if (other && other == m->base_memory()) { // m is a successor memory to other, and is not pinned inside the diamond, so push it out. // This will allow the diamond to collapse completely. - phase->is_IterGVN()->replace_node(phi, m); - return true; + return m; } } } } - return false; + return NULL; } //------------------------------Ideal------------------------------------------ @@ -427,8 +427,15 @@ bool has_phis = false; if (can_reshape) { // Need DU info to check for Phi users has_phis = (has_phi() != NULL); // Cache result - if (has_phis && try_clean_mem_phi(phase)) { - has_phis = false; + if (has_phis) { + PhiNode* phi = has_unique_phi(); + if (phi != NULL) { + Node* m = phi->try_clean_mem_phi(phase); + if (m != NULL) { + phase->is_IterGVN()->replace_node(phi, m); + has_phis = false; + } + } } if (!has_phis) { // No Phi users? Nothing merging? @@ -1106,15 +1113,10 @@ const TypeInstPtr* ttip = (ttp != NULL) ? ttp->isa_instptr() : NULL; const TypeKlassPtr* ttkp = (ttp != NULL) ? ttp->isa_klassptr() : NULL; bool is_intf = false; - if (ttip != NULL) { - ciKlass* k = ttip->klass(); - if (k->is_loaded() && k->is_interface()) - is_intf = true; - } - if (ttkp != NULL) { - ciKlass* k = ttkp->klass(); - if (k->is_loaded() && k->is_interface()) - is_intf = true; + if (ttip != NULL && ttip->is_loaded() && ttip->klass()->is_interface()) { + is_intf = true; + } else if (ttkp != NULL && ttkp->is_loaded() && ttkp->klass()->is_interface()) { + is_intf = true; } // Default case: merge all inputs @@ -1171,9 +1173,9 @@ // be 'I' or 'j/l/O'. Thus we'll pick 'j/l/O'. If this then flows // into a Phi which "knows" it's an Interface type we'll have to // uplift the type. - if (!t->empty() && ttip && ttip->is_loaded() && ttip->klass()->is_interface()) { + if (!t->empty() && ttip != NULL && ttip->is_loaded() && ttip->klass()->is_interface()) { assert(ft == _type, ""); // Uplift to interface - } else if (!t->empty() && ttkp && ttkp->is_loaded() && ttkp->klass()->is_interface()) { + } else if (!t->empty() && ttkp != NULL && ttkp->is_loaded() && ttkp->klass()->is_interface()) { assert(ft == _type, ""); // Uplift to interface } else { // We also have to handle 'evil cases' of interface- vs. class-arrays @@ -1335,6 +1337,14 @@ if (id != NULL) return id; } + if (phase->is_IterGVN()) { + Node* m = try_clean_mem_phi(phase); + if (m != NULL) { + return m; + } + } + + return this; // No identity } @@ -1796,6 +1806,24 @@ if( phase->type_or_null(r) == Type::TOP ) // Dead code? return NULL; // No change + // If all inputs are value types of the same type, push the value type node down + // through the phi because value type nodes should be merged through their input values. + if (req() > 2 && in(1) != NULL && in(1)->is_ValueTypeBase() && (can_reshape || in(1)->is_ValueType())) { + int opcode = in(1)->Opcode(); + uint i = 2; + // Check if inputs are values of the same type + for (; i < req() && in(i) && in(i)->is_ValueTypeBase() && in(i)->cmp(*in(1)); i++) { + assert(in(i)->Opcode() == opcode, "mixing pointers and values?"); + } + if (i == req()) { + ValueTypeBaseNode* vt = in(1)->as_ValueTypeBase()->clone_with_phis(phase, in(0)); + for (uint i = 2; i < req(); ++i) { + vt->merge_with(phase, in(i)->as_ValueTypeBase(), i, i == (req()-1)); + } + return vt; + } + } + Node *top = phase->C->top(); bool new_phi = (outcnt() == 0); // transforming new Phi // No change for igvn if new phi is not hooked @@ -2503,6 +2531,12 @@ // We only come from CatchProj, unless the CatchProj goes away. // If the CatchProj is optimized away, then we just carry the // exception oop through. + + // CheckCastPPNode::Ideal() for value types reuses the exception + // paths of a call to perform an allocation: we can see a Phi here. + if (in(1)->is_Phi()) { + return this; + } CallNode *call = in(1)->in(0)->as_Call(); return ( in(0)->is_CatchProj() && in(0)->in(0)->in(1) == in(1) )