Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/hotspot/share/opto/callnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1652,8 +1652,7 @@ Node *AllocateArrayNode::make_ideal_length(const TypeOopPtr* oop_type, PhaseValu
// propagate the fact that the array length must be positive.
InitializeNode* init = initialization();
if (init != nullptr) {
length = new CastIINode(length, narrow_length_type);
length->set_req(TypeFunc::Control, init->proj_out_or_null(TypeFunc::Control));
length = new CastIINode(init->proj_out_or_null(TypeFunc::Control), length, narrow_length_type);
}
}
}
Expand Down
69 changes: 13 additions & 56 deletions src/hotspot/share/opto/castnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,54 +123,12 @@ uint ConstraintCastNode::size_of() const {
return sizeof(*this);
}

Node* ConstraintCastNode::make_cast(int opcode, Node* c, Node* n, const Type* t, DependencyType dependency,
const TypeTuple* extra_types) {
switch(opcode) {
case Op_CastII: {
Node* cast = new CastIINode(n, t, dependency, false, extra_types);
cast->set_req(0, c);
return cast;
}
case Op_CastLL: {
Node* cast = new CastLLNode(n, t, dependency, extra_types);
cast->set_req(0, c);
return cast;
}
case Op_CastPP: {
Node* cast = new CastPPNode(n, t, dependency, extra_types);
cast->set_req(0, c);
return cast;
}
case Op_CastFF: {
Node* cast = new CastFFNode(n, t, dependency, extra_types);
cast->set_req(0, c);
return cast;
}
case Op_CastDD: {
Node* cast = new CastDDNode(n, t, dependency, extra_types);
cast->set_req(0, c);
return cast;
}
case Op_CastVV: {
Node* cast = new CastVVNode(n, t, dependency, extra_types);
cast->set_req(0, c);
return cast;
}
case Op_CheckCastPP: return new CheckCastPPNode(c, n, t, dependency, extra_types);
default:
fatal("Bad opcode %d", opcode);
}
return nullptr;
}

