3232// (i.e. not belonging to an Initialized Assertion Predicate anymore)
3333Node* AssertionPredicatesWithHalt::find_entry (Node* start_proj) {
3434 Node* entry = start_proj;
35- while (is_assertion_predicate_success_proj (entry)) {
35+ while (AssertionPredicateWithHalt::is_predicate (entry)) {
3636 entry = entry->in (0 )->in (0 );
3737 }
3838 return entry;
3939}
4040
41- bool AssertionPredicatesWithHalt::is_assertion_predicate_success_proj (const Node* predicate_proj ) {
42- if (predicate_proj == nullptr || !predicate_proj ->is_IfProj () || !predicate_proj ->in (0 )->is_If ()) {
41+ bool AssertionPredicateWithHalt::is_predicate (const Node* maybe_success_proj ) {
42+ if (maybe_success_proj == nullptr || !maybe_success_proj ->is_IfProj () || !maybe_success_proj ->in (0 )->is_If ()) {
4343 return false ;
4444 }
45- return has_assertion_predicate_opaque (predicate_proj ) && has_halt (predicate_proj );
45+ return has_assertion_predicate_opaque (maybe_success_proj ) && has_halt (maybe_success_proj );
4646}
4747
4848// Check if the If node of `predicate_proj` has an Opaque4 (Template Assertion Predicate) or an
4949// OpaqueInitializedAssertionPredicate (Initialized Assertion Predicate) node as input.
50- bool AssertionPredicatesWithHalt ::has_assertion_predicate_opaque (const Node* predicate_proj) {
50+ bool AssertionPredicateWithHalt ::has_assertion_predicate_opaque (const Node* predicate_proj) {
5151 IfNode* iff = predicate_proj->in (0 )->as_If ();
5252 Node* bol = iff->in (1 );
5353 return bol->is_Opaque4 () || bol->is_OpaqueInitializedAssertionPredicate ();
5454}
5555
5656// Check if the other projection (UCT projection) of `success_proj` has a Halt node as output.
57- bool AssertionPredicatesWithHalt ::has_halt (const Node* success_proj) {
57+ bool AssertionPredicateWithHalt ::has_halt (const Node* success_proj) {
5858 ProjNode* other_proj = success_proj->as_IfProj ()->other_if_proj ();
5959 return other_proj->outcnt () == 1 && other_proj->unique_out ()->Opcode () == Op_Halt;
6060}
@@ -72,24 +72,44 @@ ParsePredicateNode* ParsePredicate::init_parse_predicate(Node* parse_predicate_p
7272 return nullptr ;
7373}
7474
75- Deoptimization::DeoptReason RuntimePredicate::uncommon_trap_reason (IfProjNode* if_proj) {
75+ bool ParsePredicate::is_predicate (Node* maybe_success_proj) {
76+ if (!maybe_success_proj->is_IfProj ()) {
77+ return false ;
78+ }
79+ IfNode* if_node = maybe_success_proj->in (0 )->as_If ();
80+ return if_node->is_ParsePredicate ();
81+ }
82+
83+ Deoptimization::DeoptReason RegularPredicateWithUCT::uncommon_trap_reason (IfProjNode* if_proj) {
7684 CallStaticJavaNode* uct_call = if_proj->is_uncommon_trap_if_pattern ();
7785 if (uct_call == nullptr ) {
7886 return Deoptimization::Reason_none;
7987 }
8088 return Deoptimization::trap_request_reason (uct_call->uncommon_trap_request ());
8189}
8290
83- bool RuntimePredicate::is_success_proj (Node* node, Deoptimization::DeoptReason deopt_reason) {
84- if (may_be_runtime_predicate_if (node)) {
91+ bool RegularPredicateWithUCT::is_predicate (Node* maybe_success_proj) {
92+ if (may_be_predicate_if (maybe_success_proj)) {
93+ IfProjNode* success_proj = maybe_success_proj->as_IfProj ();
94+ const Deoptimization::DeoptReason deopt_reason = uncommon_trap_reason (success_proj);
95+ return (deopt_reason == Deoptimization::Reason_loop_limit_check ||
96+ deopt_reason == Deoptimization::Reason_predicate ||
97+ deopt_reason == Deoptimization::Reason_profile_predicate);
98+ } else {
99+ return false ;
100+ }
101+ }
102+
103+ bool RegularPredicateWithUCT::is_predicate (Node* node, Deoptimization::DeoptReason deopt_reason) {
104+ if (may_be_predicate_if (node)) {
85105 return deopt_reason == uncommon_trap_reason (node->as_IfProj ());
86106 } else {
87107 return false ;
88108 }
89109}
90110
91111// A Runtime Predicate must have an If or a RangeCheck node, while the If should not be a zero trip guard check.
92- bool RuntimePredicate::may_be_runtime_predicate_if (Node* node) {
112+ bool RegularPredicateWithUCT::may_be_predicate_if (Node* node) {
93113 if (node->is_IfProj ()) {
94114 const IfNode* if_node = node->in (0 )->as_If ();
95115 const int opcode_if = if_node->Opcode ();
@@ -101,6 +121,10 @@ bool RuntimePredicate::may_be_runtime_predicate_if(Node* node) {
101121 return false ;
102122}
103123
124+ bool RuntimePredicate::is_success_proj (Node* node, Deoptimization::DeoptReason deopt_reason) {
125+ return RegularPredicateWithUCT::is_predicate (node, deopt_reason);
126+ }
127+
104128ParsePredicateIterator::ParsePredicateIterator (const Predicates& predicates) : _current_index(0 ) {
105129 const PredicateBlock* loop_limit_check_predicate_block = predicates.loop_limit_check_predicate_block ();
106130 if (loop_limit_check_predicate_block->has_parse_predicate ()) {
@@ -356,3 +380,18 @@ bool TemplateAssertionPredicateExpressionNode::is_in_expression(Node* node) {
356380bool TemplateAssertionPredicateExpressionNode::is_template_assertion_predicate (Node* node) {
357381 return node->is_If () && node->in (1 )->is_Opaque4 ();
358382}
383+
384+ // Is current node pointed to by iterator a predicate?
385+ bool PredicateEntryIterator::has_next () const {
386+ return ParsePredicate::is_predicate (_current) ||
387+ RegularPredicateWithUCT::is_predicate (_current) ||
388+ AssertionPredicateWithHalt::is_predicate (_current);
389+ }
390+
391+ // Skip the current predicate pointed to by iterator by returning the input into the predicate. This could possibly be
392+ // a non-predicate node.
393+ Node* PredicateEntryIterator::next_entry () {
394+ assert (has_next (), " current must be predicate" );
395+ _current = _current->in (0 )->in (0 );
396+ return _current;
397+ }
0 commit comments