Skip to content

Commit a6c85da

Browse files
committed
8342945: Replace predicate walking code in get_assertion_predicates() used for Loop Unswitching and cleaning useless Template Assertion Predicates with a predicate visitor
Reviewed-by: thartmann, roland, kvn
1 parent 97b681e commit a6c85da

File tree

4 files changed

+37
-37
lines changed

4 files changed

+37
-37
lines changed

src/hotspot/share/opto/loopPredicate.cpp

+11-33
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ IfProjNode* PhaseIdealLoop::clone_parse_predicate_to_unswitched_loop(ParsePredic
288288
// cloned predicates.
289289
void PhaseIdealLoop::clone_assertion_predicates_to_unswitched_loop(IdealLoopTree* loop, const Node_List& old_new,
290290
Deoptimization::DeoptReason reason,
291-
IfProjNode* old_predicate_proj,
291+
ParsePredicateSuccessProj* old_parse_predicate_proj,
292292
ParsePredicateSuccessProj* fast_loop_parse_predicate_proj,
293293
ParsePredicateSuccessProj* slow_loop_parse_predicate_proj) {
294294
assert(fast_loop_parse_predicate_proj->in(0)->is_ParsePredicate() &&
@@ -297,17 +297,15 @@ void PhaseIdealLoop::clone_assertion_predicates_to_unswitched_loop(IdealLoopTree
297297
// and doing loop unrolling. Push the original predicates on a list to later process them in reverse order to keep the
298298
// original predicate order.
299299
Unique_Node_List list;
300-
get_assertion_predicates(old_predicate_proj, list);
300+
get_assertion_predicates(old_parse_predicate_proj, list);
301301

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

@@ -337,34 +335,14 @@ void PhaseIdealLoop::clone_assertion_predicates_to_unswitched_loop(IdealLoopTree
337335
}
338336

339337
// Put all Assertion Predicate projections on a list, starting at 'predicate' and going up in the tree. If 'get_opaque'
340-
// is set, then the OpaqueTemplateAssertionPredicate nodes of the Assertion Predicates are put on the list instead of
341-
// the projections.
342-
void PhaseIdealLoop::get_assertion_predicates(Node* predicate, Unique_Node_List& list, bool get_opaque) {
343-
ParsePredicateNode* parse_predicate = predicate->in(0)->as_ParsePredicate();
344-
ProjNode* uncommon_proj = parse_predicate->proj_out(1 - predicate->as_Proj()->_con);
345-
Node* rgn = uncommon_proj->unique_ctrl_out();
346-
assert(rgn->is_Region() || rgn->is_Call(), "must be a region or call uct");
347-
predicate = parse_predicate->in(0);
348-
while (predicate != nullptr && predicate->is_Proj() && predicate->in(0)->is_If()) {
349-
IfNode* iff = predicate->in(0)->as_If();
350-
uncommon_proj = iff->proj_out(1 - predicate->as_Proj()->_con);
351-
if (uncommon_proj->unique_ctrl_out() != rgn) {
352-
break;
353-
}
354-
Node* bol = iff->in(1);
355-
assert(!bol->is_OpaqueInitializedAssertionPredicate(), "should not find an Initialized Assertion Predicate");
356-
if (bol->is_OpaqueTemplateAssertionPredicate()) {
357-
assert(assertion_predicate_has_loop_opaque_node(iff), "must find OpaqueLoop* nodes");
358-
if (get_opaque) {
359-
// Collect the OpaqueTemplateAssertionPredicateNode.
360-
list.push(bol);
361-
} else {
362-
// Collect the predicate projection.
363-
list.push(predicate);
364-
}
365-
}
366-
predicate = predicate->in(0)->in(0);
367-
}
338+
// is set, then the OpaqueTemplateAssertionPredicateNode nodes of the Assertion Predicates are put on the list instead
339+
// of the projections.
340+
void PhaseIdealLoop::get_assertion_predicates(ParsePredicateSuccessProj* parse_predicate_proj, Unique_Node_List& list,
341+
const bool get_opaque) {
342+
Deoptimization::DeoptReason deopt_reason = parse_predicate_proj->in(0)->as_ParsePredicate()->deopt_reason();
343+
PredicateBlockIterator predicate_iterator(parse_predicate_proj, deopt_reason);
344+
TemplateAssertionPredicateCollector template_assertion_predicate_collector(list, get_opaque);
345+
predicate_iterator.for_each(template_assertion_predicate_collector);
368346
}
369347

370348
// Clone an Assertion Predicate for an unswitched loop. OpaqueLoopInit and OpaqueLoopStride nodes are cloned and uncommon

src/hotspot/share/opto/loopnode.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -4469,15 +4469,15 @@ void PhaseIdealLoop::collect_useful_template_assertion_predicates_for_loop(Ideal
44694469
if (UseProfiledLoopPredicate) {
44704470
const PredicateBlock* profiled_loop_predicate_block = predicates.profiled_loop_predicate_block();
44714471
if (profiled_loop_predicate_block->has_parse_predicate()) {
4472-
IfProjNode* parse_predicate_proj = profiled_loop_predicate_block->parse_predicate_success_proj();
4472+
ParsePredicateSuccessProj* parse_predicate_proj = profiled_loop_predicate_block->parse_predicate_success_proj();
44734473
get_assertion_predicates(parse_predicate_proj, useful_predicates, true);
44744474
}
44754475
}
44764476

44774477
if (UseLoopPredicate) {
44784478
const PredicateBlock* loop_predicate_block = predicates.loop_predicate_block();
44794479
if (loop_predicate_block->has_parse_predicate()) {
4480-
IfProjNode* parse_predicate_proj = loop_predicate_block->parse_predicate_success_proj();
4480+
ParsePredicateSuccessProj* parse_predicate_proj = loop_predicate_block->parse_predicate_success_proj();
44814481
get_assertion_predicates(parse_predicate_proj, useful_predicates, true);
44824482
}
44834483
}

src/hotspot/share/opto/loopnode.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -947,7 +947,7 @@ class PhaseIdealLoop : public PhaseTransform {
947947
DEBUG_ONLY(static bool assertion_predicate_has_loop_opaque_node(IfNode* iff);)
948948
private:
949949
DEBUG_ONLY(static void count_opaque_loop_nodes(Node* n, uint& init, uint& stride);)
950-
static void get_assertion_predicates(Node* predicate, Unique_Node_List& list, bool get_opaque = false);
950+
static void get_assertion_predicates(ParsePredicateSuccessProj* parse_predicate_proj, Unique_Node_List& list, bool get_opaque = false);
951951
void update_main_loop_assertion_predicates(Node* ctrl, CountedLoopNode* loop_head, Node* init, int stride_con);
952952
void initialize_assertion_predicates_for_peeled_loop(CountedLoopNode* peeled_loop_head,
953953
CountedLoopNode* remaining_loop_head,
@@ -1672,7 +1672,7 @@ class PhaseIdealLoop : public PhaseTransform {
16721672
IfProjNode* clone_parse_predicate_to_unswitched_loop(ParsePredicateSuccessProj* parse_predicate_proj, Node* new_entry,
16731673
Deoptimization::DeoptReason reason, bool slow_loop);
16741674
void clone_assertion_predicates_to_unswitched_loop(IdealLoopTree* loop, const Node_List& old_new,
1675-
Deoptimization::DeoptReason reason, IfProjNode* old_predicate_proj,
1675+
Deoptimization::DeoptReason reason, ParsePredicateSuccessProj* old_parse_predicate_proj,
16761676
ParsePredicateSuccessProj* fast_loop_parse_predicate_proj,
16771677
ParsePredicateSuccessProj* slow_loop_parse_predicate_proj);
16781678
IfProjNode* clone_assertion_predicate_for_unswitched_loops(IfNode* template_assertion_predicate, IfProjNode* predicate,

src/hotspot/share/opto/predicates.hpp

+22
Original file line numberDiff line numberDiff line change
@@ -1010,4 +1010,26 @@ class CreateAssertionPredicatesVisitor : public PredicateVisitor {
10101010
}
10111011
};
10121012

1013+
// This visitor collects all Template Assertion Predicates If nodes or the corresponding Opaque nodes, depending on the
1014+
// provided 'get_opaque' flag, to the provided list.
1015+
class TemplateAssertionPredicateCollector : public PredicateVisitor {
1016+
Unique_Node_List& _list;
1017+
const bool _get_opaque;
1018+
1019+
public:
1020+
TemplateAssertionPredicateCollector(Unique_Node_List& list, const bool get_opaque)
1021+
: _list(list),
1022+
_get_opaque(get_opaque) {}
1023+
1024+
using PredicateVisitor::visit;
1025+
1026+
void visit(const TemplateAssertionPredicate& template_assertion_predicate) override {
1027+
if (_get_opaque) {
1028+
_list.push(template_assertion_predicate.opaque_node());
1029+
} else {
1030+
_list.push(template_assertion_predicate.tail());
1031+
}
1032+
}
1033+
};
1034+
10131035
#endif // SHARE_OPTO_PREDICATES_HPP

0 commit comments

Comments
 (0)