Node* ConstraintCastNode::make(Node* c, Node *n, const Type *t, DependencyType dependency, BasicType bt) {
Node* ConstraintCastNode::make_cast_for_basic_type(Node* c, Node* n, const Type* t, DependencyType dependency, BasicType bt) {
switch(bt) {
case T_INT: {
return make_cast(Op_CastII, c, n, t, dependency, nullptr);
}
case T_LONG: {
return make_cast(Op_CastLL, c, n, t, dependency, nullptr);
}
case T_INT:
return new CastIINode(c, n, t, dependency);
case T_LONG:
return new CastLLNode(c, n, t, dependency);
default:
fatal("Bad basic type %s", type2name(bt));
}
Expand Down Expand Up @@ -267,7 +225,7 @@ const Type* CastIINode::Value(PhaseGVN* phase) const {
}

static Node* find_or_make_integer_cast(PhaseIterGVN* igvn, Node* parent, Node* control, const TypeInteger* type, ConstraintCastNode::DependencyType dependency, BasicType bt) {
Node* n = ConstraintCastNode::make(control, parent, type, dependency, bt);
Node* n = ConstraintCastNode::make_cast_for_basic_type(control, parent, type, dependency, bt);
Node* existing = igvn->hash_find_insert(n);
if (existing != nullptr) {
n->destruct(igvn);
Expand Down Expand Up @@ -487,21 +445,20 @@ Node* CastP2XNode::Identity(PhaseGVN* phase) {

Node* ConstraintCastNode::make_cast_for_type(Node* c, Node* in, const Type* type, DependencyType dependency,
const TypeTuple* types) {
Node* cast= nullptr;
if (type->isa_int()) {
cast = make_cast(Op_CastII, c, in, type, dependency, types);
return new CastIINode(c, in, type, dependency, false, types);
} else if (type->isa_long()) {
cast = make_cast(Op_CastLL, c, in, type, dependency, types);
return new CastLLNode(c, in, type, dependency, types);
} else if (type->isa_float()) {
cast = make_cast(Op_CastFF, c, in, type, dependency, types);
return new CastFFNode(c, in, type, dependency, types);
} else if (type->isa_double()) {
cast = make_cast(Op_CastDD, c, in, type, dependency, types);
return new CastDDNode(c, in, type, dependency, types);
} else if (type->isa_vect()) {
cast = make_cast(Op_CastVV, c, in, type, dependency, types);
return new CastVVNode(c, in, type, dependency, types);
} else if (type->isa_ptr()) {
cast = make_cast(Op_CastPP, c, in, type, dependency, types);
return new CastPPNode(c, in, type, dependency, types);
}
return cast;
fatal("unreachable. Invalid cast type.");
}

Node* ConstraintCastNode::optimize_integer_cast(PhaseGVN* phase, BasicType bt) {
Expand Down
43 changes: 18 additions & 25 deletions src/hotspot/share/opto/castnode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,11 @@ class ConstraintCastNode: public TypeNode {
const TypeTuple* _extra_types;

public:
ConstraintCastNode(Node* n, const Type* t, ConstraintCastNode::DependencyType dependency,
ConstraintCastNode(Node* ctrl, Node* n, const Type* t, ConstraintCastNode::DependencyType dependency,
const TypeTuple* extra_types)
: TypeNode(t,2), _dependency(dependency), _extra_types(extra_types) {
init_class_id(Class_ConstraintCast);
init_req(0, ctrl);
init_req(1, n);
}
virtual Node* Identity(PhaseGVN* phase);
Expand All @@ -68,8 +69,7 @@ class ConstraintCastNode: public TypeNode {
virtual bool depends_only_on_test() const { return _dependency == RegularDependency; }
bool carry_dependency() const { return _dependency != RegularDependency; }
TypeNode* dominating_cast(PhaseGVN* gvn, PhaseTransform* pt) const;
static Node* make_cast(int opcode, Node* c, Node* n, const Type* t, DependencyType dependency, const TypeTuple* extra_types);
static Node* make(Node* c, Node *n, const Type *t, DependencyType dependency, BasicType bt);
static Node* make_cast_for_basic_type(Node* c, Node* n, const Type* t, DependencyType dependency, BasicType bt);

#ifndef PRODUCT
virtual void dump_spec(outputStream *st) const;
Expand Down Expand Up @@ -102,13 +102,12 @@ class CastIINode: public ConstraintCastNode {

public:
CastIINode(Node* n, const Type* t, DependencyType dependency = RegularDependency, bool range_check_dependency = false, const TypeTuple* types = nullptr)
: ConstraintCastNode(n, t, dependency, types), _range_check_dependency(range_check_dependency) {
: ConstraintCastNode(nullptr, n, t, dependency, types), _range_check_dependency(range_check_dependency) {
init_class_id(Class_CastII);
}
CastIINode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, bool range_check_dependency = false)
: ConstraintCastNode(n, t, dependency, nullptr), _range_check_dependency(range_check_dependency) {
CastIINode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, bool range_check_dependency = false, const TypeTuple* types = nullptr)
: ConstraintCastNode(ctrl, n, t, dependency, types), _range_check_dependency(range_check_dependency) {
init_class_id(Class_CastII);
init_req(0, ctrl);
}
virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegI; }
Expand All @@ -131,13 +130,8 @@ class CastIINode: public ConstraintCastNode {

class CastLLNode: public ConstraintCastNode {
public:
CastLLNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency)
: ConstraintCastNode(n, t, dependency, nullptr) {
init_class_id(Class_CastLL);
init_req(0, ctrl);
}
CastLLNode(Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
: ConstraintCastNode(n, t, dependency, types) {
CastLLNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
: ConstraintCastNode(ctrl, n, t, dependency, types) {
init_class_id(Class_CastLL);
}

Expand All @@ -149,8 +143,8 @@ class CastLLNode: public ConstraintCastNode {

class CastFFNode: public ConstraintCastNode {
public:
CastFFNode(Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
: ConstraintCastNode(n, t, dependency, types) {
CastFFNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
: ConstraintCastNode(ctrl, n, t, dependency, types) {
init_class_id(Class_CastFF);
}
virtual int Opcode() const;
Expand All @@ -159,8 +153,8 @@ class CastFFNode: public ConstraintCastNode {

class CastDDNode: public ConstraintCastNode {
public:
CastDDNode(Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
: ConstraintCastNode(n, t, dependency, types) {
CastDDNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
: ConstraintCastNode(ctrl, n, t, dependency, types) {
init_class_id(Class_CastDD);
}
virtual int Opcode() const;
Expand All @@ -169,8 +163,8 @@ class CastDDNode: public ConstraintCastNode {

class CastVVNode: public ConstraintCastNode {
public:
CastVVNode(Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
: ConstraintCastNode(n, t, dependency, types) {
CastVVNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
: ConstraintCastNode(ctrl, n, t, dependency, types) {
init_class_id(Class_CastVV);
}
virtual int Opcode() const;
Expand All @@ -182,8 +176,8 @@ class CastVVNode: public ConstraintCastNode {
// cast pointer to pointer (different type)
class CastPPNode: public ConstraintCastNode {
public:
CastPPNode (Node *n, const Type *t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
: ConstraintCastNode(n, t, dependency, types) {
CastPPNode (Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
: ConstraintCastNode(ctrl, n, t, dependency, types) {
}
virtual int Opcode() const;
virtual uint ideal_reg() const { return Op_RegP; }
Expand All @@ -193,10 +187,9 @@ class CastPPNode: public ConstraintCastNode {
// for _checkcast, cast pointer to pointer (different type), without JOIN,
class CheckCastPPNode: public ConstraintCastNode {
public:
CheckCastPPNode(Node *c, Node *n, const Type *t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
: ConstraintCastNode(n, t, dependency, types) {
CheckCastPPNode(Node* ctrl, Node* n, const Type* t, DependencyType dependency = RegularDependency, const TypeTuple* types = nullptr)
: ConstraintCastNode(ctrl, n, t, dependency, types) {
init_class_id(Class_CheckCastPP);
init_req(0, c);
}

virtual const Type* Value(PhaseGVN* phase) const;
Expand Down
12 changes: 4 additions & 8 deletions src/hotspot/share/opto/cfgnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2148,8 +2148,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
if (phi_type->isa_ptr()) {
const Type* uin_type = phase->type(uin);
if (!phi_type->isa_oopptr() && !uin_type->isa_oopptr()) {
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, ConstraintCastNode::StrongDependency,
extra_types);
cast = new CastPPNode(r, uin, phi_type, ConstraintCastNode::StrongDependency, extra_types);
} else {
// Use a CastPP for a cast to not null and a CheckCastPP for
// a cast to a new klass (and both if both null-ness and
Expand All @@ -2159,8 +2158,7 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// null, uin's type must be casted to not null
if (phi_type->join(TypePtr::NOTNULL) == phi_type->remove_speculative() &&
uin_type->join(TypePtr::NOTNULL) != uin_type->remove_speculative()) {
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, TypePtr::NOTNULL,
ConstraintCastNode::StrongDependency, extra_types);
cast = new CastPPNode(r, uin, TypePtr::NOTNULL, ConstraintCastNode::StrongDependency, extra_types);
}

// If the type of phi and uin, both casted to not null,
Expand All @@ -2172,12 +2170,10 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
cast = phase->transform(cast);
n = cast;
}
cast = ConstraintCastNode::make_cast(Op_CheckCastPP, r, n, phi_type, ConstraintCastNode::StrongDependency,
extra_types);
cast = new CheckCastPPNode(r, uin, phi_type, ConstraintCastNode::StrongDependency, extra_types);
}
if (cast == nullptr) {
cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, ConstraintCastNode::StrongDependency,
extra_types);
cast = new CastPPNode(r, uin, phi_type, ConstraintCastNode::StrongDependency, extra_types);
}
}
} else {
Expand Down
3 changes: 1 addition & 2 deletions src/hotspot/share/opto/compile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4471,12 +4471,11 @@ Node* Compile::conv_I2X_index(PhaseGVN* phase, Node* idx, const TypeInt* sizetyp
Node* Compile::constrained_convI2L(PhaseGVN* phase, Node* value, const TypeInt* itype, Node* ctrl, bool carry_dependency) {
if (ctrl != nullptr) {
// Express control dependency by a CastII node with a narrow type.
value = new CastIINode(value, itype, carry_dependency ? ConstraintCastNode::StrongDependency : ConstraintCastNode::RegularDependency, true /* range check dependency */);
// Make the CastII node dependent on the control input to prevent the narrowed ConvI2L
// node from floating above the range check during loop optimizations. Otherwise, the
// ConvI2L node may be eliminated independently of the range check, causing the data path
// to become TOP while the control path is still there (although it's unreachable).
Comment on lines 4474 to 4477
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be cleaner to move this comment block above the creation of the cast node

value->set_req(0, ctrl);
value = new CastIINode(ctrl, value, itype, carry_dependency ? ConstraintCastNode::StrongDependency : ConstraintCastNode::RegularDependency, true /* range check dependency */);
value = phase->transform(value);
}
const TypeLong* ltype = TypeLong::make(itype->_lo, itype->_hi, itype->_widen);
Expand Down
3 changes: 1 addition & 2 deletions src/hotspot/share/opto/graphKit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1439,8 +1439,7 @@ Node* GraphKit::cast_not_null(Node* obj, bool do_replace_in_map) {
// Object is already not-null?
if( t == t_not_null ) return obj;

Node *cast = new CastPPNode(obj,t_not_null);
cast->init_req(0, control());
Node* cast = new CastPPNode(control(), obj,t_not_null);
cast = _gvn.transform( cast );

// Scan for instances of 'obj' in the current JVM mapping.
Expand Down
17 changes: 9 additions & 8 deletions src/hotspot/share/opto/library_call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -872,8 +872,7 @@ inline Node* LibraryCallKit::generate_negative_guard(Node* index, RegionNode* re
Node* is_neg = generate_guard(bol_lt, region, PROB_MIN);
if (is_neg != nullptr && pos_index != nullptr) {
// Emulate effect of Parse::adjust_map_after_if.
Node* ccast = new CastIINode(index, TypeInt::POS);
ccast->set_req(0, control());
Node* ccast = new CastIINode(control(), index, TypeInt::POS);
(*pos_index) = _gvn.transform(ccast);
}
return is_neg;
Expand Down Expand Up @@ -1140,7 +1139,9 @@ bool LibraryCallKit::inline_preconditions_checkIndex(BasicType bt) {

// length is now known positive, add a cast node to make this explicit
jlong upper_bound = _gvn.type(length)->is_integer(bt)->hi_as_long();
Node* casted_length = ConstraintCastNode::make(control(), length, TypeInteger::make(0, upper_bound, Type::WidenMax, bt), ConstraintCastNode::RegularDependency, bt);
Node* casted_length = ConstraintCastNode::make_cast_for_basic_type(
control(), length, TypeInteger::make(0, upper_bound, Type::WidenMax, bt),
ConstraintCastNode::RegularDependency, bt);
casted_length = _gvn.transform(casted_length);
replace_in_map(length, casted_length);
length = casted_length;
Expand Down Expand Up @@ -1168,7 +1169,9 @@ bool LibraryCallKit::inline_preconditions_checkIndex(BasicType bt) {
}

// index is now known to be >= 0 and < length, cast it
Node* result = ConstraintCastNode::make(control(), index, TypeInteger::make(0, upper_bound, Type::WidenMax, bt), ConstraintCastNode::RegularDependency, bt);
Node* result = ConstraintCastNode::make_cast_for_basic_type(
control(), index, TypeInteger::make(0, upper_bound, Type::WidenMax, bt),
ConstraintCastNode::RegularDependency, bt);
result = _gvn.transform(result);
set_result(result);
replace_in_map(index, result);
Expand Down Expand Up @@ -4288,8 +4291,7 @@ bool LibraryCallKit::inline_array_copyOf(bool is_copyOfRange) {
// Improve the klass node's type from the new optimistic assumption:
ciKlass* ak = ciArrayKlass::make(env()->Object_klass());
const Type* akls = TypeKlassPtr::make(TypePtr::NotNull, ak, 0/*offset*/);
Node* cast = new CastPPNode(klass_node, akls);
cast->init_req(0, control());
Node* cast = new CastPPNode(control(), klass_node, akls);
klass_node = _gvn.transform(cast);
}

Expand Down Expand Up @@ -5916,8 +5918,7 @@ bool LibraryCallKit::inline_multiplyToLen() {
} __ else_(); {
// Update graphKit memory and control from IdealKit.
sync_kit(ideal);
Node *cast = new CastPPNode(z, TypePtr::NOTNULL);
cast->init_req(0, control());
Node* cast = new CastPPNode(control(), z, TypePtr::NOTNULL);
_gvn.set_type(cast, cast->bottom_type());
C->record_for_igvn(cast);

Expand Down
11 changes: 6 additions & 5 deletions src/hotspot/share/opto/loopTransform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1284,8 +1284,7 @@ Node *PhaseIdealLoop::clone_up_backedge_goo(Node *back_ctrl, Node *preheader_ctr
}

Node* PhaseIdealLoop::cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop) {
Node* castii = new CastIINode(incr, TypeInt::INT, ConstraintCastNode::UnconditionalDependency);
castii->set_req(0, ctrl);
Node* castii = new CastIINode(ctrl, incr, TypeInt::INT, ConstraintCastNode::UnconditionalDependency);
register_new_node(castii, ctrl);
for (DUIterator_Fast imax, i = incr->fast_outs(imax); i < imax; i++) {
Node* n = incr->fast_out(i);
Expand Down Expand Up @@ -3161,9 +3160,8 @@ void PhaseIdealLoop::do_range_check(IdealLoopTree *loop, Node_List &old_new) {
// The new loop limit is <= (for an upward loop) >= (for a downward loop) than the orig limit.
// The expression that computes the new limit may be too complicated and the computed type of the new limit
// may be too pessimistic. A CastII here guarantees it's not lost.
main_limit = new CastIINode(main_limit, TypeInt::make(upward ? min_jint : orig_limit_t->_lo,
main_limit = new CastIINode(pre_ctrl, main_limit, TypeInt::make(upward ? min_jint : orig_limit_t->_lo,
upward ? orig_limit_t->_hi : max_jint, Type::WidenMax));
main_limit->init_req(0, pre_ctrl);
register_new_node(main_limit, pre_ctrl);
// Hack the now-private loop bounds
_igvn.replace_input_of(main_cmp, 2, main_limit);
Expand Down Expand Up @@ -3422,7 +3420,10 @@ bool IdealLoopTree::do_remove_empty_loop(PhaseIdealLoop *phase) {
Node* exact_limit = phase->exact_limit(this);

// We need to pin the exact limit to prevent it from floating above the zero trip guard.
Node* cast_ii = ConstraintCastNode::make(cl->in(LoopNode::EntryControl), exact_limit, phase->_igvn.type(exact_limit), ConstraintCastNode::UnconditionalDependency, T_INT);
Node* cast_ii = ConstraintCastNode::make_cast_for_basic_type(
cl->in(LoopNode::EntryControl), exact_limit,
phase->_igvn.type(exact_limit),
ConstraintCastNode::UnconditionalDependency, T_INT);
phase->register_new_node(cast_ii, cl->in(LoopNode::EntryControl));

Node* final_iv = new SubINode(cast_ii, cl->stride());
Expand Down
5 changes: 2 additions & 3 deletions src/hotspot/share/opto/parse2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1730,10 +1730,10 @@ void Parse::sharpen_type_after_if(BoolTest::mask btest,
const Type* tboth = tcon->join_speculative(tval);
if (tboth == tval) break; // Nothing to gain.
if (tcon->isa_int()) {
ccast = new CastIINode(val, tboth);
ccast = new CastIINode(control(), val, tboth);
} else if (tcon == TypePtr::NULL_PTR) {
// Cast to null, but keep the pointer identity temporarily live.
ccast = new CastPPNode(val, tboth);
ccast = new CastPPNode(control(), val, tboth);
} else {
const TypeF* tf = tcon->isa_float_constant();
const TypeD* td = tcon->isa_double_constant();
Expand Down Expand Up @@ -1764,7 +1764,6 @@ void Parse::sharpen_type_after_if(BoolTest::mask btest,
assert(tcc != tval && tcc->higher_equal(tval), "must improve");
// Delay transform() call to allow recovery of pre-cast value
// at the control merge.
ccast->set_req(0, control());
_gvn.set_type_bottom(ccast);
record_for_igvn(ccast);
cast = ccast;
Expand Down
Loading