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