8346774: Use Predicate classes instead of Node classes

Reviewed-by: epeter, kvn
This commit is contained in:
Christian Hagedorn 2025-02-04 07:33:34 +00:00
parent 7ea176d79c
commit c545a3e028
2 changed files with 120 additions and 95 deletions

View File

@ -81,13 +81,13 @@ ParsePredicateNode* ParsePredicate::init_parse_predicate(Node* parse_predicate_p
return nullptr; return nullptr;
} }
ParsePredicateSuccessProj* ParsePredicate::clone_to_unswitched_loop(Node* new_control, const bool is_true_path_loop, ParsePredicate ParsePredicate::clone_to_unswitched_loop(Node* new_control, const bool is_true_path_loop,
PhaseIdealLoop* phase) const { PhaseIdealLoop* phase) const {
ParsePredicateSuccessProj* success_proj = phase->create_new_if_for_predicate(_success_proj, new_control, ParsePredicateSuccessProj* success_proj = phase->create_new_if_for_predicate(_success_proj, new_control,
_parse_predicate_node->deopt_reason(), _parse_predicate_node->deopt_reason(),
Op_ParsePredicate, is_true_path_loop); Op_ParsePredicate, is_true_path_loop);
NOT_PRODUCT(trace_cloned_parse_predicate(is_true_path_loop, success_proj)); NOT_PRODUCT(trace_cloned_parse_predicate(is_true_path_loop, success_proj));
return success_proj; return ParsePredicate(success_proj, _parse_predicate_node->deopt_reason());
} }
#ifndef PRODUCT #ifndef PRODUCT
@ -169,8 +169,8 @@ bool TemplateAssertionPredicate::is_predicate(Node* node) {
return if_node->in(1)->is_OpaqueTemplateAssertionPredicate(); return if_node->in(1)->is_OpaqueTemplateAssertionPredicate();
} }
// Clone this Template Assertion Predicate and replace the OpaqueLoopInitNode with the provided 'new_opaque_init' node. // Clone this Template Assertion Predicate without modifying any OpaqueLoop*Node inputs.
IfTrueNode* TemplateAssertionPredicate::clone(Node* new_control, PhaseIdealLoop* phase) const { TemplateAssertionPredicate TemplateAssertionPredicate::clone(Node* new_control, PhaseIdealLoop* phase) const {
DEBUG_ONLY(verify();) DEBUG_ONLY(verify();)
TemplateAssertionExpression template_assertion_expression(opaque_node()); TemplateAssertionExpression template_assertion_expression(opaque_node());
OpaqueTemplateAssertionPredicateNode* new_opaque_node = template_assertion_expression.clone(new_control, phase); OpaqueTemplateAssertionPredicateNode* new_opaque_node = template_assertion_expression.clone(new_control, phase);
@ -178,14 +178,18 @@ IfTrueNode* TemplateAssertionPredicate::clone(Node* new_control, PhaseIdealLoop*
IfTrueNode* success_proj = assertion_predicate_if_creator.create_for_template(new_control, _if_node->Opcode(), IfTrueNode* success_proj = assertion_predicate_if_creator.create_for_template(new_control, _if_node->Opcode(),
new_opaque_node, new_opaque_node,
_if_node->assertion_predicate_type()); _if_node->assertion_predicate_type());
DEBUG_ONLY(TemplateAssertionPredicate::verify(success_proj);) TemplateAssertionPredicate cloned_template_assertion_predicate(success_proj);
return success_proj; DEBUG_ONLY(cloned_template_assertion_predicate.verify();)
return cloned_template_assertion_predicate;
} }
// Clone this Template Assertion Predicate and replace the OpaqueLoopInitNode with the provided 'new_opaque_init' node. // Clone this Template Assertion Predicate and use a newly created OpaqueLoopInitNode with 'new_opaque_input' as input.
IfTrueNode* TemplateAssertionPredicate::clone_and_replace_init(Node* new_control, OpaqueLoopInitNode* new_opaque_init, TemplateAssertionPredicate TemplateAssertionPredicate::clone_and_replace_opaque_input(Node* new_control,
PhaseIdealLoop* phase) const { Node* new_opaque_input,
PhaseIdealLoop* phase) const {
DEBUG_ONLY(verify();) DEBUG_ONLY(verify();)
OpaqueLoopInitNode* new_opaque_init = new OpaqueLoopInitNode(phase->C, new_opaque_input);
phase->register_new_node(new_opaque_init, new_control);
TemplateAssertionExpression template_assertion_expression(opaque_node()); TemplateAssertionExpression template_assertion_expression(opaque_node());
OpaqueTemplateAssertionPredicateNode* new_opaque_node = OpaqueTemplateAssertionPredicateNode* new_opaque_node =
template_assertion_expression.clone_and_replace_init(new_control, new_opaque_init, phase); template_assertion_expression.clone_and_replace_init(new_control, new_opaque_init, phase);
@ -193,8 +197,9 @@ IfTrueNode* TemplateAssertionPredicate::clone_and_replace_init(Node* new_control
IfTrueNode* success_proj = assertion_predicate_if_creator.create_for_template(new_control, _if_node->Opcode(), IfTrueNode* success_proj = assertion_predicate_if_creator.create_for_template(new_control, _if_node->Opcode(),
new_opaque_node, new_opaque_node,
_if_node->assertion_predicate_type()); _if_node->assertion_predicate_type());
DEBUG_ONLY(TemplateAssertionPredicate::verify(success_proj);) TemplateAssertionPredicate cloned_template_assertion_predicate(success_proj);
return success_proj; DEBUG_ONLY(cloned_template_assertion_predicate.verify();)
return cloned_template_assertion_predicate;
} }
// Replace the input to OpaqueLoopStrideNode with 'new_stride' and leave the other nodes unchanged. // Replace the input to OpaqueLoopStrideNode with 'new_stride' and leave the other nodes unchanged.
@ -204,14 +209,14 @@ void TemplateAssertionPredicate::replace_opaque_stride_input(Node* new_stride, P
expression.replace_opaque_stride_input(new_stride, igvn); expression.replace_opaque_stride_input(new_stride, igvn);
} }
// Create a new Initialized Assertion Predicate from this template at 'new_control' and return the success projection // Create a new Initialized Assertion Predicate from this template at the template success projection.
// of the newly created Initialized Assertion Predicate. InitializedAssertionPredicate TemplateAssertionPredicate::initialize(PhaseIdealLoop* phase) const {
IfTrueNode* TemplateAssertionPredicate::initialize(PhaseIdealLoop* phase, Node* new_control) const {
DEBUG_ONLY(verify();) DEBUG_ONLY(verify();)
InitializedAssertionPredicateCreator initialized_assertion_predicate_creator(phase); InitializedAssertionPredicateCreator initialized_assertion_predicate_creator(phase);
IfTrueNode* success_proj = initialized_assertion_predicate_creator.create_from_template(head(), new_control); InitializedAssertionPredicate initialized_assertion_predicate =
DEBUG_ONLY(InitializedAssertionPredicate::verify(success_proj);) initialized_assertion_predicate_creator.create_from_template_and_insert_below(*this);
return success_proj; DEBUG_ONLY(initialized_assertion_predicate.verify();)
return initialized_assertion_predicate;
} }
// Kills the Template Assertion Predicate by setting the condition to true. Will be folded away in the next IGVN round. // Kills the Template Assertion Predicate by setting the condition to true. Will be folded away in the next IGVN round.
@ -746,7 +751,7 @@ Node* TemplateAssertionPredicateCreator::create_last_value(Node* new_control, Op
IfTrueNode* TemplateAssertionPredicateCreator::create_if_node( IfTrueNode* TemplateAssertionPredicateCreator::create_if_node(
Node* new_control, OpaqueTemplateAssertionPredicateNode* template_assertion_predicate_expression, Node* new_control, OpaqueTemplateAssertionPredicateNode* template_assertion_predicate_expression,
const bool does_overflow, const AssertionPredicateType assertion_predicate_type) { const bool does_overflow, const AssertionPredicateType assertion_predicate_type) const {
AssertionPredicateIfCreator assertion_predicate_if_creator(_phase); AssertionPredicateIfCreator assertion_predicate_if_creator(_phase);
return assertion_predicate_if_creator.create_for_template(new_control, does_overflow ? Op_If : Op_RangeCheck, return assertion_predicate_if_creator.create_for_template(new_control, does_overflow ? Op_If : Op_RangeCheck,
template_assertion_predicate_expression, template_assertion_predicate_expression,
@ -780,7 +785,7 @@ InitializedAssertionPredicateCreator::InitializedAssertionPredicateCreator(Phase
// Create an Initialized Assertion Predicate from the provided template_assertion_predicate at 'new_control'. // Create an Initialized Assertion Predicate from the provided template_assertion_predicate at 'new_control'.
// We clone the Template Assertion Expression and replace: // We clone the Template Assertion Expression and replace:
// - OpaqueTemplateAssertionPredicateNode with OpaqueInitializedAssertionPredicate // - OpaqueTemplateAssertionPredicateNode with OpaqueInitializedAssertionPredicate
// - OpaqueLoop*Nodes with new_init and _ew_stride, respectively. // - OpaqueLoop*Nodes with new_init and new_stride, respectively.
// //
// / init stride // / init stride
// | | | // | | |
@ -797,32 +802,38 @@ InitializedAssertionPredicateCreator::InitializedAssertionPredicateCreator(Phase
// success fail path new success new Halt // success fail path new success new Halt
// proj (Halt or UCT) proj // proj (Halt or UCT) proj
// //
IfTrueNode* InitializedAssertionPredicateCreator::create_from_template(IfNode* template_assertion_predicate, InitializedAssertionPredicate InitializedAssertionPredicateCreator::create_from_template(
Node* new_control, Node* new_init, IfNode* template_assertion_predicate, Node* new_control, Node* new_init, Node* new_stride) const {
Node* new_stride) {
OpaqueInitializedAssertionPredicateNode* assertion_expression = OpaqueInitializedAssertionPredicateNode* assertion_expression =
create_assertion_expression_from_template(template_assertion_predicate, new_control, new_init, new_stride); create_assertion_expression_from_template(template_assertion_predicate, new_control, new_init, new_stride);
return create_control_nodes(new_control, template_assertion_predicate->Opcode(), assertion_expression, IfTrueNode* success_proj = create_control_nodes(new_control,
template_assertion_predicate->assertion_predicate_type()); template_assertion_predicate->Opcode(),
assertion_expression,
template_assertion_predicate->assertion_predicate_type());
return InitializedAssertionPredicate(success_proj);
} }
// Create a new Initialized Assertion Predicate from 'template_assertion_predicate' by cloning it but omitting the // Create a new Initialized Assertion Predicate from the provided Template Assertion Predicate at the template success
// OpaqueLoop*Notes (i.e. taking their inputs instead). // projection by cloning it but omitting the OpaqueLoop*Notes (i.e. taking their inputs instead).
IfTrueNode* InitializedAssertionPredicateCreator::create_from_template(IfNode* template_assertion_predicate, InitializedAssertionPredicate InitializedAssertionPredicateCreator::create_from_template_and_insert_below(
Node* new_control) { const TemplateAssertionPredicate& template_assertion_predicate) const {
OpaqueTemplateAssertionPredicateNode* template_opaque = TemplateAssertionExpression template_assertion_expression(template_assertion_predicate.opaque_node());
template_assertion_predicate->in(1)->as_OpaqueTemplateAssertionPredicate(); IfTrueNode* template_assertion_predicate_success_proj = template_assertion_predicate.tail();
TemplateAssertionExpression template_assertion_expression(template_opaque);
OpaqueInitializedAssertionPredicateNode* assertion_expression = OpaqueInitializedAssertionPredicateNode* assertion_expression =
template_assertion_expression.clone_and_fold_opaque_loop_nodes(new_control, _phase); template_assertion_expression.clone_and_fold_opaque_loop_nodes(template_assertion_predicate_success_proj, _phase);
return create_control_nodes(new_control, template_assertion_predicate->Opcode(), assertion_expression,
template_assertion_predicate->assertion_predicate_type()); IfNode* template_assertion_predicate_if = template_assertion_predicate.head();
AssertionPredicateType assertion_predicate_type = template_assertion_predicate_if->assertion_predicate_type();
int if_opcode = template_assertion_predicate_if->Opcode();
IfTrueNode* success_proj = create_control_nodes(template_assertion_predicate_success_proj, if_opcode,
assertion_expression, assertion_predicate_type);
return InitializedAssertionPredicate(success_proj);
} }
// Create a new Initialized Assertion Predicate directly without a template. // Create a new Initialized Assertion Predicate directly without a template.
IfTrueNode* InitializedAssertionPredicateCreator::create(Node* operand, Node* new_control, const jint stride, IfTrueNode* InitializedAssertionPredicateCreator::create(Node* operand, Node* new_control, const jint stride,
const int scale, Node* offset, Node* range, const int scale, Node* offset, Node* range,
const AssertionPredicateType assertion_predicate_type) { const AssertionPredicateType assertion_predicate_type) const {
AssertionPredicateExpressionCreator expression_creator(stride, scale, offset, range, _phase); AssertionPredicateExpressionCreator expression_creator(stride, scale, offset, range, _phase);
bool does_overflow; bool does_overflow;
OpaqueInitializedAssertionPredicateNode* assertion_expression = OpaqueInitializedAssertionPredicateNode* assertion_expression =
@ -836,7 +847,7 @@ IfTrueNode* InitializedAssertionPredicateCreator::create(Node* operand, Node* ne
// Creates the CFG nodes for the Initialized Assertion Predicate. // Creates the CFG nodes for the Initialized Assertion Predicate.
IfTrueNode* InitializedAssertionPredicateCreator::create_control_nodes( IfTrueNode* InitializedAssertionPredicateCreator::create_control_nodes(
Node* new_control, const int if_opcode, OpaqueInitializedAssertionPredicateNode* assertion_expression, Node* new_control, const int if_opcode, OpaqueInitializedAssertionPredicateNode* assertion_expression,
const AssertionPredicateType assertion_predicate_type) { const AssertionPredicateType assertion_predicate_type) const {
AssertionPredicateIfCreator assertion_predicate_if_creator(_phase); AssertionPredicateIfCreator assertion_predicate_if_creator(_phase);
return assertion_predicate_if_creator.create_for_initialized(new_control, if_opcode, assertion_expression, return assertion_predicate_if_creator.create_for_initialized(new_control, if_opcode, assertion_expression,
assertion_predicate_type); assertion_predicate_type);
@ -847,7 +858,7 @@ IfTrueNode* InitializedAssertionPredicateCreator::create_control_nodes(
OpaqueInitializedAssertionPredicateNode* OpaqueInitializedAssertionPredicateNode*
InitializedAssertionPredicateCreator::create_assertion_expression_from_template(IfNode* template_assertion_predicate, InitializedAssertionPredicateCreator::create_assertion_expression_from_template(IfNode* template_assertion_predicate,
Node* new_control, Node* new_init, Node* new_control, Node* new_init,
Node* new_stride) { Node* new_stride) const {
OpaqueTemplateAssertionPredicateNode* template_opaque = OpaqueTemplateAssertionPredicateNode* template_opaque =
template_assertion_predicate->in(1)->as_OpaqueTemplateAssertionPredicate(); template_assertion_predicate->in(1)->as_OpaqueTemplateAssertionPredicate();
TemplateAssertionExpression template_assertion_expression(template_opaque); TemplateAssertionExpression template_assertion_expression(template_opaque);
@ -931,36 +942,39 @@ void CreateAssertionPredicatesVisitor::visit(const TemplateAssertionPredicate& t
return; return;
} }
if (_clone_template) { if (_clone_template) {
IfTrueNode* cloned_template_success_proj = clone_template_and_replace_init_input(template_assertion_predicate); TemplateAssertionPredicate cloned_template_assertion_predicate =
initialize_from_template(template_assertion_predicate, cloned_template_success_proj); clone_template_and_replace_init_input(template_assertion_predicate);
_current_predicate_chain_head = cloned_template_success_proj->in(0); initialize_from_template(template_assertion_predicate, cloned_template_assertion_predicate.tail());
_current_predicate_chain_head = cloned_template_assertion_predicate.head();
} else { } else {
IfTrueNode* initialized_success_proj = initialize_from_template(template_assertion_predicate, _old_target_loop_entry); InitializedAssertionPredicate initialized_assertion_predicate =
_current_predicate_chain_head = initialized_success_proj->in(0); initialize_from_template(template_assertion_predicate, _old_target_loop_entry);
_current_predicate_chain_head = initialized_assertion_predicate.head();
} }
} }
// Create an Initialized Assertion Predicate from the provided Template Assertion Predicate. // Create an Initialized Assertion Predicate from the provided Template Assertion Predicate.
IfTrueNode* CreateAssertionPredicatesVisitor::initialize_from_template( InitializedAssertionPredicate CreateAssertionPredicatesVisitor::initialize_from_template(
const TemplateAssertionPredicate& template_assertion_predicate, Node* new_control) const { const TemplateAssertionPredicate& template_assertion_predicate, Node* new_control) const {
DEBUG_ONLY(template_assertion_predicate.verify();) DEBUG_ONLY(template_assertion_predicate.verify();)
IfNode* template_head = template_assertion_predicate.head(); IfNode* template_head = template_assertion_predicate.head();
InitializedAssertionPredicateCreator initialized_assertion_predicate_creator(_phase); InitializedAssertionPredicateCreator initialized_assertion_predicate_creator(_phase);
IfTrueNode* initialized_predicate = initialized_assertion_predicate_creator.create_from_template(template_head, InitializedAssertionPredicate initialized_assertion_predicate =
new_control, initialized_assertion_predicate_creator.create_from_template(template_head, new_control, _init, _stride);
_init, _stride);
DEBUG_ONLY(InitializedAssertionPredicate::verify(initialized_predicate);) DEBUG_ONLY(initialized_assertion_predicate.verify();)
template_assertion_predicate.rewire_loop_data_dependencies(initialized_predicate, _node_in_loop_body, _phase); template_assertion_predicate.rewire_loop_data_dependencies(initialized_assertion_predicate.tail(),
rewire_to_old_predicate_chain_head(initialized_predicate); _node_in_loop_body, _phase);
return initialized_predicate; rewire_to_old_predicate_chain_head(initialized_assertion_predicate.tail());
return initialized_assertion_predicate;
} }
// Clone the provided 'template_assertion_predicate' and set '_init' as new input for the OpaqueLoopInitNode. // Clone the provided Template Assertion Predicate and set '_init' as new input for the OpaqueLoopInitNode.
IfTrueNode* CreateAssertionPredicatesVisitor::clone_template_and_replace_init_input( TemplateAssertionPredicate CreateAssertionPredicatesVisitor::clone_template_and_replace_init_input(
const TemplateAssertionPredicate& template_assertion_predicate) { const TemplateAssertionPredicate& template_assertion_predicate) const {
OpaqueLoopInitNode* opaque_init = new OpaqueLoopInitNode(_phase->C, _init); TemplateAssertionPredicate new_template =
_phase->register_new_node(opaque_init, _old_target_loop_entry); template_assertion_predicate.clone_and_replace_opaque_input(_old_target_loop_entry, _init, _phase);
return template_assertion_predicate.clone_and_replace_init(_old_target_loop_entry, opaque_init, _phase); return new_template;
} }
// Rewire the newly created predicates to the old predicate chain head (i.e. '_current_predicate_chain_head') by // Rewire the newly created predicates to the old predicate chain head (i.e. '_current_predicate_chain_head') by
@ -1008,10 +1022,11 @@ TargetLoopPredicateChain::TargetLoopPredicateChain(LoopNode* loop_head, PhaseIde
_phase(phase) {} _phase(phase) {}
// Inserts the provided newly cloned predicate to the head of the target loop predicate chain. // Inserts the provided newly cloned predicate to the head of the target loop predicate chain.
void TargetLoopPredicateChain::insert_predicate(IfTrueNode* predicate_success_proj) { void TargetLoopPredicateChain::insert_predicate(const Predicate& predicate) {
rewire_to_target_chain_head(predicate_success_proj); rewire_to_target_chain_head(predicate.tail()->as_IfTrue());
_current_predicate_chain_head = predicate_success_proj->in(0); _current_predicate_chain_head = predicate.head();
assert(predicate_success_proj->_idx >= _node_index_before_cloning, "must be a newly cloned predicate"); assert(predicate.head()->_idx >= _node_index_before_cloning, "must be a newly cloned predicate");
assert(predicate.tail()->_idx >= _node_index_before_cloning, "must be a newly cloned predicate");
assert(_current_predicate_chain_head->in(0) == _old_target_loop_entry && assert(_current_predicate_chain_head->in(0) == _old_target_loop_entry &&
_old_target_loop_entry->unique_ctrl_out() == _current_predicate_chain_head , "must be connected now"); _old_target_loop_entry->unique_ctrl_out() == _current_predicate_chain_head , "must be connected now");
} }
@ -1068,7 +1083,8 @@ void CloneUnswitchedLoopPredicatesVisitor::visit(const TemplateAssertionPredicat
template_assertion_predicate.kill(_phase); template_assertion_predicate.kill(_phase);
} }
// Clone the Template Assertion Predicate and set a new input for the OpaqueLoopStrideNode. // Update the Template Assertion Predicate by setting a new input for the OpaqueLoopStrideNode. Create a new
// Initialized Assertion Predicate from the updated Template Assertion Predicate.
void UpdateStrideForAssertionPredicates::visit(const TemplateAssertionPredicate& template_assertion_predicate) { void UpdateStrideForAssertionPredicates::visit(const TemplateAssertionPredicate& template_assertion_predicate) {
if (!template_assertion_predicate.is_last_value()) { if (!template_assertion_predicate.is_last_value()) {
// Only Last Value Assertion Predicates have an OpaqueLoopStrideNode. // Only Last Value Assertion Predicates have an OpaqueLoopStrideNode.
@ -1076,8 +1092,9 @@ void UpdateStrideForAssertionPredicates::visit(const TemplateAssertionPredicate&
} }
replace_opaque_stride_input(template_assertion_predicate); replace_opaque_stride_input(template_assertion_predicate);
Node* template_tail_control_out = template_assertion_predicate.tail()->unique_ctrl_out(); Node* template_tail_control_out = template_assertion_predicate.tail()->unique_ctrl_out();
IfTrueNode* initialized_success_proj = initialize_from_updated_template(template_assertion_predicate); InitializedAssertionPredicate initialized_assertion_predicate =
connect_initialized_assertion_predicate(template_tail_control_out, initialized_success_proj); initialize_from_updated_template(template_assertion_predicate);
connect_initialized_assertion_predicate(template_tail_control_out, initialized_assertion_predicate);
} }
// Replace the input to OpaqueLoopStrideNode with 'new_stride' and leave the other nodes unchanged. // Replace the input to OpaqueLoopStrideNode with 'new_stride' and leave the other nodes unchanged.
@ -1086,20 +1103,20 @@ void UpdateStrideForAssertionPredicates::replace_opaque_stride_input(
template_assertion_predicate.replace_opaque_stride_input(_new_stride, _phase->igvn()); template_assertion_predicate.replace_opaque_stride_input(_new_stride, _phase->igvn());
} }
IfTrueNode* UpdateStrideForAssertionPredicates::initialize_from_updated_template( InitializedAssertionPredicate UpdateStrideForAssertionPredicates::initialize_from_updated_template(
const TemplateAssertionPredicate& template_assertion_predicate) const { const TemplateAssertionPredicate& template_assertion_predicate) const {
IfTrueNode* initialized_success_proj = template_assertion_predicate.initialize(_phase, template_assertion_predicate.tail()); return template_assertion_predicate.initialize(_phase);
return initialized_success_proj;
} }
// The newly created Initialized Assertion Predicate can safely be inserted because this visitor is already visiting // The newly created Initialized Assertion Predicate can safely be inserted because this visitor is already visiting
// the Template Assertion Predicate above this. So, we will not accidentally visit this again and kill it with the // the Template Assertion Predicate above this. So, we will not accidentally visit this again and kill it with the
// visit() method for Initialized Assertion Predicates. // visit() method for Initialized Assertion Predicates.
void UpdateStrideForAssertionPredicates::connect_initialized_assertion_predicate( void UpdateStrideForAssertionPredicates::connect_initialized_assertion_predicate(
Node* new_control_out, IfTrueNode* initialized_success_proj) const { Node* new_control_out, const InitializedAssertionPredicate& initialized_assertion_predicate) const {
Node* initialized_assertion_predicate_success_proj = initialized_assertion_predicate.tail();
if (new_control_out->is_Loop()) { if (new_control_out->is_Loop()) {
_phase->replace_loop_entry(new_control_out->as_Loop(), initialized_success_proj); _phase->replace_loop_entry(new_control_out->as_Loop(), initialized_assertion_predicate_success_proj);
} else { } else {
_phase->replace_control(new_control_out, initialized_success_proj); _phase->replace_control(new_control_out, initialized_assertion_predicate_success_proj);
} }
} }

View File

@ -327,8 +327,8 @@ class ParsePredicate : public Predicate {
return _success_proj; return _success_proj;
} }
ParsePredicateSuccessProj* clone_to_unswitched_loop(Node* new_control, bool is_true_path_loop, ParsePredicate clone_to_unswitched_loop(Node* new_control, bool is_true_path_loop,
PhaseIdealLoop* phase) const; PhaseIdealLoop* phase) const;
// Kills this Parse Predicate by marking it useless. Will be folded away in the next IGVN round. // Kills this Parse Predicate by marking it useless. Will be folded away in the next IGVN round.
void kill(const PhaseIterGVN& igvn) const { void kill(const PhaseIterGVN& igvn) const {
@ -403,10 +403,11 @@ class TemplateAssertionPredicate : public Predicate {
return _if_node->assertion_predicate_type() == AssertionPredicateType::LastValue; return _if_node->assertion_predicate_type() == AssertionPredicateType::LastValue;
} }
IfTrueNode* clone(Node* new_control, PhaseIdealLoop* phase) const; TemplateAssertionPredicate clone(Node* new_control, PhaseIdealLoop* phase) const;
IfTrueNode* clone_and_replace_init(Node* new_control, OpaqueLoopInitNode* new_opaque_init, PhaseIdealLoop* phase) const; TemplateAssertionPredicate clone_and_replace_opaque_input(Node* new_control, Node* new_opaque_input,
PhaseIdealLoop* phase) const;
void replace_opaque_stride_input(Node* new_stride, PhaseIterGVN& igvn) const; void replace_opaque_stride_input(Node* new_stride, PhaseIterGVN& igvn) const;
IfTrueNode* initialize(PhaseIdealLoop* phase, Node* new_control) const; InitializedAssertionPredicate initialize(PhaseIdealLoop* phase) const;
void rewire_loop_data_dependencies(IfTrueNode* target_predicate, const NodeInLoopBody& data_in_loop_body, void rewire_loop_data_dependencies(IfTrueNode* target_predicate, const NodeInLoopBody& data_in_loop_body,
PhaseIdealLoop* phase) const; PhaseIdealLoop* phase) const;
void kill(PhaseIdealLoop* phase) const; void kill(PhaseIdealLoop* phase) const;
@ -609,7 +610,7 @@ class TemplateAssertionPredicateCreator : public StackObj {
Node* create_last_value(Node* new_control, OpaqueLoopInitNode* opaque_init) const; Node* create_last_value(Node* new_control, OpaqueLoopInitNode* opaque_init) const;
IfTrueNode* create_if_node(Node* new_control, IfTrueNode* create_if_node(Node* new_control,
OpaqueTemplateAssertionPredicateNode* template_assertion_predicate_expression, OpaqueTemplateAssertionPredicateNode* template_assertion_predicate_expression,
bool does_overflow, AssertionPredicateType assertion_predicate_type); bool does_overflow, AssertionPredicateType assertion_predicate_type) const;
public: public:
TemplateAssertionPredicateCreator(CountedLoopNode* loop_head, int scale, Node* offset, Node* range, TemplateAssertionPredicateCreator(CountedLoopNode* loop_head, int scale, Node* offset, Node* range,
@ -632,19 +633,21 @@ class InitializedAssertionPredicateCreator : public StackObj {
explicit InitializedAssertionPredicateCreator(PhaseIdealLoop* phase); explicit InitializedAssertionPredicateCreator(PhaseIdealLoop* phase);
NONCOPYABLE(InitializedAssertionPredicateCreator); NONCOPYABLE(InitializedAssertionPredicateCreator);
IfTrueNode* create_from_template(IfNode* template_assertion_predicate, Node* new_control, Node* new_init, InitializedAssertionPredicate create_from_template(IfNode* template_assertion_predicate, Node* new_control,
Node* new_stride); Node* new_init, Node* new_stride) const;
IfTrueNode* create_from_template(IfNode* template_assertion_predicate, Node* new_control);
InitializedAssertionPredicate
create_from_template_and_insert_below(const TemplateAssertionPredicate& template_assertion_predicate) const;
IfTrueNode* create(Node* operand, Node* new_control, jint stride, int scale, Node* offset, Node* range, IfTrueNode* create(Node* operand, Node* new_control, jint stride, int scale, Node* offset, Node* range,
AssertionPredicateType assertion_predicate_type); AssertionPredicateType assertion_predicate_type) const;
private: private:
OpaqueInitializedAssertionPredicateNode* create_assertion_expression_from_template(IfNode* template_assertion_predicate, OpaqueInitializedAssertionPredicateNode* create_assertion_expression_from_template(IfNode* template_assertion_predicate,
Node* new_control, Node* new_init, Node* new_control, Node* new_init,
Node* new_stride); Node* new_stride) const;
IfTrueNode* create_control_nodes(Node* new_control, int if_opcode, IfTrueNode* create_control_nodes(Node* new_control, int if_opcode,
OpaqueInitializedAssertionPredicateNode* assertion_expression, OpaqueInitializedAssertionPredicateNode* assertion_expression,
AssertionPredicateType assertion_predicate_type); AssertionPredicateType assertion_predicate_type) const;
}; };
// This class iterates through all predicates of a Regular Predicate Block and applies the given visitor to each. // This class iterates through all predicates of a Regular Predicate Block and applies the given visitor to each.
@ -1040,9 +1043,11 @@ class CreateAssertionPredicatesVisitor : public PredicateVisitor {
const NodeInLoopBody& _node_in_loop_body; const NodeInLoopBody& _node_in_loop_body;
const bool _clone_template; const bool _clone_template;
IfTrueNode* clone_template_and_replace_init_input(const TemplateAssertionPredicate& template_assertion_predicate); TemplateAssertionPredicate
IfTrueNode* initialize_from_template(const TemplateAssertionPredicate& template_assertion_predicate, clone_template_and_replace_init_input(const TemplateAssertionPredicate& template_assertion_predicate) const;
Node* new_control) const;
InitializedAssertionPredicate initialize_from_template(const TemplateAssertionPredicate& template_assertion_predicate,
Node* new_control) const;
void rewire_to_old_predicate_chain_head(Node* initialized_assertion_predicate_success_proj) const; void rewire_to_old_predicate_chain_head(Node* initialized_assertion_predicate_success_proj) const;
public: public:
@ -1070,7 +1075,7 @@ public:
TargetLoopPredicateChain(LoopNode* loop_head, PhaseIdealLoop* phase); TargetLoopPredicateChain(LoopNode* loop_head, PhaseIdealLoop* phase);
NONCOPYABLE(TargetLoopPredicateChain); NONCOPYABLE(TargetLoopPredicateChain);
void insert_predicate(IfTrueNode* predicate_success_proj); void insert_predicate(const Predicate& predicate);
}; };
// This class clones Parse and Template Assertion Predicates to the provided target loop. This also involves rewiring // This class clones Parse and Template Assertion Predicates to the provided target loop. This also involves rewiring
@ -1102,17 +1107,18 @@ public:
// Clones the provided Parse Predicate to the head of the current predicate chain at the target loop. // Clones the provided Parse Predicate to the head of the current predicate chain at the target loop.
void clone_parse_predicate(const ParsePredicate& parse_predicate, bool is_true_path_loop) { void clone_parse_predicate(const ParsePredicate& parse_predicate, bool is_true_path_loop) {
ParsePredicateSuccessProj* cloned_parse_predicate_success_proj = ParsePredicate cloned_parse_predicate = parse_predicate.clone_to_unswitched_loop(_old_target_loop_entry,
parse_predicate.clone_to_unswitched_loop(_old_target_loop_entry, is_true_path_loop, _phase); is_true_path_loop, _phase);
_target_loop_predicate_chain.insert_predicate(cloned_parse_predicate_success_proj); _target_loop_predicate_chain.insert_predicate(cloned_parse_predicate);
} }
// Clones the provided Template Assertion Predicate to the head of the current predicate chain at the target loop. // Clones the provided Template Assertion Predicate to the head of the current predicate chain at the target loop.
void clone_template_assertion_predicate(const TemplateAssertionPredicate& template_assertion_predicate) { void clone_template_assertion_predicate(const TemplateAssertionPredicate& template_assertion_predicate) {
IfTrueNode* cloned_template_success_proj = template_assertion_predicate.clone(_old_target_loop_entry, TemplateAssertionPredicate cloned_template_assertion_predicate =
_phase); template_assertion_predicate.clone(_old_target_loop_entry, _phase);
template_assertion_predicate.rewire_loop_data_dependencies(cloned_template_success_proj, _node_in_loop_body, _phase); template_assertion_predicate.rewire_loop_data_dependencies(cloned_template_assertion_predicate.tail(),
_target_loop_predicate_chain.insert_predicate(cloned_template_success_proj); _node_in_loop_body, _phase);
_target_loop_predicate_chain.insert_predicate(cloned_template_assertion_predicate);
} }
}; };
@ -1164,8 +1170,10 @@ class UpdateStrideForAssertionPredicates : public PredicateVisitor {
PhaseIdealLoop* const _phase; PhaseIdealLoop* const _phase;
void replace_opaque_stride_input(const TemplateAssertionPredicate& template_assertion_predicate) const; void replace_opaque_stride_input(const TemplateAssertionPredicate& template_assertion_predicate) const;
IfTrueNode* initialize_from_updated_template(const TemplateAssertionPredicate& template_assertion_predicate) const;
void connect_initialized_assertion_predicate(Node* new_control_out, IfTrueNode* initialized_success_proj) const; InitializedAssertionPredicate
initialize_from_updated_template(const TemplateAssertionPredicate& template_assertion_predicate) const;
void connect_initialized_assertion_predicate(Node* new_control_out, const InitializedAssertionPredicate& initialized_assertion_predicate) const;
public: public:
UpdateStrideForAssertionPredicates(Node* const new_stride, PhaseIdealLoop* phase) UpdateStrideForAssertionPredicates(Node* const new_stride, PhaseIdealLoop* phase)