From dda0daaec00aed48c82d20c5b0c497d53a4f2a09 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Thu, 16 Nov 2023 14:04:34 +0100 Subject: [PATCH] Misc cleanups --- src/hotspot/share/opto/cfgnode.hpp | 9 +-- src/hotspot/share/opto/loopPredicate.cpp | 18 +++--- src/hotspot/share/opto/loopTransform.cpp | 4 +- src/hotspot/share/opto/loopUnswitch.cpp | 41 +++++++------ src/hotspot/share/opto/loopnode.hpp | 1 - src/hotspot/share/opto/predicates.cpp | 58 +++++++++---------- src/hotspot/share/opto/predicates.hpp | 31 +++++----- .../predicates/TestAssertionPredicates.java | 1 - 8 files changed, 82 insertions(+), 81 deletions(-) diff --git a/src/hotspot/share/opto/cfgnode.hpp b/src/hotspot/share/opto/cfgnode.hpp index 52fea12b66f8c..3006931bdd800 100644 --- a/src/hotspot/share/opto/cfgnode.hpp +++ b/src/hotspot/share/opto/cfgnode.hpp @@ -291,8 +291,9 @@ class GotoNode : public Node { virtual const RegMask &out_RegMask() const; }; -// This node represents a Template Assertion Predicate with two bools as input which can be used to create and +// This node represents a Template Assertion Predicate with two bools as input which can be used to create an // Initialized Assertion Predicate from (more information can be found in the summary at predicates.hpp). +// This node is folded either after loop opts or once the associated CountedLoopNode is removed. class TemplateAssertionPredicateNode : public Node { int _initialized_init_value_opcode; int _initialized_last_value_opcode; @@ -308,7 +309,6 @@ class TemplateAssertionPredicateNode : public Node { TemplateAssertionPredicateNode(Node* control, BoolNode* bool_init_value, BoolNode* bool_last_value, int initialized_init_value_opcode, int initialized_last_value_opcode); - IfNode* create_initialized_assertion_predicate(Node* control, OpaqueAssertionPredicateNode* opaque_bool, AssertionPredicateType initialized_assertion_predicate_type) const; @@ -492,7 +492,8 @@ class IfNode : public MultiBranchNode { class RangeCheckNode : public IfNode { private: - int is_range_check(Node* &range, Node* &index, jint &offset); + int is_range_check(Node*& range, Node*& index, jint& offset); + public: RangeCheckNode(Node* control, Node* bol, float p, float fcnt) : IfNode(control, bol, p, fcnt) { @@ -516,7 +517,7 @@ class RangeCheckNode : public IfNode { // There are three kinds of Parse Predicates: // Loop Parse Predicate, Profiled Loop Parse Predicate (both used by Loop Predication), and Loop Limit Check Parse // Predicate (used for integer overflow checks when creating a counted loop). -// More information about predicates can be found in loopPredicate.cpp. +// More information about predicates can be found in predicates.hpp. class ParsePredicateNode : public IfNode { Deoptimization::DeoptReason _deopt_reason; bool _useless; // If the associated loop dies, this parse predicate becomes useless and can be cleaned up by Value(). diff --git a/src/hotspot/share/opto/loopPredicate.cpp b/src/hotspot/share/opto/loopPredicate.cpp index 49a58bce7203e..dbab17ecb6082 100644 --- a/src/hotspot/share/opto/loopPredicate.cpp +++ b/src/hotspot/share/opto/loopPredicate.cpp @@ -612,7 +612,7 @@ bool IdealLoopTree::is_range_check_if(IfProjNode* if_success_proj, PhaseIdealLoo // (2) stride*scale < 0 // max(scale*i + offset) = scale*init + offset BoolNode* PhaseIdealLoop::rc_predicate(Node* ctrl, const int scale, Node* offset, Node* init, Node* limit, - const jint stride, Node* range, const bool upper, bool &overflow) { + const jint stride, Node* range, const bool upper, bool& overflow) { jint con_limit = (limit != nullptr && limit->is_Con()) ? limit->get_int() : 0; jint con_init = init->is_Con() ? init->get_int() : 0; jint con_offset = offset->is_Con() ? offset->get_int() : 0; @@ -1000,10 +1000,8 @@ void PhaseIdealLoop::loop_predication_follow_branches(Node *n, IdealLoopTree *lo bool PhaseIdealLoop::loop_predication_impl_helper(IdealLoopTree* loop, IfProjNode* if_success_proj, ParsePredicateSuccessProj* parse_predicate_proj, CountedLoopNode* cl, ConNode* zero, Invariance& invar, Deoptimization::DeoptReason reason) { - // Following are changed to nonnull when a predicate can be hoisted - Node* new_predicate_tail = nullptr; - IfNode* iff = if_success_proj->in(0)->as_If(); - Node* test = iff->in(1); + IfNode* iff = if_success_proj->in(0)->as_If(); + Node* test = iff->in(1); if (!test->is_Bool()) { // Conv2B, ... return false; } @@ -1085,7 +1083,9 @@ bool PhaseIdealLoop::loop_predication_impl_helper(IdealLoopTree* loop, IfProjNod IfNode* lower_bound_iff = lower_bound_proj->in(0)->as_If(); _igvn.hash_delete(lower_bound_iff); lower_bound_iff->set_req(1, lower_bound_bol); - if (TraceLoopPredicate) tty->print_cr("lower bound check if: %d", lower_bound_iff->_idx); + if (TraceLoopPredicate) { + tty->print_cr("lower bound check if: %d", lower_bound_iff->_idx); + } // Test the upper bound BoolNode* upper_bound_bol = rc_predicate(lower_bound_proj, scale, offset, init, limit, stride, rng, true, overflow); @@ -1095,7 +1095,9 @@ bool PhaseIdealLoop::loop_predication_impl_helper(IdealLoopTree* loop, IfProjNod IfNode* upper_bound_iff = upper_bound_proj->in(0)->as_If(); _igvn.hash_delete(upper_bound_iff); upper_bound_iff->set_req(1, upper_bound_bol); - if (TraceLoopPredicate) tty->print_cr("upper bound check if: %d", lower_bound_iff->_idx); + if (TraceLoopPredicate) { + tty->print_cr("upper bound check if: %d", upper_bound_iff->_idx); + } // Each newly created Hoisted Check Predicate is accompanied by two Template Assertion Predicates. Later, we initialize // them by making a copy of them when splitting a loop into sub loops. The Assertion Predicates ensure that dead sub @@ -1293,7 +1295,7 @@ bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree* loop) { return hoisted; } -// We cannot add Loop Predicates if: +// We cannot create Loop Predicates if: // (1) There is no Loop Parse Predicate. // (2) Already added Profiled Loop Predicates (Loop Predicates and Profiled Loop Predicates can be dependent // through a data node, and thus we should only add new Profiled Loop Predicates which are below Loop Predicates diff --git a/src/hotspot/share/opto/loopTransform.cpp b/src/hotspot/share/opto/loopTransform.cpp index e62b2398eb262..445bee5ab3dc0 100644 --- a/src/hotspot/share/opto/loopTransform.cpp +++ b/src/hotspot/share/opto/loopTransform.cpp @@ -788,8 +788,8 @@ void PhaseIdealLoop::do_peeling(IdealLoopTree *loop, Node_List &old_new) { // Creates new Assertion Predicates at the 'target_loop_head' (cloned loop). A new Template Assertion Predicate is // inserted with the new init and stride values of the target loop for each existing Template Assertion Predicate found -// 'source_loop_head (original loop). For each new Template Assertion Predicate, an init and last value Initialized -// Assertion Predicate is created. +// at 'source_loop_head (original loop). For each new Template Assertion Predicate, an Initialized Assertion Predicate +// for the new init and stride value is created. void PhaseIdealLoop::clone_assertion_predicates_from_original_loop(CountedLoopNode* source_loop_head, CountedLoopNode* target_loop_head, const uint first_cloned_loop_node_index) { diff --git a/src/hotspot/share/opto/loopUnswitch.cpp b/src/hotspot/share/opto/loopUnswitch.cpp index d8ae9550884a8..9f68f62bb19ae 100644 --- a/src/hotspot/share/opto/loopUnswitch.cpp +++ b/src/hotspot/share/opto/loopUnswitch.cpp @@ -83,13 +83,13 @@ bool IdealLoopTree::policy_unswitching( PhaseIdealLoop *phase ) const { return phase->may_require_nodes(est_loop_clone_sz(2)); } -//------------------------------find_unswitching_candidate----------------------------- -// Find candidate "if" for unswitching +// Find invariant test in loop body that does not exit the loop. If multiple are found, we pick the first one in the +// loop body. Return the candidate "if" for unswitching. IfNode* PhaseIdealLoop::find_unswitching_candidate(const IdealLoopTree *loop) const { // Find first invariant test that doesn't exit the loop LoopNode *head = loop->_head->as_Loop(); - IfNode* unswitch_iff = nullptr; + IfNode* unswitching_candidate = nullptr; Node* n = head->in(LoopNode::LoopBackControl); while (n != head) { Node* n_dom = idom(n); @@ -102,7 +102,7 @@ IfNode* PhaseIdealLoop::find_unswitching_candidate(const IdealLoopTree *loop) co // If condition is invariant and not a loop exit, // then found reason to unswitch. if (loop->is_invariant(bol) && !loop->is_loop_exit(iff)) { - unswitch_iff = iff; + unswitching_candidate = iff; } } } @@ -110,16 +110,18 @@ IfNode* PhaseIdealLoop::find_unswitching_candidate(const IdealLoopTree *loop) co } n = n_dom; } - return unswitch_iff; + return unswitching_candidate; } -//------------------------------do_unswitching----------------------------- -// Clone loop with an invariant test (that does not exit) and -// insert a clone of the test that selects which version to -// execute. -void PhaseIdealLoop::do_unswitching(IdealLoopTree *loop, Node_List &old_new) { - // Find first invariant test that doesn't exit the loop - IfNode* unswitching_candidate = find_unswitching_candidate((const IdealLoopTree *)loop); +// Perform Loop Unswitching on the loop containing an invariant test that does not exit the loop. The loop is cloned +// such that we have two identical loops next to each other - a fast and a slow loop. We modify the loops as follows: +// - Fast loop: We remove the invariant test together with the false path and only leave the true path in the loop. +// - Slow loop: We remove the invariant test together with the true path and only leave the false path in the loop. +// +// We insert a new If node before both loops that performs the removed invariant test. If the test is true at runtime, +// we select the fast loop. Otherwise, we select the slow loop. +void PhaseIdealLoop::do_unswitching(IdealLoopTree* loop, Node_List& old_new) { + IfNode* unswitching_candidate = find_unswitching_candidate(loop); assert(unswitching_candidate != nullptr, "should be at least one"); LoopNode* head = loop->_head->as_Loop(); @@ -304,7 +306,7 @@ class UnswitchedLoop : public StackObj { NewParsePredicate* _new_parse_predicate; TemplateAssertionPredicateDataOutput* _node_in_target_loop; PhaseIdealLoop* _phase; - PredicateChain _predicate_chain; + PredicateInserter _predicate_inserter; public: UnswitchedLoop(IfProjNode* unswitch_if_proj, LoopNode* unswitched_loop_head, NewParsePredicate* new_parse_predicate, @@ -313,19 +315,19 @@ class UnswitchedLoop : public StackObj { _new_parse_predicate(new_parse_predicate), _node_in_target_loop(node_in_target_loop), _phase(phase), - _predicate_chain(unswitched_loop_head, phase) {} + _predicate_inserter(unswitched_loop_head, phase) {} // Clone the Template Assertion Predicate to this loop. void clone_to(TemplateAssertionPredicate& template_assertion_predicate) { TemplateAssertionPredicate cloned_template = template_assertion_predicate.clone(_entry, _node_in_target_loop, _phase); - _predicate_chain.insert_new_predicate(cloned_template); + _predicate_inserter.insert(cloned_template); } // Clone the Parse Predicate to this loop. void clone_to(ParsePredicate& parse_predicate) { ParsePredicate cloned_parse_predicate = parse_predicate.clone(_entry, _new_parse_predicate, _phase); - _predicate_chain.insert_new_predicate(cloned_parse_predicate); + _predicate_inserter.insert(cloned_parse_predicate); } }; @@ -522,10 +524,8 @@ class OriginalLoop { #endif // ASSERT }; -//-------------------------create_slow_version_of_loop------------------------ -// Create a slow version of the loop by cloning the loop -// and inserting an if to select fast-slow versions. -// Return the inserted if. +// Create a slow version of the loop by cloning the loop and inserting an If to select the fast or slow version. +// Return the inserted loop selector If. IfNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree* loop, Node_List& old_new, IfNode* unswitching_candidate) { OriginalLoop original_loop(loop, &old_new); @@ -533,4 +533,3 @@ IfNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree* loop, Node_Li recompute_dom_depth(); return loop_selector_if; } - diff --git a/src/hotspot/share/opto/loopnode.hpp b/src/hotspot/share/opto/loopnode.hpp index 69316dcc964af..76812b19172db 100644 --- a/src/hotspot/share/opto/loopnode.hpp +++ b/src/hotspot/share/opto/loopnode.hpp @@ -1315,7 +1315,6 @@ class PhaseIdealLoop : public PhaseTransform { Deoptimization::DeoptReason reason, int opcode, bool rewire_uncommon_proj_phi_inputs = false); - private: // Helper functions for create_new_if_for_predicate() void set_ctrl_of_nodes_with_same_ctrl(Node* node, ProjNode* old_ctrl, Node* new_ctrl); diff --git a/src/hotspot/share/opto/predicates.cpp b/src/hotspot/share/opto/predicates.cpp index 7e95fbc7e105d..df58471020494 100644 --- a/src/hotspot/share/opto/predicates.cpp +++ b/src/hotspot/share/opto/predicates.cpp @@ -142,19 +142,19 @@ bool RuntimePredicate::is_success_proj(Node* maybe_success_proj, Deoptimization: // Insert a new predicate above the current tail of the chain. The control input of the current tail is set to the new // predicate. The new predicate becomes the new tail of this chain. -void PredicateChain::insert_new_predicate(Predicate& new_predicate) { +void PredicateInserter::insert(Predicate& new_predicate) { Node* new_entry_for_tail = new_predicate.tail(); - if (_tail->is_Loop()) { - _phase->replace_loop_entry(_tail->as_Loop(), new_entry_for_tail); + if (_ctrl_out->is_Loop()) { + _phase->replace_loop_entry(_ctrl_out->as_Loop(), new_entry_for_tail); } else { - _phase->replace_control_same_loop(_tail, new_entry_for_tail); + _phase->replace_control_same_loop(_ctrl_out, new_entry_for_tail); } - _tail = new_predicate.head(); + _ctrl_out = new_predicate.head(); } // Insert an existing predicate into the chain by setting it as new tail. There is no control update involved. -void PredicateChain::insert_existing_predicate(Predicate& existing_predicate) { - _tail = existing_predicate.head(); +void PredicateInserter::skip(Predicate& existing_predicate) { + _ctrl_out = existing_predicate.head(); } // This visitor clones all visited Template Assertion Predicates and sets a new input for the cloned OpaqueLoopInitNodes. @@ -164,13 +164,13 @@ class CloneAndInitAssertionPredicates : public PredicateVisitor { Node* _new_init; PhaseIdealLoop* _phase; TemplateAssertionPredicateDataOutput* _node_in_target_loop; - PredicateChain _predicate_chain; + PredicateInserter _predicate_inserter; TemplateAssertionPredicate create_new_template(TemplateAssertionPredicate& template_assertion_predicate) { TemplateAssertionPredicate new_template = template_assertion_predicate.clone_update_opaque_init(_old_target_loop_entry, _new_init, _node_in_target_loop, _phase); - _predicate_chain.insert_new_predicate(new_template); + _predicate_inserter.insert(new_template); return new_template; } @@ -183,11 +183,11 @@ class CloneAndInitAssertionPredicates : public PredicateVisitor { _new_init(target_loop_head->init_trip()), _phase(phase), _node_in_target_loop(node_in_target_loop), - _predicate_chain(target_loop_head, phase) {} + _predicate_inserter(target_loop_head, phase) {} void visit(TemplateAssertionPredicate& template_assertion_predicate) override { TemplateAssertionPredicate new_template = create_new_template(template_assertion_predicate); - new_template.initialize(_phase, _predicate_chain); + new_template.initialize(_phase, _predicate_inserter); } }; @@ -233,34 +233,34 @@ void AssertionPredicates::move_to_loop(CountedLoopNode* target_loop_head, Templa predicates_for_loop.for_each(); } -// Creates a single new Template Assertion Predicates at the source loop with its init and stride value together with an +// Creates a single new Template Assertion Predicate at the source loop with its init and stride value together with an // Initialized Assertion Predicate for the init and last value. void AssertionPredicates::create(const int if_opcode, const int scale, Node* offset, Node* range) { - PredicateChain predicate_chain(_source_loop_head, _phase); + PredicateInserter predicate_inserter(_source_loop_head, _phase); TemplateAssertionPredicate template_assertion_predicate = create_new_template(if_opcode, scale, offset, range, - predicate_chain); - template_assertion_predicate.initialize(_phase, predicate_chain); + predicate_inserter); + template_assertion_predicate.initialize(_phase, predicate_inserter); } TemplateAssertionPredicate AssertionPredicates::create_new_template(const int if_opcode, const int scale, Node* offset, - Node* range, PredicateChain& predicate_chain) { + Node* range, PredicateInserter& predicate_inserter) { LoopNode* loop_head = _source_loop_head->skip_strip_mined(); NewTemplateAssertionPredicate new_template_assertion_predicate(_source_loop_head, _phase); TemplateAssertionPredicate template_assertion_predicate( new_template_assertion_predicate.create(if_opcode, loop_head->in(LoopNode::EntryControl), scale, offset, range)); - predicate_chain.insert_new_predicate(template_assertion_predicate); + predicate_inserter.insert(template_assertion_predicate); return template_assertion_predicate; } // This visitor updates all visited Template Assertion Predicates by setting a new input for the OpaqueLoopStrideNodes. -// Afterward, we initialize the updated template by creating an InitializedAssertionPredicate for the init and last value. -// The old InitializedAssertionPredicates are killed. +// Afterward, we initialize the updated template by creating an Initialized Assertion Predicate for the init and last +// value. The old Initialized Assertion Predicates are killed. class UpdateAndInitAssertionPredicates : public PredicateVisitor { Node* _new_stride; PhaseIdealLoop* _phase; uint _index_before_visit; - PredicateChain _predicate_chain; + PredicateInserter _predicate_inserter; public: using PredicateVisitor::visit; @@ -269,12 +269,12 @@ class UpdateAndInitAssertionPredicates : public PredicateVisitor { : _new_stride(new_stride), _phase(phase), _index_before_visit(phase->C->unique()), - _predicate_chain(loop_head, phase) {} + _predicate_inserter(loop_head, phase) {} void visit(TemplateAssertionPredicate& template_assertion_predicate) override { template_assertion_predicate.update_opaque_stride(_new_stride, &_phase->igvn()); - _predicate_chain.insert_existing_predicate(template_assertion_predicate); - template_assertion_predicate.initialize(_phase, _predicate_chain); + _predicate_inserter.skip(template_assertion_predicate); + template_assertion_predicate.initialize(_phase, _predicate_inserter); } void visit(InitializedAssertionPredicate& initialized_assertion_predicate) override { @@ -305,7 +305,7 @@ TemplateAssertionPredicateBool::TemplateAssertionPredicateBool(Node* source_bool #ifdef ASSERT // We could have already folded the BoolNode to a constant. if (is_not_dead()) { - // During IGVN, we could have multiple outputs of the _source_bool, for example, when the backedge of the loop is + // During IGVN, we could have multiple outputs of the _source_bool, for example, when the backedge of the loop of // this Template Assertion Predicate is about to die and the CastII on the last value bool already folded to a // constant (i.e. no OpaqueLoop* nodes anymore). Then IGVN could already have commoned up the bool with the bool of // one of the Hoisted Check Predicates. Just check that the Template Assertion Predicate is one of the outputs. @@ -743,12 +743,12 @@ class CreateInitializedAssertionPredicate { // Create the out nodes of a newly created Initialized Assertion Predicate If node which includes the projections and // the dedicated Halt node. IfTrueNode* create_if_proj_nodes(IfNode* if_node, IdealLoopTree* loop) { - IfTrueNode* succ_proj = new IfTrueNode(if_node); + IfTrueNode* success_proj = new IfTrueNode(if_node); IfFalseNode* fail_proj = new IfFalseNode(if_node); - _phase->register_control(succ_proj, loop, if_node); + _phase->register_control(success_proj, loop, if_node); _phase->register_control(fail_proj, loop, if_node); create_halt_node(fail_proj, loop); - return succ_proj; + return success_proj; } public: explicit CreateInitializedAssertionPredicate(PhaseIdealLoop* phase) : _phase(phase) {} @@ -764,13 +764,13 @@ class CreateInitializedAssertionPredicate { void TemplateAssertionPredicate::create_initialized_predicate(Node* new_ctrl, PhaseIdealLoop* phase, TemplateAssertionPredicateBool& template_bool, AssertionPredicateType assertion_predicate_type, - PredicateChain& predicate_chain) { + PredicateInserter& predicate_inserter) { CreateInitializedAssertionPredicate create_initialized_assertion_predicate(phase); BoolNode* new_bool = template_bool.clone_remove_opaque_loop_nodes(new_ctrl, phase); InitializedAssertionPredicate initialized_assertion_predicate = create_initialized_assertion_predicate.create(_template_assertion_predicate, new_ctrl, new_bool, assertion_predicate_type); - predicate_chain.insert_new_predicate(initialized_assertion_predicate); + predicate_inserter.insert(initialized_assertion_predicate); } Node* TemplateAssertionPredicateBools::create_last_value(Node* new_ctrl, OpaqueLoopInitNode* opaque_init) { diff --git a/src/hotspot/share/opto/predicates.hpp b/src/hotspot/share/opto/predicates.hpp index 6e332f0c540b8..6d267e2a32c72 100644 --- a/src/hotspot/share/opto/predicates.hpp +++ b/src/hotspot/share/opto/predicates.hpp @@ -350,27 +350,27 @@ class RuntimePredicate : public Predicate { static bool is_success_proj(Node* maybe_success_proj, Deoptimization::DeoptReason deopt_reason); }; -// This class represents a chain of predicates above a loop. We build the chain by inserting either existing predicates -// at the loop or by inserting new predicates which also update control. -class PredicateChain : public StackObj { - Node* _tail; // The current tail of this predicate chain which is initially the loop node itself. +// This class can be used to insert predicates in the graph above a loop. It can either insert new predicates or skip +// over existing predicates in the graph. The class acts as an iterator and always maintains a link to the current +// control output where a new predicate could possibly be inserted. +class PredicateInserter : public StackObj { + Node* _ctrl_out; // The current control output if a new predicate is inserted in the graph. PhaseIdealLoop* _phase; public: - PredicateChain(LoopNode* loop_node, PhaseIdealLoop* phase) : _tail(loop_node->skip_strip_mined()), _phase(phase) {} + PredicateInserter(LoopNode* loop_node, PhaseIdealLoop* phase) : _ctrl_out(loop_node->skip_strip_mined()), _phase(phase) {} - void insert_new_predicate(Predicate& new_predicate); - void insert_existing_predicate(Predicate& existing_predicate); + void insert(Predicate& new_predicate); + void skip(Predicate& existing_predicate); }; -// Class to create Assertion Predicates at the target loop by moving the templates from the source to the target loop -// and creating initialized predicates from them. +// The class offers different actions for Assertion Predicates belonging to a source loop. class AssertionPredicates : public StackObj { CountedLoopNode* _source_loop_head; PhaseIdealLoop* _phase; TemplateAssertionPredicate create_new_template(int if_opcode, int scale, Node* offset, Node* range, - PredicateChain& predicate_chain); + PredicateInserter& predicate_inserter); Node* create_stride(int stride_con); public: @@ -378,7 +378,6 @@ class AssertionPredicates : public StackObj { : _source_loop_head(source_loop_head), _phase(phase) {} - void clone_to_loop(CountedLoopNode* target_loop_head, TemplateAssertionPredicateDataOutput* node_in_target_loop); void move_to_loop(CountedLoopNode* target_loop_head, TemplateAssertionPredicateDataOutput* node_in_target_loop); void create(int if_opcode, int scale, Node* offset, Node* range); @@ -419,6 +418,8 @@ class TemplateAssertionPredicateBool : public StackObj { public: explicit TemplateAssertionPredicateBool(Node* source_bool); + // The last value bool could already be a constant (i.e. dead) when the CastII node between the Template Assertion + // Predicate and the OpaqueLoop* nodes was replaced by a constant. In this case, _source_bool is null. bool is_not_dead() const { return _source_bool != nullptr; } @@ -443,7 +444,7 @@ class TemplateAssertionPredicate : public Predicate { void update_data_dependencies_to_clone(TemplateAssertionPredicateNode* cloned_template_assertion_predicate, TemplateAssertionPredicateDataOutput* node_in_target_loop, PhaseIdealLoop* phase); void create_initialized_predicate(Node* new_ctrl, PhaseIdealLoop* phase, TemplateAssertionPredicateBool &template_bool, - AssertionPredicateType assertion_predicate_type, PredicateChain& predicate_chain); + AssertionPredicateType assertion_predicate_type, PredicateInserter& predicate_inserter); public: TemplateAssertionPredicate(TemplateAssertionPredicateNode* template_assertion_predicate) @@ -503,13 +504,13 @@ class TemplateAssertionPredicate : public Predicate { // Create an Initialized Assertion Predicate from this Template Assertion Predicate for the init and the last value. // This is done by cloning the Template Assertion Predicate bools and removing the OpaqueLoop* nodes (i.e. folding // them away and using their inputs instead). - void initialize(PhaseIdealLoop* phase, PredicateChain& predicate_chain) { + void initialize(PhaseIdealLoop* phase, PredicateInserter& predicate_inserter) { Node* new_ctrl = entry(); if (_last_value_bool.is_not_dead()) { create_initialized_predicate(new_ctrl, phase, _last_value_bool, AssertionPredicateType::Last_value, - predicate_chain); + predicate_inserter); } - create_initialized_predicate(new_ctrl, phase, _init_value_bool, AssertionPredicateType::Init_value, predicate_chain); + create_initialized_predicate(new_ctrl, phase, _init_value_bool, AssertionPredicateType::Init_value, predicate_inserter); } // Kill this Template Assertion Predicate by marking it as useless. The Template Assertion Predicate will be removed diff --git a/test/hotspot/jtreg/compiler/predicates/TestAssertionPredicates.java b/test/hotspot/jtreg/compiler/predicates/TestAssertionPredicates.java index a359feeb58fec..3158724eafbfc 100644 --- a/test/hotspot/jtreg/compiler/predicates/TestAssertionPredicates.java +++ b/test/hotspot/jtreg/compiler/predicates/TestAssertionPredicates.java @@ -117,7 +117,6 @@ /* * @test id=NoFlags - * @key randomness * @bug 8288981 * @run driver compiler.predicates.TestAssertionPredicates NoFlags */