< prev index next >

src/hotspot/share/opto/cfgnode.cpp

Print this page

        

*** 41,50 **** --- 41,51 ---- #include "opto/mulnode.hpp" #include "opto/phaseX.hpp" #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 // Optimization - Graph Style
*** 370,380 **** } return true; // The Region node is unreachable - it is dead. } ! bool RegionNode::try_clean_mem_phi(PhaseGVN *phase) { // Incremental inlining + PhaseStringOpts sometimes produce: // // cmpP with 1 top input // | // If --- 371,381 ---- } return true; // The Region node is unreachable - it is dead. } ! Node* PhiNode::try_clean_mem_phi(PhaseGVN *phase) { // Incremental inlining + PhaseStringOpts sometimes produce: // // cmpP with 1 top input // | // If
*** 390,420 **** // the Region stays in the graph. The top input from the cmpP is // propagated forward and a subgraph that is useful goes away. The // 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)) { MergeMemNode* m = NULL; ! assert(phi->req() == 3, "same as region"); for (uint i = 1; i < 3; ++i) { ! Node *mem = phi->in(i); ! if (mem && mem->is_MergeMem() && 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); 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 false; } //------------------------------Ideal------------------------------------------ // Return a node which is more "ideal" than the current node. Must preserve // the CFG, but we can still strip out dead paths. --- 391,420 ---- // the Region stays in the graph. The top input from the cmpP is // propagated forward and a subgraph that is useful goes away. The // code below replaces the Phi with the MergeMem so that the Region // is simplified. ! if (type() == Type::MEMORY && is_diamond_phi(true)) { MergeMemNode* m = NULL; ! assert(req() == 3, "same as region"); ! Node* r = in(0); for (uint i = 1; i < 3; ++i) { ! 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 = 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. ! return m; } } } } ! return NULL; } //------------------------------Ideal------------------------------------------ // Return a node which is more "ideal" than the current node. Must preserve // the CFG, but we can still strip out dead paths.
*** 425,436 **** // Check for RegionNode with no Phi users and both inputs come from either // arm of the same IF. If found, then the control-flow split is useless. 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) { // No Phi users? Nothing merging? for (uint i = 1; i < req()-1; i++) { Node *if1 = in(i); --- 425,443 ---- // Check for RegionNode with no Phi users and both inputs come from either // arm of the same IF. If found, then the control-flow split is useless. 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) { ! 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? for (uint i = 1; i < req()-1; i++) { Node *if1 = in(i);
*** 894,904 **** //----------------------------make--------------------------------------------- // create a new phi with edges matching r and set (initially) to x PhiNode* PhiNode::make(Node* r, Node* x, const Type *t, const TypePtr* at) { uint preds = r->req(); // Number of predecessor paths ! assert(t != Type::MEMORY || at == flatten_phi_adr_type(at), "flatten at"); PhiNode* p = new PhiNode(r, t, at); for (uint j = 1; j < preds; j++) { // Fill in all inputs, except those which the region does not yet have if (r->in(j) != NULL) p->init_req(j, x); --- 901,911 ---- //----------------------------make--------------------------------------------- // create a new phi with edges matching r and set (initially) to x PhiNode* PhiNode::make(Node* r, Node* x, const Type *t, const TypePtr* at) { uint preds = r->req(); // Number of predecessor paths ! assert(t != Type::MEMORY || at == flatten_phi_adr_type(at) || (flatten_phi_adr_type(at) == TypeAryPtr::VALUES && Compile::current()->flattened_accesses_share_alias()), "flatten at"); PhiNode* p = new PhiNode(r, t, at); for (uint j = 1; j < preds; j++) { // Fill in all inputs, except those which the region does not yet have if (r->in(j) != NULL) p->init_req(j, x);
*** 1104,1122 **** // convert the one to the other. const TypePtr* ttp = _type->make_ptr(); 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; } // Default case: merge all inputs const Type *t = Type::TOP; // Merged type starting value for (uint i = 1; i < req(); ++i) {// For all paths in --- 1111,1124 ---- // convert the one to the other. const TypePtr* ttp = _type->make_ptr(); 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 && 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 const Type *t = Type::TOP; // Merged type starting value for (uint i = 1; i < req(); ++i) {// For all paths in
*** 1169,1181 **** // both implement interface I, but their meet is at 'j/l/O' which // doesn't implement I, we have no way to tell if the result should // 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()) { assert(ft == _type, ""); // Uplift to interface ! } else if (!t->empty() && ttkp && 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 Type::get_arrays_base_elements(jt, _type, NULL, &ttip); if (!t->empty() && ttip != NULL && ttip->is_loaded() && ttip->klass()->is_interface()) { --- 1171,1183 ---- // both implement interface I, but their meet is at 'j/l/O' which // doesn't implement I, we have no way to tell if the result should // 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 != NULL && ttip->is_loaded() && ttip->klass()->is_interface()) { assert(ft == _type, ""); // Uplift to 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 Type::get_arrays_base_elements(jt, _type, NULL, &ttip); if (!t->empty() && ttip != NULL && ttip->is_loaded() && ttip->klass()->is_interface()) {
*** 1333,1342 **** --- 1335,1352 ---- if (true_path != 0) { Node* id = is_cmove_id(phase, true_path); 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 } //-----------------------------unique_input------------------------------------ // Find the unique value, discounting top, self-loops, and casts.
*** 1794,1803 **** --- 1804,1831 ---- // Note: During parsing, phis are often transformed before their regions. // This means we have to use type_or_null to defend against untyped regions. 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 if (new_phi && can_reshape) return NULL;
*** 2501,2510 **** --- 2529,2544 ---- if( phase->type(in(1)) == Type::TOP ) return in(1); if( phase->type(in(0)) == Type::TOP ) return in(0); // 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) ) ? this : call->in(TypeFunc::Parms);
< prev index next >