src/share/vm/opto/cfgnode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Cdiff src/share/vm/opto/cfgnode.cpp

src/share/vm/opto/cfgnode.cpp

Print this page

        

*** 25,34 **** --- 25,35 ---- #include "precompiled.hpp" #include "classfile/systemDictionary.hpp" #include "memory/allocation.inline.hpp" #include "oops/objArrayKlass.hpp" #include "opto/addnode.hpp" + #include "opto/castnode.hpp" #include "opto/cfgnode.hpp" #include "opto/connode.hpp" #include "opto/convertnode.hpp" #include "opto/loopnode.hpp" #include "opto/machnode.hpp"
*** 1146,1156 **** // Check for no merging going on // (There used to be special-case code here when this->region->is_Loop. // It would check for a tributary phi on the backedge that the main phi // trivially, perhaps with a single cast. The unique_input method // does all this and more, by reducing such tributaries to 'this'.) ! Node* uin = unique_input(phase); if (uin != NULL) { return uin; } int true_path = is_diamond_phi(); --- 1147,1157 ---- // Check for no merging going on // (There used to be special-case code here when this->region->is_Loop. // It would check for a tributary phi on the backedge that the main phi // trivially, perhaps with a single cast. The unique_input method // does all this and more, by reducing such tributaries to 'this'.) ! Node* uin = unique_input(phase, false); if (uin != NULL) { return uin; } int true_path = is_diamond_phi();
*** 1163,1174 **** } //-----------------------------unique_input------------------------------------ // Find the unique value, discounting top, self-loops, and casts. // Return top if there are no inputs, and self if there are multiple. ! Node* PhiNode::unique_input(PhaseTransform* phase) { ! // 1) One unique direct input, or // 2) some of the inputs have an intervening ConstraintCast and // the type of input is the same or sharper (more specific) // than the phi's type. // 3) an input is a self loop // --- 1164,1176 ---- } //-----------------------------unique_input------------------------------------ // Find the unique value, discounting top, self-loops, and casts. // Return top if there are no inputs, and self if there are multiple. ! Node* PhiNode::unique_input(PhaseTransform* phase, bool uncast) { ! // 1) One unique direct input, ! // or if uncast is true: // 2) some of the inputs have an intervening ConstraintCast and // the type of input is the same or sharper (more specific) // than the phi's type. // 3) an input is a self loop //
*** 1178,1225 **** // phi \ / / \ / // phi / -- Node* r = in(0); // RegionNode if (r == NULL) return in(1); // Already degraded to a Copy ! Node* uncasted_input = NULL; // The unique uncasted input (ConstraintCasts removed) ! Node* direct_input = NULL; // The unique direct input for (uint i = 1, cnt = req(); i < cnt; ++i) { Node* rc = r->in(i); if (rc == NULL || phase->type(rc) == Type::TOP) continue; // ignore unreachable control path Node* n = in(i); if (n == NULL) continue; ! Node* un = n->uncast(); if (un == NULL || un == this || phase->type(un) == Type::TOP) { continue; // ignore if top, or in(i) and "this" are in a data cycle } ! // Check for a unique uncasted input ! if (uncasted_input == NULL) { ! uncasted_input = un; ! } else if (uncasted_input != un) { ! uncasted_input = NodeSentinel; // no unique uncasted input ! } ! // Check for a unique direct input ! if (direct_input == NULL) { ! direct_input = n; ! } else if (direct_input != n) { ! direct_input = NodeSentinel; // no unique direct input } } ! if (direct_input == NULL) { return phase->C->top(); // no inputs } - assert(uncasted_input != NULL,""); ! if (direct_input != NodeSentinel) { ! return direct_input; // one unique direct input ! } ! if (uncasted_input != NodeSentinel && ! phase->type(uncasted_input)->higher_equal(type())) { ! return uncasted_input; // one unique uncasted input } // Nothing. return NULL; } --- 1180,1215 ---- // phi \ / / \ / // phi / -- Node* r = in(0); // RegionNode if (r == NULL) return in(1); // Already degraded to a Copy ! Node* input = NULL; // The unique direct input (maybe uncasted = ConstraintCasts removed) for (uint i = 1, cnt = req(); i < cnt; ++i) { Node* rc = r->in(i); if (rc == NULL || phase->type(rc) == Type::TOP) continue; // ignore unreachable control path Node* n = in(i); if (n == NULL) continue; ! Node* un = uncast ? n->uncast() : n; if (un == NULL || un == this || phase->type(un) == Type::TOP) { continue; // ignore if top, or in(i) and "this" are in a data cycle } ! // Check for a unique input (maybe uncasted) ! if (input == NULL) { ! input = un; ! } else if (input != un) { ! input = NodeSentinel; // no unique input } } ! if (input == NULL) { return phase->C->top(); // no inputs } ! if (input != NodeSentinel) { ! return input; // one unique direct input } // Nothing. return NULL; }
*** 1648,1658 **** // set_req() above may kill outputs if Phi is referenced // only by itself on the dead (top) control path. return top; } ! Node* uin = unique_input(phase); if (uin == top) { // Simplest case: no alive inputs. if (can_reshape) // IGVN transformation return top; else return NULL; // Identity will return TOP --- 1638,1653 ---- // set_req() above may kill outputs if Phi is referenced // only by itself on the dead (top) control path. return top; } ! bool uncasted = false; ! Node* uin = unique_input(phase, false); ! if (uin == NULL) { ! uncasted = true; ! uin = unique_input(phase, true); ! } if (uin == top) { // Simplest case: no alive inputs. if (can_reshape) // IGVN transformation return top; else return NULL; // Identity will return TOP
*** 1681,1690 **** --- 1676,1710 ---- return NULL; } } } + if (uncasted) { + const Type* phi_type = bottom_type(); + assert(phi_type->isa_int() || phi_type->isa_ptr(), "bad phi type"); + int opcode; + if (phi_type->isa_int()) { + opcode = Op_CastII; + } else { + const Type* uin_type = phase->type(uin); + if (phi_type->join(TypePtr::NOTNULL) == uin_type->join(TypePtr::NOTNULL)) { + opcode = Op_CastPP; + } else { + opcode = Op_CheckCastPP; + } + } + // Add a cast to carry the control dependency of the Phi that is + // going away + Node* cast = ConstraintCastNode::make_cast(opcode, r, uin, phi_type, true); + cast = phase->transform(cast); + // set all inputs to the new cast so the Phi is removed by Identity + for (uint i = 1; i < req(); i++) { + set_req(i, cast); + } + uin = cast; + } + // One unique input. debug_only(Node* ident = Identity(phase)); // The unique input must eventually be detected by the Identity call. #ifdef ASSERT if (ident != uin && !ident->is_top()) {
*** 1697,1707 **** #endif assert(ident == uin || ident->is_top(), "Identity must clean this up"); return NULL; } - Node* opt = NULL; int true_path = is_diamond_phi(); if( true_path != 0 ) { // Check for CMove'ing identity. If it would be unsafe, // handle it here. In the safe case, let Identity handle it. --- 1717,1726 ----
src/share/vm/opto/cfgnode.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File