Skip to content

Commit

Permalink
Opaque4 -> NotNull
Browse files Browse the repository at this point in the history
  • Loading branch information
chhagedorn committed Oct 15, 2024
1 parent a755af2 commit 6eae11a
Show file tree
Hide file tree
Showing 11 changed files with 41 additions and 45 deletions.
2 changes: 1 addition & 1 deletion src/hotspot/share/opto/classes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ macro(Opaque1)
macro(OpaqueLoopInit)
macro(OpaqueLoopStride)
macro(OpaqueZeroTripGuard)
macro(Opaque4)
macro(OpaqueNotNull)
macro(OpaqueInitializedAssertionPredicate)
macro(OpaqueTemplateAssertionPredicate)
macro(ProfileBoolean)
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/opto/escape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,8 +574,8 @@ bool ConnectionGraph::can_reduce_check_users(Node* n, uint nesting) const {
// CmpP/N used by the If controlling the cast.
if (use->in(0)->is_IfTrue() || use->in(0)->is_IfFalse()) {
Node* iff = use->in(0)->in(0);
// We may have Opaque4 node between If and Bool nodes.
// Bail out in such case - we need to preserve Opaque4 for correct
// We may have OpaqueNotNull node between If and Bool nodes.
// Bail out in such case - we need to preserve OpaqueNotNull for correct
// processing predicates after loop opts.
bool can_reduce = (iff->Opcode() == Op_If) && iff->in(1)->is_Bool() && iff->in(1)->in(1)->is_Cmp();
if (can_reduce) {
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/opto/graphKit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1458,7 +1458,7 @@ Node* GraphKit::cast_not_null(Node* obj, bool do_replace_in_map) {
// In that case that data path will die and we need the control path
// to become dead as well to keep the graph consistent. So we have to
// add a check for null for which one branch can't be taken. It uses
// an Opaque4 node that will cause the check to be removed after loop
// an OpaqueNotNull node that will cause the check to be removed after loop
// opts so the test goes away and the compiled code doesn't execute a
// useless check.
Node* GraphKit::must_be_not_null(Node* value, bool do_replace_in_map) {
Expand All @@ -1467,7 +1467,7 @@ Node* GraphKit::must_be_not_null(Node* value, bool do_replace_in_map) {
}
Node* chk = _gvn.transform(new CmpPNode(value, null()));
Node *tst = _gvn.transform(new BoolNode(chk, BoolTest::ne));
Node* opaq = _gvn.transform(new Opaque4Node(C, tst, intcon(1)));
Node* opaq = _gvn.transform(new OpaqueNotNullNode(C, tst, intcon(1)));
IfNode *iff = new IfNode(control(), opaq, PROB_MAX, COUNT_UNKNOWN);
_gvn.set_type(iff, iff->Value(&_gvn));
if (!tst->is_Con()) {
Expand Down
10 changes: 6 additions & 4 deletions src/hotspot/share/opto/loopTransform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1189,8 +1189,10 @@ bool IdealLoopTree::policy_range_check(PhaseIdealLoop* phase, bool provisional,
continue;
}
if (!bol->is_Bool()) {
assert(bol->is_Opaque4() || bol->is_OpaqueInitializedAssertionPredicate(),
"Opaque node of non-null-check or of Initialized Assertion Predicate");
assert(bol->is_OpaqueNotNull() ||
bol->is_OpaqueTemplateAssertionPredicate() ||
bol->is_OpaqueInitializedAssertionPredicate(),
"Opaque node of a non-null-check or an Assertion Predicate");
continue;
}
if (bol->as_Bool()->_test._test == BoolTest::ne) {
Expand Down Expand Up @@ -1937,8 +1939,8 @@ void PhaseIdealLoop::update_main_loop_assertion_predicates(Node* ctrl, CountedLo
// We could keep the one for the initial access but we do not know which one we currently have here. Just kill both.
_igvn.replace_input_of(iff, 1, _igvn.intcon(1));
}
assert(!bol->is_Opaque4() || !loop_head->is_main_loop(),
"Opaque4 node from a non-null check should not be at main loop");
assert(!bol->is_OpaqueNotNull() || !loop_head->is_main_loop(),
"OpaqueNotNull should not be at main loop");
entry = entry->in(0)->in(0);
}
if (prev_proj != ctrl) {
Expand Down
10 changes: 5 additions & 5 deletions src/hotspot/share/opto/loopopts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1701,7 +1701,7 @@ void PhaseIdealLoop::try_sink_out_of_loop(Node* n) {
!n->is_Proj() &&
!n->is_MergeMem() &&
!n->is_CMove() &&
!n->is_Opaque4() &&
!n->is_OpaqueNotNull() &&
!n->is_OpaqueInitializedAssertionPredicate() &&
!n->is_Type()) {
Node *n_ctrl = get_ctrl(n);
Expand Down Expand Up @@ -2019,14 +2019,14 @@ Node* PhaseIdealLoop::clone_iff(PhiNode* phi) {
if (b->is_Phi()) {
_igvn.replace_input_of(phi, i, clone_iff(b->as_Phi()));
} else {
assert(b->is_Bool() || b->is_Opaque4() || b->is_OpaqueInitializedAssertionPredicate(),
"bool, non-null check with Opaque4 node or Initialized Assertion Predicate with its Opaque node");
assert(b->is_Bool() || b->is_OpaqueNotNull() || b->is_OpaqueInitializedAssertionPredicate(),
"bool, non-null check with OpaqueNotNull or Initialized Assertion Predicate with its Opaque node");
}
}
Node* n = phi->in(1);
Node* sample_opaque = nullptr;
Node *sample_bool = nullptr;
if (n->is_Opaque4() || n->is_OpaqueInitializedAssertionPredicate()) {
if (n->is_OpaqueNotNull() || n->is_OpaqueInitializedAssertionPredicate()) {
sample_opaque = n;
sample_bool = n->in(1);
assert(sample_bool->is_Bool(), "wrong type");
Expand Down Expand Up @@ -2200,7 +2200,7 @@ void PhaseIdealLoop::clone_loop_handle_data_uses(Node* old, Node_List &old_new,
// For example, it is unexpected that there is a Phi between an
// AllocateArray node and its ValidLengthTest input that could cause
// split if to break.
if (use->is_If() || use->is_CMove() || use->is_Opaque4() || use->is_OpaqueInitializedAssertionPredicate() ||
if (use->is_If() || use->is_CMove() || use->is_OpaqueNotNull() || use->is_OpaqueInitializedAssertionPredicate() ||
(use->Opcode() == Op_AllocateArray && use->in(AllocateNode::ValidLengthTest) == old)) {
// Since this code is highly unlikely, we lazily build the worklist
// of such Nodes to go split.
Expand Down
15 changes: 6 additions & 9 deletions src/hotspot/share/opto/macro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2428,7 +2428,7 @@ void PhaseMacroExpand::eliminate_macro_nodes() {
break;
default:
assert(n->Opcode() == Op_LoopLimit ||
n->is_Opaque4() ||
n->is_OpaqueNotNull() ||
n->is_OpaqueInitializedAssertionPredicate() ||
n->Opcode() == Op_MaxL ||
n->Opcode() == Op_MinL ||
Expand Down Expand Up @@ -2480,17 +2480,14 @@ bool PhaseMacroExpand::expand_macro_nodes() {
} else if (n->is_Opaque1()) {
_igvn.replace_node(n, n->in(1));
success = true;
} else if (n->is_Opaque4()) {
// With Opaque4 nodes, the expectation is that the test of input 1
// is always equal to the constant value of input 2. So we can
// remove the Opaque4 and replace it by input 2. In debug builds,
// leave the non constant test in instead to sanity check that it
// never fails (if it does, that subgraph was constructed so, at
// runtime, a Halt node is executed).
} else if (n->is_OpaqueNotNull()) {
// Tests with OpaqueNotNull nodes are implicitly known to be true. Replace the node with true. In debug builds,
// we leave the test in the graph to have an additional sanity check at runtime. If the test fails, we will
// execute a Halt node.
#ifdef ASSERT
_igvn.replace_node(n, n->in(1));
#else
_igvn.replace_node(n, n->in(2));
_igvn.replace_node(n, _igvn.intcon(1));
#endif
success = true;
} else if (n->is_OpaqueInitializedAssertionPredicate()) {
Expand Down
6 changes: 3 additions & 3 deletions src/hotspot/share/opto/node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class NeverBranchNode;
class Opaque1Node;
class OpaqueLoopInitNode;
class OpaqueLoopStrideNode;
class Opaque4Node;
class OpaqueNotNullNode;
class OpaqueTemplateAssertionPredicateNode;
class OpaqueInitializedAssertionPredicateNode;
class OuterStripMinedLoopNode;
Expand Down Expand Up @@ -797,7 +797,7 @@ class Node {
DEFINE_CLASS_ID(Opaque1, Node, 16)
DEFINE_CLASS_ID(OpaqueLoopInit, Opaque1, 0)
DEFINE_CLASS_ID(OpaqueLoopStride, Opaque1, 1)
DEFINE_CLASS_ID(Opaque4, Node, 17)
DEFINE_CLASS_ID(OpaqueNotNull, Node, 17)
DEFINE_CLASS_ID(OpaqueTemplateAssertionPredicate, Node, 18)
DEFINE_CLASS_ID(OpaqueInitializedAssertionPredicate, Node, 19)
DEFINE_CLASS_ID(Move, Node, 20)
Expand Down Expand Up @@ -972,7 +972,7 @@ class Node {
DEFINE_CLASS_QUERY(NegV)
DEFINE_CLASS_QUERY(NeverBranch)
DEFINE_CLASS_QUERY(Opaque1)
DEFINE_CLASS_QUERY(Opaque4)
DEFINE_CLASS_QUERY(OpaqueNotNull)
DEFINE_CLASS_QUERY(OpaqueTemplateAssertionPredicate)
DEFINE_CLASS_QUERY(OpaqueInitializedAssertionPredicate)
DEFINE_CLASS_QUERY(OpaqueLoopInit)
Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/opto/opaquenode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ IfNode* OpaqueZeroTripGuardNode::if_node() const {
return iff->as_If();
}

const Type* Opaque4Node::Value(PhaseGVN* phase) const {
const Type* OpaqueNotNullNode::Value(PhaseGVN* phase) const {
return phase->type(in(1));
}

Expand Down
20 changes: 9 additions & 11 deletions src/hotspot/share/opto/opaquenode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,16 @@ class OpaqueZeroTripGuardNode : public Opaque1Node {
IfNode* if_node() const;
};

// Input 1 is a check that we know implicitly is always true or false
// but the compiler has no way to prove. If during optimizations, that
// check becomes true or false, the Opaque4 node is replaced by that
// constant true or false. Input 2 is the constant value we know the
// test takes. After loop optimizations, we replace input 1 by input 2
// so the control that depends on that test can be removed and there's
// no overhead at runtime. Used for instance by
// GraphKit::must_be_not_null().
class Opaque4Node : public Node {
// This node is used in the context of intrinsics. We sometimes implicitly know that an object is non-null even though
// the compiler cannot prove it. We therefore add a corresponding cast to propagate this implicit knowledge. However,
// this cast could become top during optimizations (input to cast becomes null) and the data path is folded. To ensure
// that the control path is also properly folded, we insert an If node with such a OpaqueNotNullNode as condition.
// During macro expansion, we replace the OpaqueNotNullNode with true such that the actually unneeded check is folded
// and does not end up in the emitted code. Also see GraphKit::must_be_not_null() for more details.
class OpaqueNotNullNode : public Node {
public:
Opaque4Node(Compile* C, Node* tst, Node* final_tst) : Node(nullptr, tst, final_tst) {
init_class_id(Class_Opaque4);
OpaqueNotNullNode(Compile* C, Node* tst, Node* final_tst) : Node(nullptr, tst, final_tst) {
init_class_id(Class_OpaqueNotNull);
init_flags(Flag_is_macro);
C->add_macro_node(this);
}
Expand Down
3 changes: 1 addition & 2 deletions src/hotspot/share/opto/predicates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,10 +401,9 @@ class AssertionPredicateExpressionCreator : public StackObj {

private:
OpaqueTemplateAssertionPredicateNode* create_opaque_node(Node* new_control, BoolNode* bool_for_expression) const {
Compile* C = _phase->C;
OpaqueTemplateAssertionPredicateNode* new_expression =
new OpaqueTemplateAssertionPredicateNode(bool_for_expression);
C->add_template_assertion_predicate_opaq(new_expression);
_phase->C->add_template_assertion_predicate_opaq(new_expression);
_phase->register_new_node(new_expression, new_control);
return new_expression;
}
Expand Down
10 changes: 5 additions & 5 deletions src/hotspot/share/opto/split_if.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,8 +322,8 @@ bool PhaseIdealLoop::clone_cmp_down(Node* n, const Node* blk1, const Node* blk2)
assert( bol->is_Bool(), "" );
if (bol->outcnt() == 1) {
Node* use = bol->unique_out();
assert(!use->is_OpaqueTemplateAssertionPredicate(), "cannot be Template Assertion Predicate");
if (use->is_Opaque4() || use->is_OpaqueInitializedAssertionPredicate()) {
if (use->is_OpaqueNotNull() || use->is_OpaqueTemplateAssertionPredicate() ||
use->is_OpaqueInitializedAssertionPredicate()) {
if (use->outcnt() == 1) {
Node* iff = use->unique_out();
assert(iff->is_If(), "unexpected node type");
Expand Down Expand Up @@ -352,9 +352,9 @@ bool PhaseIdealLoop::clone_cmp_down(Node* n, const Node* blk1, const Node* blk2)
#endif
for (DUIterator j = bol->outs(); bol->has_out(j); j++) {
Node* u = bol->out(j);
// Uses are either IfNodes, CMoves, Opaque4, or OpaqueInitializedAssertionPredicates
assert(!u->is_OpaqueTemplateAssertionPredicate(), "cannot be Template Assertion Predicate");
if (u->is_Opaque4() || u->is_OpaqueInitializedAssertionPredicate()) {
// Uses are either IfNodes, CMoves, OpaqueNotNull, or Opaque*AssertionPredicates
if (u->is_OpaqueNotNull() || u->is_OpaqueTemplateAssertionPredicate() ||
u->is_OpaqueInitializedAssertionPredicate()) {
assert(u->in(1) == bol, "bad input");
for (DUIterator_Last kmin, k = u->last_outs(kmin); k >= kmin; --k) {
Node* iff = u->last_out(k);
Expand Down

0 comments on commit 6eae11a

Please sign in to comment.