Skip to content

Commit

Permalink
8322490: cleanup CastNode construction
Browse files Browse the repository at this point in the history
Reviewed-by: chagedorn, phh
  • Loading branch information
caojoshua authored and Paul Hohensee committed Dec 22, 2023
1 parent f695ca5 commit 7263e25
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 112 deletions.
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).
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 @@ -873,8 +873,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 @@ -1141,7 +1140,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 @@ -1169,7 +1170,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 @@ -4312,8 +4315,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 @@ -5940,8 +5942,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

1 comment on commit 7263e25

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

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

Please sign in to comment.