Skip to content

Commit

Permalink
8342945: Replace predicate walking code in get_assertion_predicates()…
Browse files Browse the repository at this point in the history
… used for Loop Unswitching and cleaning useless Template Assertion Predicates with a predicate visitor

Reviewed-by: thartmann, roland, kvn
  • Loading branch information
chhagedorn committed Nov 7, 2024
1 parent 97b681e commit a6c85da
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 37 deletions.
44 changes: 11 additions & 33 deletions src/hotspot/share/opto/loopPredicate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ IfProjNode* PhaseIdealLoop::clone_parse_predicate_to_unswitched_loop(ParsePredic
// cloned predicates.
void PhaseIdealLoop::clone_assertion_predicates_to_unswitched_loop(IdealLoopTree* loop, const Node_List& old_new,
Deoptimization::DeoptReason reason,
IfProjNode* old_predicate_proj,
ParsePredicateSuccessProj* old_parse_predicate_proj,
ParsePredicateSuccessProj* fast_loop_parse_predicate_proj,
ParsePredicateSuccessProj* slow_loop_parse_predicate_proj) {
assert(fast_loop_parse_predicate_proj->in(0)->is_ParsePredicate() &&
Expand All @@ -297,17 +297,15 @@ void PhaseIdealLoop::clone_assertion_predicates_to_unswitched_loop(IdealLoopTree
// and doing loop unrolling. Push the original predicates on a list to later process them in reverse order to keep the
// original predicate order.
Unique_Node_List list;
get_assertion_predicates(old_predicate_proj, list);
get_assertion_predicates(old_parse_predicate_proj, list);

Node_List to_process;
IfNode* iff = old_predicate_proj->in(0)->as_If();
IfProjNode* uncommon_proj = iff->proj_out(1 - old_predicate_proj->as_Proj()->_con)->as_IfProj();
// Process in reverse order such that 'create_new_if_for_predicate' can be used in
// 'clone_assertion_predicate_for_unswitched_loops' and the original order is maintained.
for (int i = list.size() - 1; i >= 0; i--) {
Node* predicate = list.at(i);
assert(predicate->in(0)->is_If(), "must be If node");
iff = predicate->in(0)->as_If();
IfNode* iff = predicate->in(0)->as_If();
assert(predicate->is_Proj() && predicate->as_Proj()->is_IfProj(), "predicate must be a projection of an if node");
IfProjNode* predicate_proj = predicate->as_IfProj();

Expand Down Expand Up @@ -337,34 +335,14 @@ void PhaseIdealLoop::clone_assertion_predicates_to_unswitched_loop(IdealLoopTree
}

// Put all Assertion Predicate projections on a list, starting at 'predicate' and going up in the tree. If 'get_opaque'
// is set, then the OpaqueTemplateAssertionPredicate nodes of the Assertion Predicates are put on the list instead of
// the projections.
void PhaseIdealLoop::get_assertion_predicates(Node* predicate, Unique_Node_List& list, bool get_opaque) {
ParsePredicateNode* parse_predicate = predicate->in(0)->as_ParsePredicate();
ProjNode* uncommon_proj = parse_predicate->proj_out(1 - predicate->as_Proj()->_con);
Node* rgn = uncommon_proj->unique_ctrl_out();
assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct");
predicate = parse_predicate->in(0);
while (predicate != nullptr && predicate->is_Proj() && predicate->in(0)->is_If()) {
IfNode* iff = predicate->in(0)->as_If();
uncommon_proj = iff->proj_out(1 - predicate->as_Proj()->_con);
if (uncommon_proj->unique_ctrl_out() != rgn) {
break;
}
Node* bol = iff->in(1);
assert(!bol->is_OpaqueInitializedAssertionPredicate(), "should not find an Initialized Assertion Predicate");
if (bol->is_OpaqueTemplateAssertionPredicate()) {
assert(assertion_predicate_has_loop_opaque_node(iff), "must find OpaqueLoop* nodes");
if (get_opaque) {
// Collect the OpaqueTemplateAssertionPredicateNode.
list.push(bol);
} else {
// Collect the predicate projection.
list.push(predicate);
}
}
predicate = predicate->in(0)->in(0);
}
// is set, then the OpaqueTemplateAssertionPredicateNode nodes of the Assertion Predicates are put on the list instead
// of the projections.
void PhaseIdealLoop::get_assertion_predicates(ParsePredicateSuccessProj* parse_predicate_proj, Unique_Node_List& list,
const bool get_opaque) {
Deoptimization::DeoptReason deopt_reason = parse_predicate_proj->in(0)->as_ParsePredicate()->deopt_reason();
PredicateBlockIterator predicate_iterator(parse_predicate_proj, deopt_reason);
TemplateAssertionPredicateCollector template_assertion_predicate_collector(list, get_opaque);
predicate_iterator.for_each(template_assertion_predicate_collector);
}

// Clone an Assertion Predicate for an unswitched loop. OpaqueLoopInit and OpaqueLoopStride nodes are cloned and uncommon
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/opto/loopnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4469,15 +4469,15 @@ void PhaseIdealLoop::collect_useful_template_assertion_predicates_for_loop(Ideal
if (UseProfiledLoopPredicate) {
const PredicateBlock* profiled_loop_predicate_block = predicates.profiled_loop_predicate_block();
if (profiled_loop_predicate_block->has_parse_predicate()) {
IfProjNode* parse_predicate_proj = profiled_loop_predicate_block->parse_predicate_success_proj();
ParsePredicateSuccessProj* parse_predicate_proj = profiled_loop_predicate_block->parse_predicate_success_proj();
get_assertion_predicates(parse_predicate_proj, useful_predicates, true);
}
}

if (UseLoopPredicate) {
const PredicateBlock* loop_predicate_block = predicates.loop_predicate_block();
if (loop_predicate_block->has_parse_predicate()) {
IfProjNode* parse_predicate_proj = loop_predicate_block->parse_predicate_success_proj();
ParsePredicateSuccessProj* parse_predicate_proj = loop_predicate_block->parse_predicate_success_proj();
get_assertion_predicates(parse_predicate_proj, useful_predicates, true);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/opto/loopnode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -947,7 +947,7 @@ class PhaseIdealLoop : public PhaseTransform {
DEBUG_ONLY(static bool assertion_predicate_has_loop_opaque_node(IfNode* iff);)
private:
DEBUG_ONLY(static void count_opaque_loop_nodes(Node* n, uint& init, uint& stride);)
static void get_assertion_predicates(Node* predicate, Unique_Node_List& list, bool get_opaque = false);
static void get_assertion_predicates(ParsePredicateSuccessProj* parse_predicate_proj, Unique_Node_List& list, bool get_opaque = false);
void update_main_loop_assertion_predicates(Node* ctrl, CountedLoopNode* loop_head, Node* init, int stride_con);
void initialize_assertion_predicates_for_peeled_loop(CountedLoopNode* peeled_loop_head,
CountedLoopNode* remaining_loop_head,
Expand Down Expand Up @@ -1672,7 +1672,7 @@ class PhaseIdealLoop : public PhaseTransform {
IfProjNode* clone_parse_predicate_to_unswitched_loop(ParsePredicateSuccessProj* parse_predicate_proj, Node* new_entry,
Deoptimization::DeoptReason reason, bool slow_loop);
void clone_assertion_predicates_to_unswitched_loop(IdealLoopTree* loop, const Node_List& old_new,
Deoptimization::DeoptReason reason, IfProjNode* old_predicate_proj,
Deoptimization::DeoptReason reason, ParsePredicateSuccessProj* old_parse_predicate_proj,
ParsePredicateSuccessProj* fast_loop_parse_predicate_proj,
ParsePredicateSuccessProj* slow_loop_parse_predicate_proj);
IfProjNode* clone_assertion_predicate_for_unswitched_loops(IfNode* template_assertion_predicate, IfProjNode* predicate,
Expand Down
22 changes: 22 additions & 0 deletions src/hotspot/share/opto/predicates.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1010,4 +1010,26 @@ class CreateAssertionPredicatesVisitor : public PredicateVisitor {
}
};

// This visitor collects all Template Assertion Predicates If nodes or the corresponding Opaque nodes, depending on the
// provided 'get_opaque' flag, to the provided list.
class TemplateAssertionPredicateCollector : public PredicateVisitor {
Unique_Node_List& _list;
const bool _get_opaque;

public:
TemplateAssertionPredicateCollector(Unique_Node_List& list, const bool get_opaque)
: _list(list),
_get_opaque(get_opaque) {}

using PredicateVisitor::visit;

void visit(const TemplateAssertionPredicate& template_assertion_predicate) override {
if (_get_opaque) {
_list.push(template_assertion_predicate.opaque_node());
} else {
_list.push(template_assertion_predicate.tail());
}
}
};

#endif // SHARE_OPTO_PREDICATES_HPP

0 comments on commit a6c85da

Please sign in to comment.