Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
2 changes: 1 addition & 1 deletion src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1394,7 +1394,7 @@ void ShenandoahBarrierC2Support::pin_and_expand(PhaseIdealLoop* phase) {
}
if (addr->Opcode() == Op_AddP) {
Node* orig_base = addr->in(AddPNode::Base);
Node* base = new CheckCastPPNode(ctrl, orig_base, orig_base->bottom_type(), ConstraintCastNode::StrongDependency);
Node* base = new CheckCastPPNode(ctrl, orig_base, orig_base->bottom_type(), ConstraintCastNode::NonFloatingNarrowingDependency);
phase->register_new_node(base, ctrl);
if (addr->in(AddPNode::Base) == addr->in((AddPNode::Address))) {
// Field access
Expand Down
13 changes: 7 additions & 6 deletions src/hotspot/share/opto/castnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
#include "opto/type.hpp"
#include "utilities/checkedCast.hpp"

const ConstraintCastNode::DependencyType ConstraintCastNode::RegularDependency(true, true, "regular dependency"); // not pinned, narrows type
const ConstraintCastNode::DependencyType ConstraintCastNode::WidenTypeDependency(true, false, "widen type dependency"); // not pinned, doesn't narrow type
const ConstraintCastNode::DependencyType ConstraintCastNode::StrongDependency(false, true, "strong dependency"); // pinned, narrows type
const ConstraintCastNode::DependencyType ConstraintCastNode::UnconditionalDependency(false, false, "unconditional dependency"); // pinned, doesn't narrow type
const ConstraintCastNode::DependencyType ConstraintCastNode::FloatingNarrowingDependency(true, true, "floating narrowing dependency"); // not pinned, narrows type
const ConstraintCastNode::DependencyType ConstraintCastNode::FloatingNonNarrowingDependency(true, false, "floating non narrowing dependency"); // not pinned, doesn't narrow type
const ConstraintCastNode::DependencyType ConstraintCastNode::NonFloatingNarrowingDependency(false, true, "now floating narrowing dependency"); // pinned, narrows type
const ConstraintCastNode::DependencyType ConstraintCastNode::NonFloatingNonNarrowingDependency(false, false, "non floating non narrowing dependency"); // pinned, doesn't narrow type

//=============================================================================
// If input is already higher or equal to cast type, then this is an identity.
Expand Down Expand Up @@ -607,8 +607,9 @@ Node* ConstraintCastNode::optimize_integer_cast(PhaseGVN* phase, BasicType bt) {
}
const Type* t = Value(phase);
if (t != Type::TOP) {
const TypeInteger* wide_t = widen_type(phase, t, bt);
if (wide_t != t) {
const Type* bottom_t = bottom_type();
const TypeInteger* wide_t = widen_type(phase, bottom_t, bt);
if (wide_t != bottom_t) {
// Widening the type of the Cast (to allow some commoning) causes the Cast to change how it can be optimized (if
// type of its input is narrower than the Cast's type, we can't remove it to not loose the dependency).
return make_with(in(1), wide_t, _dependency.widen_type_dependency());
Expand Down
62 changes: 36 additions & 26 deletions src/hotspot/share/opto/castnode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ class ConstraintCastNode: public TypeNode {
class DependencyType {
public:
DependencyType(bool depends_on_test, bool narrows_type, const char* desc)
: _depends_only_on_test(depends_on_test),
: _floating(depends_on_test),
_narrows_type(narrows_type),
_desc(desc) {
}
NONCOPYABLE(DependencyType);

bool depends_only_on_test() const {
return _depends_only_on_test;
bool floating() const {
return _floating;
}

bool narrows_type() const {
Expand All @@ -65,41 +65,51 @@ class ConstraintCastNode: public TypeNode {
}

uint hash() const {
return (_depends_only_on_test ? 1 : 0) + (_narrows_type ? 2 : 0);
return (_floating ? 1 : 0) + (_narrows_type ? 2 : 0);
}

bool cmp(const DependencyType& other) const {
return _depends_only_on_test == other._depends_only_on_test && _narrows_type == other._narrows_type;
return _floating == other._floating && _narrows_type == other._narrows_type;
}

const DependencyType& widen_type_dependency() const {
if (_depends_only_on_test) {
return WidenTypeDependency;
if (_floating) {
return FloatingNonNarrowingDependency;
}
return UnconditionalDependency;
return NonFloatingNonNarrowingDependency;
}

const DependencyType& pinned_dependency() const {
if (_narrows_type) {
return StrongDependency;
return NonFloatingNarrowingDependency;
}
return UnconditionalDependency;
return NonFloatingNonNarrowingDependency;
}

private:
const bool _depends_only_on_test; // Does this Cast depends on its control input or is it pinned?
const bool _floating; // Does this Cast depends on its control input or is it pinned?
const bool _narrows_type; // Does this Cast narrows the type i.e. if input type is narrower can it be removed?
const char* _desc;
};

public:

static const DependencyType RegularDependency;
static const DependencyType WidenTypeDependency;
static const DependencyType StrongDependency;
static const DependencyType UnconditionalDependency;
// All the possible combinations of floating/narrowing. Example use cases for each:
// FloatingNarrowingDependency is used for range checks: the range check CastII is dependent on the range check and if
// its input's type is narrower than the type of the range check, it's safe to be removed.
// NonFloatingNonNarrowingDependency is used when a floating node is sunk out of loop: we don't want the cast that
// forces the node to be out of loop to be removed in any case
// NonFloatingNarrowingDependency is used when an array access is no longer dependent on a single range check (range
// check smearing for instance)
// FloatingNonNarrowingDependency is used after loop opts when Cast nodes' types are widen so Casts that only differ
// by slightly different types can common. Given the type carried by the Cast is no longer accurate, removing a Cast
// because its input has a narrower type causes the dependency carried by the Cast to be lost
static const DependencyType FloatingNarrowingDependency;
static const DependencyType FloatingNonNarrowingDependency;
static const DependencyType NonFloatingNarrowingDependency;
static const DependencyType NonFloatingNonNarrowingDependency;

protected:
protected:
const DependencyType& _dependency;
virtual bool cmp( const Node &n ) const;
virtual uint size_of() const;
Expand Down Expand Up @@ -132,8 +142,8 @@ class ConstraintCastNode: public TypeNode {
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
virtual int Opcode() const;
virtual uint ideal_reg() const = 0;
bool carry_dependency() const { return !_dependency.cmp(RegularDependency); }
virtual bool depends_only_on_test() const { return _dependency.depends_only_on_test(); }
bool carry_dependency() const { return !_dependency.cmp(FloatingNarrowingDependency); }
virtual bool depends_only_on_test() const { return _dependency.floating(); }
const DependencyType& dependency() const { return _dependency; }
TypeNode* dominating_cast(PhaseGVN* gvn, PhaseTransform* pt) const;
static Node* make_cast_for_basic_type(Node* c, Node* n, const Type* t, const DependencyType& dependency, BasicType bt);
Expand Down Expand Up @@ -169,7 +179,7 @@ class CastIINode: public ConstraintCastNode {
virtual uint size_of() const;

public:
CastIINode(Node* ctrl, Node* n, const Type* t, const DependencyType& dependency = RegularDependency, bool range_check_dependency = false, const TypeTuple* types = nullptr)
CastIINode(Node* ctrl, Node* n, const Type* t, const DependencyType& dependency = FloatingNarrowingDependency, bool range_check_dependency = false, const TypeTuple* types = nullptr)
: ConstraintCastNode(ctrl, n, t, dependency, types), _range_check_dependency(range_check_dependency) {
assert(ctrl != nullptr, "control must be set");
init_class_id(Class_CastII);
Expand Down Expand Up @@ -199,7 +209,7 @@ class CastIINode: public ConstraintCastNode {

class CastLLNode: public ConstraintCastNode {
public:
CastLLNode(Node* ctrl, Node* n, const Type* t, const DependencyType& dependency = RegularDependency, const TypeTuple* types = nullptr)
CastLLNode(Node* ctrl, Node* n, const Type* t, const DependencyType& dependency = FloatingNarrowingDependency, const TypeTuple* types = nullptr)
: ConstraintCastNode(ctrl, n, t, dependency, types) {
assert(ctrl != nullptr, "control must be set");
init_class_id(Class_CastLL);
Expand All @@ -220,7 +230,7 @@ class CastLLNode: public ConstraintCastNode {

class CastHHNode: public ConstraintCastNode {
public:
CastHHNode(Node* ctrl, Node* n, const Type* t, const DependencyType& dependency = RegularDependency, const TypeTuple* types = nullptr)
CastHHNode(Node* ctrl, Node* n, const Type* t, const DependencyType& dependency = FloatingNarrowingDependency, const TypeTuple* types = nullptr)
: ConstraintCastNode(ctrl, n, t, dependency, types) {
assert(ctrl != nullptr, "control must be set");
init_class_id(Class_CastHH);
Expand All @@ -231,7 +241,7 @@ class CastHHNode: public ConstraintCastNode {

class CastFFNode: public ConstraintCastNode {
public:
CastFFNode(Node* ctrl, Node* n, const Type* t, const DependencyType& dependency = RegularDependency, const TypeTuple* types = nullptr)
CastFFNode(Node* ctrl, Node* n, const Type* t, const DependencyType& dependency = FloatingNarrowingDependency, const TypeTuple* types = nullptr)
: ConstraintCastNode(ctrl, n, t, dependency, types) {
assert(ctrl != nullptr, "control must be set");
init_class_id(Class_CastFF);
Expand All @@ -242,7 +252,7 @@ class CastFFNode: public ConstraintCastNode {

class CastDDNode: public ConstraintCastNode {
public:
CastDDNode(Node* ctrl, Node* n, const Type* t, const DependencyType& dependency = RegularDependency, const TypeTuple* types = nullptr)
CastDDNode(Node* ctrl, Node* n, const Type* t, const DependencyType& dependency = FloatingNarrowingDependency, const TypeTuple* types = nullptr)
: ConstraintCastNode(ctrl, n, t, dependency, types) {
assert(ctrl != nullptr, "control must be set");
init_class_id(Class_CastDD);
Expand All @@ -253,7 +263,7 @@ class CastDDNode: public ConstraintCastNode {

class CastVVNode: public ConstraintCastNode {
public:
CastVVNode(Node* ctrl, Node* n, const Type* t, const DependencyType& dependency = RegularDependency, const TypeTuple* types = nullptr)
CastVVNode(Node* ctrl, Node* n, const Type* t, const DependencyType& dependency = FloatingNarrowingDependency, const TypeTuple* types = nullptr)
: ConstraintCastNode(ctrl, n, t, dependency, types) {
assert(ctrl != nullptr, "control must be set");
init_class_id(Class_CastVV);
Expand All @@ -267,7 +277,7 @@ class CastVVNode: public ConstraintCastNode {
// cast pointer to pointer (different type)
class CastPPNode: public ConstraintCastNode {
public:
CastPPNode (Node* ctrl, Node* n, const Type* t, const DependencyType& dependency = RegularDependency, const TypeTuple* types = nullptr)
CastPPNode (Node* ctrl, Node* n, const Type* t, const DependencyType& dependency = FloatingNarrowingDependency, const TypeTuple* types = nullptr)
: ConstraintCastNode(ctrl, n, t, dependency, types) {
init_class_id(Class_CastPP);
}
Expand All @@ -279,7 +289,7 @@ class CastPPNode: public ConstraintCastNode {
// for _checkcast, cast pointer to pointer (different type), without JOIN,
class CheckCastPPNode: public ConstraintCastNode {
public:
CheckCastPPNode(Node* ctrl, Node* n, const Type* t, const DependencyType& dependency = RegularDependency, const TypeTuple* types = nullptr)
CheckCastPPNode(Node* ctrl, Node* n, const Type* t, const DependencyType& dependency = FloatingNarrowingDependency, const TypeTuple* types = nullptr)
: ConstraintCastNode(ctrl, n, t, dependency, types) {
assert(ctrl != nullptr, "control must be set");
init_class_id(Class_CheckCastPP);
Expand Down
10 changes: 5 additions & 5 deletions src/hotspot/share/opto/cfgnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2191,7 +2191,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 = new CastPPNode(r, uin, phi_type, ConstraintCastNode::StrongDependency, extra_types);
cast = new CastPPNode(r, uin, phi_type, ConstraintCastNode::NonFloatingNarrowingDependency, 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 @@ -2201,7 +2201,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 = new CastPPNode(r, uin, TypePtr::NOTNULL, ConstraintCastNode::StrongDependency, extra_types);
cast = new CastPPNode(r, uin, TypePtr::NOTNULL, ConstraintCastNode::NonFloatingNarrowingDependency, extra_types);
}

// If the type of phi and uin, both casted to not null,
Expand All @@ -2213,14 +2213,14 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) {
cast = phase->transform(cast);
n = cast;
}
cast = new CheckCastPPNode(r, n, phi_type, ConstraintCastNode::StrongDependency, extra_types);
cast = new CheckCastPPNode(r, n, phi_type, ConstraintCastNode::NonFloatingNarrowingDependency, extra_types);
}
if (cast == nullptr) {
cast = new CastPPNode(r, uin, phi_type, ConstraintCastNode::StrongDependency, extra_types);
cast = new CastPPNode(r, uin, phi_type, ConstraintCastNode::NonFloatingNarrowingDependency, extra_types);
}
}
} else {
cast = ConstraintCastNode::make_cast_for_type(r, uin, phi_type, ConstraintCastNode::StrongDependency, extra_types);
cast = ConstraintCastNode::make_cast_for_type(r, uin, phi_type, ConstraintCastNode::NonFloatingNarrowingDependency, extra_types);
}
assert(cast != nullptr, "cast should be set");
cast = phase->transform(cast);
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/opto/compile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4570,7 +4570,7 @@ Node* Compile::constrained_convI2L(PhaseGVN* phase, Node* value, const TypeInt*
// 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 = new CastIINode(ctrl, value, itype, carry_dependency ? ConstraintCastNode::StrongDependency : ConstraintCastNode::RegularDependency, true /* range check dependency */);
value = new CastIINode(ctrl, value, itype, carry_dependency ? ConstraintCastNode::NonFloatingNarrowingDependency : ConstraintCastNode::FloatingNarrowingDependency, true /* range check dependency */);
value = phase->transform(value);
}
const TypeLong* ltype = TypeLong::make(itype->_lo, itype->_hi, itype->_widen);
Expand Down
6 changes: 3 additions & 3 deletions src/hotspot/share/opto/escape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,7 @@ Node* ConnectionGraph::specialize_castpp(Node* castpp, Node* base, Node* current
_igvn->_worklist.push(current_control);
_igvn->_worklist.push(control_successor);

return _igvn->transform(ConstraintCastNode::make_cast_for_type(not_eq_control, base, _igvn->type(castpp), ConstraintCastNode::UnconditionalDependency, nullptr));
return _igvn->transform(ConstraintCastNode::make_cast_for_type(not_eq_control, base, _igvn->type(castpp), ConstraintCastNode::NonFloatingNonNarrowingDependency, nullptr));
}

Node* ConnectionGraph::split_castpp_load_through_phi(Node* curr_addp, Node* curr_load, Node* region, GrowableArray<Node*>* bases_for_loads, GrowableArray<Node *> &alloc_worklist) {
Expand Down Expand Up @@ -1220,7 +1220,7 @@ bool ConnectionGraph::reduce_phi_on_safepoints_helper(Node* ophi, Node* cast, No
Node* nsr_merge_pointer = ophi;
if (cast != nullptr) {
const Type* new_t = merge_t->meet(TypePtr::NULL_PTR);
nsr_merge_pointer = _igvn->transform(ConstraintCastNode::make_cast_for_type(cast->in(0), cast->in(1), new_t, ConstraintCastNode::RegularDependency, nullptr));
nsr_merge_pointer = _igvn->transform(ConstraintCastNode::make_cast_for_type(cast->in(0), cast->in(1), new_t, ConstraintCastNode::FloatingNarrowingDependency, nullptr));
}

for (uint spi = 0; spi < safepoints.size(); spi++) {
Expand Down Expand Up @@ -1357,7 +1357,7 @@ void ConnectionGraph::reset_scalar_replaceable_entries(PhiNode* ophi) {
}

if (change) {
Node* new_cast = ConstraintCastNode::make_cast_for_type(out->in(0), out->in(1), out_new_t, ConstraintCastNode::StrongDependency, nullptr);
Node* new_cast = ConstraintCastNode::make_cast_for_type(out->in(0), out->in(1), out_new_t, ConstraintCastNode::NonFloatingNarrowingDependency, nullptr);
_igvn->replace_node(out, new_cast);
_igvn->register_new_node_with_optimizer(new_cast);
}
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/opto/library_call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1182,7 +1182,7 @@ bool LibraryCallKit::inline_preconditions_checkIndex(BasicType bt) {
jlong upper_bound = _gvn.type(length)->is_integer(bt)->hi_as_long();
Node* casted_length = ConstraintCastNode::make_cast_for_basic_type(
control(), length, TypeInteger::make(0, upper_bound, Type::WidenMax, bt),
ConstraintCastNode::RegularDependency, bt);
ConstraintCastNode::FloatingNarrowingDependency, bt);
casted_length = _gvn.transform(casted_length);
replace_in_map(length, casted_length);
length = casted_length;
Expand Down Expand Up @@ -1212,7 +1212,7 @@ bool LibraryCallKit::inline_preconditions_checkIndex(BasicType bt) {
// index is now known to be >= 0 and < length, cast it
Node* result = ConstraintCastNode::make_cast_for_basic_type(
control(), index, TypeInteger::make(0, upper_bound, Type::WidenMax, bt),
ConstraintCastNode::RegularDependency, bt);
ConstraintCastNode::FloatingNarrowingDependency, bt);
result = _gvn.transform(result);
set_result(result);
replace_in_map(index, result);
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/opto/loopTransform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1366,7 +1366,7 @@ Node *PhaseIdealLoop::clone_up_backedge_goo(Node *back_ctrl, Node *preheader_ctr
// the backedge of the main or post loop is removed, a Div node won't be able to float above the zero trip guard of the
// loop and can't execute even if the loop is not reached.
void PhaseIdealLoop::cast_incr_before_loop(Node* incr, Node* ctrl, CountedLoopNode* loop) {
Node* castii = new CastIINode(ctrl, incr, TypeInt::INT, ConstraintCastNode::UnconditionalDependency);
Node* castii = new CastIINode(ctrl, incr, TypeInt::INT, ConstraintCastNode::NonFloatingNonNarrowingDependency);
register_new_node(castii, ctrl);
Node* phi = loop->phi();
assert(phi->in(LoopNode::EntryControl) == incr, "replacing wrong input?");
Expand Down Expand Up @@ -3208,7 +3208,7 @@ bool IdealLoopTree::do_remove_empty_loop(PhaseIdealLoop *phase) {
Node* cast_ii = ConstraintCastNode::make_cast_for_basic_type(
cl->in(LoopNode::EntryControl), exact_limit,
phase->_igvn.type(exact_limit),
ConstraintCastNode::UnconditionalDependency, T_INT);
ConstraintCastNode::NonFloatingNonNarrowingDependency, T_INT);
phase->register_new_node(cast_ii, cl->in(LoopNode::EntryControl));

Node* final_iv = new SubINode(cast_ii, cl->stride());
Expand Down
Loading