8343745: Only update Last Value Assertion Predicates in Loop Unrolling

Reviewed-by: thartmann, kvn
This commit is contained in:
Christian Hagedorn 2024-11-12 10:11:55 +00:00
parent b53ee053f7
commit 3727f40461
7 changed files with 88 additions and 85 deletions

View File

@ -324,7 +324,7 @@ class IfNode : public MultiBranchNode {
float _fcnt; // Frequency counter
private:
NOT_PRODUCT(AssertionPredicateType _assertion_predicate_type;)
AssertionPredicateType _assertion_predicate_type;
void init_node(Node* control, Node* bol) {
init_class_id(Class_If);
@ -426,7 +426,7 @@ public:
// gen_subtype_check() and catch_inline_exceptions().
IfNode(Node* control, Node* bol, float p, float fcnt);
NOT_PRODUCT(IfNode(Node* control, Node* bol, float p, float fcnt, AssertionPredicateType assertion_predicate_type);)
IfNode(Node* control, Node* bol, float p, float fcnt, AssertionPredicateType assertion_predicate_type);
static IfNode* make_with_same_profile(IfNode* if_node_profile, Node* ctrl, BoolNode* bol);
@ -448,11 +448,11 @@ public:
// Returns null is it couldn't improve the type.
static const TypeInt* filtered_int_type(PhaseGVN* phase, Node* val, Node* if_proj);
#ifndef PRODUCT
AssertionPredicateType assertion_predicate_type() const {
return _assertion_predicate_type;
}
#ifndef PRODUCT
virtual void dump_spec(outputStream *st) const;
#endif
@ -468,12 +468,10 @@ public:
init_class_id(Class_RangeCheck);
}
#ifndef PRODUCT
RangeCheckNode(Node* control, Node* bol, float p, float fcnt, AssertionPredicateType assertion_predicate_type)
: IfNode(control, bol, p, fcnt, assertion_predicate_type) {
init_class_id(Class_RangeCheck);
}
#endif // NOT PRODUCT
virtual int Opcode() const;
virtual Node* Ideal(PhaseGVN *phase, bool can_reshape);

View File

@ -50,12 +50,11 @@ extern uint explicit_null_checks_elided;
IfNode::IfNode(Node* control, Node* bol, float p, float fcnt)
: MultiBranchNode(2),
_prob(p),
_fcnt(fcnt)
NOT_PRODUCT(COMMA _assertion_predicate_type(AssertionPredicateType::None)) {
_fcnt(fcnt),
_assertion_predicate_type(AssertionPredicateType::None) {
init_node(control, bol);
}
#ifndef PRODUCT
IfNode::IfNode(Node* control, Node* bol, float p, float fcnt, AssertionPredicateType assertion_predicate_type)
: MultiBranchNode(2),
_prob(p),
@ -63,7 +62,6 @@ IfNode::IfNode(Node* control, Node* bol, float p, float fcnt, AssertionPredicate
_assertion_predicate_type(assertion_predicate_type) {
init_node(control, bol);
}
#endif // NOT_PRODUCT
//=============================================================================
//------------------------------Value------------------------------------------

View File

@ -100,8 +100,8 @@ void PhaseIdealLoop::register_control(Node* n, IdealLoopTree *loop, Node* pred,
// is an IfTrue projection. This code is also used to clone predicates to cloned loops.
IfTrueNode* PhaseIdealLoop::create_new_if_for_predicate(ParsePredicateSuccessProj* parse_predicate_success_proj,
Node* new_entry, const Deoptimization::DeoptReason reason,
const int opcode, const bool rewire_uncommon_proj_phi_inputs
NOT_PRODUCT (COMMA AssertionPredicateType assertion_predicate_type)) {
const int opcode, const bool rewire_uncommon_proj_phi_inputs,
AssertionPredicateType assertion_predicate_type) {
assert(parse_predicate_success_proj->is_uncommon_trap_if_pattern(reason), "must be a uct if pattern!");
ParsePredicateNode* parse_predicate = parse_predicate_success_proj->in(0)->as_ParsePredicate();
ParsePredicateUncommonProj* uncommon_proj = parse_predicate->uncommon_proj();

View File

@ -2759,8 +2759,8 @@ void PhaseIdealLoop::do_range_check(IdealLoopTree *loop, Node_List &old_new) {
// cannot remove an empty loop with a constant limit when init is not a constant as well. We will use
// a LoopLimitCheck node that can only be folded if the zero grip guard is also foldable.
loop_entry = initialized_assertion_predicate_creator.create(final_iv_placeholder, loop_entry, stride_con,
scale_con, int_offset, int_limit NOT_PRODUCT(
COMMA AssertionPredicateType::FinalIv));
scale_con, int_offset, int_limit,
AssertionPredicateType::FinalIv);
assert(!assertion_predicate_has_loop_opaque_node(loop_entry->in(0)->as_If()), "unexpected");
}
@ -2773,8 +2773,8 @@ void PhaseIdealLoop::do_range_check(IdealLoopTree *loop, Node_List &old_new) {
// Initialized Assertion Predicate for the value of the initial main-loop.
loop_entry = initialized_assertion_predicate_creator.create(init, loop_entry, stride_con, scale_con,
int_offset, int_limit NOT_PRODUCT(COMMA
AssertionPredicateType::InitValue));
int_offset, int_limit,
AssertionPredicateType::InitValue);
assert(!assertion_predicate_has_loop_opaque_node(loop_entry->in(0)->as_If()), "unexpected");
} else {

View File

@ -1352,8 +1352,8 @@ public:
// Create a new if above the uncommon_trap_if_pattern for the predicate to be promoted
IfTrueNode* create_new_if_for_predicate(
ParsePredicateSuccessProj* parse_predicate_proj, Node* new_entry, Deoptimization::DeoptReason reason, int opcode,
bool rewire_uncommon_proj_phi_inputs = false
NOT_PRODUCT (COMMA AssertionPredicateType assertion_predicate_type = AssertionPredicateType::None));
bool rewire_uncommon_proj_phi_inputs = false,
AssertionPredicateType assertion_predicate_type = AssertionPredicateType::None);
private:
// Helper functions for create_new_if_for_predicate()

View File

@ -171,8 +171,8 @@ IfTrueNode* TemplateAssertionPredicate::clone_and_replace_init(Node* new_control
template_assertion_expression.clone_and_replace_init(new_opaque_init, new_control, phase);
AssertionPredicateIfCreator assertion_predicate_if_creator(phase);
IfTrueNode* success_proj = assertion_predicate_if_creator.create_for_template(new_control, _if_node->Opcode(),
new_opaque_node NOT_PRODUCT(COMMA
_if_node->assertion_predicate_type()));
new_opaque_node,
_if_node->assertion_predicate_type());
assert(PhaseIdealLoop::assertion_predicate_has_loop_opaque_node(success_proj->in(0)->as_If()),
"Template Assertion Predicates must have OpaqueLoop* nodes in the bool expression");
return success_proj;
@ -546,19 +546,19 @@ class AssertionPredicateExpressionCreator : public StackObj {
// Creates an If with a success and a fail path with the given assertion_expression. The only difference to
// create_for_initialized() is that we use a template specific Halt message on the fail path.
IfTrueNode* AssertionPredicateIfCreator::create_for_template(Node* new_control, const int if_opcode,
Node* assertion_expression NOT_PRODUCT(COMMA
const AssertionPredicateType assertion_predicate_type)) {
Node* assertion_expression,
const AssertionPredicateType assertion_predicate_type) {
const char* halt_message = "Template Assertion Predicates are always removed before code generation";
return create(new_control, if_opcode, assertion_expression, halt_message NOT_PRODUCT(COMMA assertion_predicate_type));
return create(new_control, if_opcode, assertion_expression, halt_message, assertion_predicate_type);
}
// Creates an If with a success and a fail path with the given assertion_expression. The only difference to
// create_for_template() is that we use a initialized specific Halt message on the fail path.
IfTrueNode* AssertionPredicateIfCreator::create_for_initialized(Node* new_control, const int if_opcode,
Node* assertion_expression NOT_PRODUCT(COMMA
const AssertionPredicateType assertion_predicate_type)) {
Node* assertion_expression,
const AssertionPredicateType assertion_predicate_type) {
const char* halt_message = "Initialized Assertion Predicate cannot fail";
return create(new_control, if_opcode, assertion_expression, halt_message NOT_PRODUCT(COMMA assertion_predicate_type));
return create(new_control, if_opcode, assertion_expression, halt_message, assertion_predicate_type);
}
// Creates the If node for an Assertion Predicate with a success path and a fail path having a Halt node:
@ -571,28 +571,25 @@ IfTrueNode* AssertionPredicateIfCreator::create_for_initialized(Node* new_contro
// proj with Halt
//
IfTrueNode* AssertionPredicateIfCreator::create(Node* new_control, const int if_opcode, Node* assertion_expression,
const char* halt_message NOT_PRODUCT(COMMA
const AssertionPredicateType assertion_predicate_type)) {
const char* halt_message,
const AssertionPredicateType assertion_predicate_type) {
assert(assertion_expression->is_OpaqueTemplateAssertionPredicate() ||
assertion_expression->is_OpaqueInitializedAssertionPredicate(), "not a valid assertion expression");
IdealLoopTree* loop = _phase->get_loop(new_control);
IfNode* if_node = create_if_node(new_control, if_opcode, assertion_expression, loop
NOT_PRODUCT(COMMA assertion_predicate_type));
IfNode* if_node = create_if_node(new_control, if_opcode, assertion_expression, loop, assertion_predicate_type);
create_fail_path(if_node, loop, halt_message);
return create_success_path(if_node, loop);
}
IfNode* AssertionPredicateIfCreator::create_if_node(Node* new_control, const int if_opcode, Node* assertion_expression,
IdealLoopTree* loop NOT_PRODUCT(COMMA
const AssertionPredicateType assertion_predicate_type)) {
IdealLoopTree* loop,
const AssertionPredicateType assertion_predicate_type) {
IfNode* if_node;
if (if_opcode == Op_If) {
if_node = new IfNode(new_control, assertion_expression, PROB_MAX, COUNT_UNKNOWN
NOT_PRODUCT(COMMA assertion_predicate_type));
if_node = new IfNode(new_control, assertion_expression, PROB_MAX, COUNT_UNKNOWN, assertion_predicate_type);
} else {
assert(if_opcode == Op_RangeCheck, "must be range check");
if_node = new RangeCheckNode(new_control, assertion_expression, PROB_MAX, COUNT_UNKNOWN
NOT_PRODUCT(COMMA assertion_predicate_type));
if_node = new RangeCheckNode(new_control, assertion_expression, PROB_MAX, COUNT_UNKNOWN, assertion_predicate_type);
}
_phase->register_control(if_node, loop, new_control);
return if_node;
@ -631,13 +628,13 @@ IfTrueNode* TemplateAssertionPredicateCreator::create_with_uncommon_trap(
create_for_init_value(new_control, opaque_init, does_overflow);
IfTrueNode* template_predicate_success_proj =
create_if_node_with_uncommon_trap(template_assertion_predicate_expression, parse_predicate_success_proj,
deopt_reason, if_opcode, does_overflow
NOT_PRODUCT(COMMA AssertionPredicateType::InitValue));
deopt_reason, if_opcode, does_overflow,
AssertionPredicateType::InitValue);
template_assertion_predicate_expression = create_for_last_value(template_predicate_success_proj, opaque_init,
does_overflow);
return create_if_node_with_uncommon_trap(template_assertion_predicate_expression, parse_predicate_success_proj,
deopt_reason, if_opcode, does_overflow
NOT_PRODUCT(COMMA AssertionPredicateType::LastValue));
deopt_reason, if_opcode, does_overflow,
AssertionPredicateType::LastValue);
}
OpaqueLoopInitNode* TemplateAssertionPredicateCreator::create_opaque_init(Node* new_control) {
@ -656,11 +653,10 @@ TemplateAssertionPredicateCreator::create_for_init_value(Node* new_control, Opaq
IfTrueNode* TemplateAssertionPredicateCreator::create_if_node_with_uncommon_trap(
OpaqueTemplateAssertionPredicateNode* template_assertion_predicate_expression,
ParsePredicateSuccessProj* parse_predicate_success_proj, const Deoptimization::DeoptReason deopt_reason,
const int if_opcode, const bool does_overflow
NOT_PRODUCT(COMMA AssertionPredicateType assertion_predicate_type)) {
const int if_opcode, const bool does_overflow, const AssertionPredicateType assertion_predicate_type) {
IfTrueNode* success_proj = _phase->create_new_if_for_predicate(parse_predicate_success_proj, nullptr, deopt_reason,
does_overflow ? Op_If : if_opcode, false
NOT_PRODUCT(COMMA assertion_predicate_type));
does_overflow ? Op_If : if_opcode, false,
assertion_predicate_type);
_phase->igvn().replace_input_of(success_proj->in(0), 1, template_assertion_predicate_expression);
return success_proj;
}
@ -688,12 +684,12 @@ Node* TemplateAssertionPredicateCreator::create_last_value(Node* new_control, Op
}
IfTrueNode* TemplateAssertionPredicateCreator::create_if_node_with_halt(
Node* new_control, OpaqueTemplateAssertionPredicateNode* template_assertion_predicate_expression, bool does_overflow
NOT_PRODUCT(COMMA AssertionPredicateType assertion_predicate_type)) {
Node* new_control, OpaqueTemplateAssertionPredicateNode* template_assertion_predicate_expression,
const bool does_overflow, const AssertionPredicateType assertion_predicate_type) {
AssertionPredicateIfCreator assertion_predicate_if_creator(_phase);
return assertion_predicate_if_creator.create_for_template(new_control, does_overflow ? Op_If : Op_RangeCheck,
template_assertion_predicate_expression
NOT_PRODUCT(COMMA assertion_predicate_type));
template_assertion_predicate_expression,
assertion_predicate_type);
}
// Creates an init and last value Template Assertion Predicate connected together with a Halt node on the failing path.
@ -704,12 +700,12 @@ IfTrueNode* TemplateAssertionPredicateCreator::create_with_halt(Node* new_contro
OpaqueTemplateAssertionPredicateNode* template_assertion_predicate_expression =
create_for_init_value(new_control, opaque_init, does_overflow);
IfTrueNode* template_predicate_success_proj =
create_if_node_with_halt(new_control, template_assertion_predicate_expression, does_overflow
NOT_PRODUCT(COMMA AssertionPredicateType::InitValue));
create_if_node_with_halt(new_control, template_assertion_predicate_expression, does_overflow,
AssertionPredicateType::InitValue);
template_assertion_predicate_expression = create_for_last_value(template_predicate_success_proj, opaque_init,
does_overflow);
return create_if_node_with_halt(template_predicate_success_proj, template_assertion_predicate_expression,
does_overflow NOT_PRODUCT(COMMA AssertionPredicateType::LastValue));
does_overflow, AssertionPredicateType::LastValue);
}
InitializedAssertionPredicateCreator::InitializedAssertionPredicateCreator(PhaseIdealLoop* phase)
@ -740,8 +736,8 @@ IfTrueNode* InitializedAssertionPredicateCreator::create_from_template(IfNode* t
Node* new_stride) {
OpaqueInitializedAssertionPredicateNode* assertion_expression =
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
NOT_PRODUCT(COMMA template_assertion_predicate->assertion_predicate_type()));
return create_control_nodes(new_control, template_assertion_predicate->Opcode(), assertion_expression,
template_assertion_predicate->assertion_predicate_type());
}
// Create a new Initialized Assertion Predicate from 'template_assertion_predicate' by cloning it but omitting the
@ -753,29 +749,29 @@ IfTrueNode* InitializedAssertionPredicateCreator::create_from_template(IfNode* t
TemplateAssertionExpression template_assertion_expression(template_opaque);
OpaqueInitializedAssertionPredicateNode* assertion_expression =
template_assertion_expression.clone_and_fold_opaque_loop_nodes(new_control, _phase);
return create_control_nodes(new_control, template_assertion_predicate->Opcode(), assertion_expression
NOT_PRODUCT(COMMA template_assertion_predicate->assertion_predicate_type()));
return create_control_nodes(new_control, template_assertion_predicate->Opcode(), assertion_expression,
template_assertion_predicate->assertion_predicate_type());
}
// Create a new Initialized Assertion Predicate directly without a template.
IfTrueNode* InitializedAssertionPredicateCreator::create(Node* operand, Node* new_control, const jint stride,
const int scale, Node* offset, Node* range NOT_PRODUCT(COMMA
AssertionPredicateType assertion_predicate_type)) {
const int scale, Node* offset, Node* range,
const AssertionPredicateType assertion_predicate_type) {
AssertionPredicateExpressionCreator expression_creator(stride, scale, offset, range, _phase);
bool does_overflow;
OpaqueInitializedAssertionPredicateNode* assertion_expression =
expression_creator.create_for_initialized(new_control, operand, does_overflow);
return create_control_nodes(new_control, does_overflow ? Op_If : Op_RangeCheck, assertion_expression
NOT_PRODUCT(COMMA assertion_predicate_type));
return create_control_nodes(new_control, does_overflow ? Op_If : Op_RangeCheck, assertion_expression,
assertion_predicate_type);
}
// Creates the CFG nodes for the Initialized Assertion Predicate.
IfTrueNode* InitializedAssertionPredicateCreator::create_control_nodes(
Node* new_control, const int if_opcode, OpaqueInitializedAssertionPredicateNode* assertion_expression
NOT_PRODUCT(COMMA AssertionPredicateType assertion_predicate_type)) {
Node* new_control, const int if_opcode, OpaqueInitializedAssertionPredicateNode* assertion_expression,
const AssertionPredicateType assertion_predicate_type) {
AssertionPredicateIfCreator assertion_predicate_if_creator(_phase);
return assertion_predicate_if_creator.create_for_initialized(new_control, if_opcode, assertion_expression
NOT_PRODUCT(COMMA assertion_predicate_type));
return assertion_predicate_if_creator.create_for_initialized(new_control, if_opcode, assertion_expression,
assertion_predicate_type);
}
// Create a new Assertion Expression based from the given template to be used as bool input for the Initialized
@ -879,6 +875,10 @@ IfTrueNode* CreateAssertionPredicatesVisitor::clone_template_and_replace_init_in
// Clone the Template Assertion Predicate and set a new input for the OpaqueLoopStrideNode.
void UpdateStrideForAssertionPredicates::visit(const TemplateAssertionPredicate& template_assertion_predicate) {
if (!template_assertion_predicate.is_last_value()) {
// Only Last Value Assertion Predicates have an OpaqueLoopStrideNode.
return;
}
replace_opaque_stride_input(template_assertion_predicate);
Node* template_tail_control_out = template_assertion_predicate.tail()->unique_ctrl_out();
IfTrueNode* initialized_success_proj = initialize_from_updated_template(template_assertion_predicate);

View File

@ -201,7 +201,6 @@ class TemplateAssertionPredicate;
* Main Loop Head
*/
#ifndef PRODUCT
// Assertion Predicates are either emitted to check the initial value of a range check in the first iteration or the last
// value of a range check in the last iteration of a loop.
enum class AssertionPredicateType {
@ -211,7 +210,6 @@ enum class AssertionPredicateType {
// Used for the Initialized Assertion Predicate emitted during Range Check Elimination for the final IV value.
FinalIv
};
#endif // NOT PRODUCT
// Interface to represent a C2 predicate. A predicate is always represented by two CFG nodes:
// - An If node (head)
@ -377,8 +375,8 @@ class RuntimePredicate : public Predicate {
// Class to represent a Template Assertion Predicate.
class TemplateAssertionPredicate : public Predicate {
IfTrueNode* _success_proj;
IfNode* _if_node;
IfTrueNode* const _success_proj;
IfNode* const _if_node;
public:
explicit TemplateAssertionPredicate(IfTrueNode* success_proj)
@ -403,6 +401,10 @@ class TemplateAssertionPredicate : public Predicate {
return _success_proj;
}
bool is_last_value() const {
return _if_node->assertion_predicate_type() == AssertionPredicateType::LastValue;
}
IfTrueNode* clone_and_replace_init(Node* new_control, OpaqueLoopInitNode* new_opaque_init, PhaseIdealLoop* phase) const;
void replace_opaque_stride_input(Node* new_stride, PhaseIterGVN& igvn) const;
IfTrueNode* initialize(PhaseIdealLoop* phase, Node* new_control) const;
@ -414,8 +416,8 @@ class TemplateAssertionPredicate : public Predicate {
// Class to represent an Initialized Assertion Predicate which always has a halt node on the failing path.
// This predicate should never fail at runtime by design.
class InitializedAssertionPredicate : public Predicate {
IfTrueNode* _success_proj;
IfNode* _if_node;
IfTrueNode* const _success_proj;
IfNode* const _if_node;
public:
explicit InitializedAssertionPredicate(IfTrueNode* success_proj)
@ -436,6 +438,10 @@ class InitializedAssertionPredicate : public Predicate {
return _success_proj;
}
bool is_last_value() const {
return _if_node->assertion_predicate_type() == AssertionPredicateType::LastValue;
}
void kill(PhaseIdealLoop* phase) const;
static bool is_predicate(Node* node);
};
@ -550,15 +556,15 @@ class AssertionPredicateIfCreator : public StackObj {
explicit AssertionPredicateIfCreator(PhaseIdealLoop* const phase) : _phase(phase) {}
NONCOPYABLE(AssertionPredicateIfCreator);
IfTrueNode* create_for_initialized(Node* new_control, int if_opcode, Node* assertion_expression
NOT_PRODUCT(COMMA const AssertionPredicateType assertion_predicate_type));
IfTrueNode* create_for_template(Node* new_control, int if_opcode, Node* assertion_expression
NOT_PRODUCT(COMMA const AssertionPredicateType assertion_predicate_type));
IfTrueNode* create_for_initialized(Node* new_control, int if_opcode, Node* assertion_expression,
AssertionPredicateType assertion_predicate_type);
IfTrueNode* create_for_template(Node* new_control, int if_opcode, Node* assertion_expression,
AssertionPredicateType assertion_predicate_type);
private:
IfTrueNode* create(Node* new_control, int if_opcode, Node* assertion_expression, const char* halt_message
NOT_PRODUCT(COMMA const AssertionPredicateType assertion_predicate_type));
IfNode* create_if_node(Node* new_control, int if_opcode, Node* assertion_expression, IdealLoopTree* loop
NOT_PRODUCT(COMMA const AssertionPredicateType assertion_predicate_type));
IfTrueNode* create(Node* new_control, int if_opcode, Node* assertion_expression, const char* halt_message,
AssertionPredicateType assertion_predicate_type);
IfNode* create_if_node(Node* new_control, int if_opcode, Node* assertion_expression, IdealLoopTree* loop,
AssertionPredicateType assertion_predicate_type);
IfTrueNode* create_success_path(IfNode* if_node, IdealLoopTree* loop);
void create_fail_path(IfNode* if_node, IdealLoopTree* loop, const char* halt_message);
void create_halt_node(IfFalseNode* fail_proj, IdealLoopTree* loop, const char* halt_message);
@ -581,12 +587,10 @@ class TemplateAssertionPredicateCreator : public StackObj {
IfTrueNode* create_if_node_with_uncommon_trap(OpaqueTemplateAssertionPredicateNode* template_assertion_predicate_expression,
ParsePredicateSuccessProj* parse_predicate_success_proj,
Deoptimization::DeoptReason deopt_reason, int if_opcode,
bool does_overflow
NOT_PRODUCT(COMMA AssertionPredicateType assertion_predicate_type));
bool does_overflow, AssertionPredicateType assertion_predicate_type);
IfTrueNode* create_if_node_with_halt(Node* new_control,
OpaqueTemplateAssertionPredicateNode* template_assertion_predicate_expression,
bool does_overflow
NOT_PRODUCT(COMMA AssertionPredicateType assertion_predicate_type));
bool does_overflow, AssertionPredicateType assertion_predicate_type);
public:
TemplateAssertionPredicateCreator(CountedLoopNode* loop_head, int scale, Node* offset, Node* range,
@ -614,16 +618,16 @@ class InitializedAssertionPredicateCreator : public StackObj {
IfTrueNode* create_from_template(IfNode* template_assertion_predicate, Node* new_control, Node* new_init,
Node* new_stride);
IfTrueNode* create_from_template(IfNode* template_assertion_predicate, Node* new_control);
IfTrueNode* create(Node* operand, Node* new_control, jint stride, int scale, Node* offset, Node* range
NOT_PRODUCT(COMMA AssertionPredicateType assertion_predicate_type));
IfTrueNode* create(Node* operand, Node* new_control, jint stride, int scale, Node* offset, Node* range,
AssertionPredicateType assertion_predicate_type);
private:
OpaqueInitializedAssertionPredicateNode* create_assertion_expression_from_template(IfNode* template_assertion_predicate,
Node* new_control, Node* new_init,
Node* new_stride);
IfTrueNode* create_control_nodes(Node* new_control, int if_opcode,
OpaqueInitializedAssertionPredicateNode* assertion_expression
NOT_PRODUCT(COMMA AssertionPredicateType assertion_predicate_type));
OpaqueInitializedAssertionPredicateNode* assertion_expression,
AssertionPredicateType assertion_predicate_type);
};
// This class iterates through all predicates of a Regular Predicate Block and applies the given visitor to each.
@ -1063,7 +1067,10 @@ class UpdateStrideForAssertionPredicates : public PredicateVisitor {
// Predicates are inserted after the Template Assertion Predicate which ensures that we are not accidentally visiting
// and killing a newly created Initialized Assertion Predicate here.
void visit(const InitializedAssertionPredicate& initialized_assertion_predicate) override {
initialized_assertion_predicate.kill(_phase);
if (initialized_assertion_predicate.is_last_value()) {
// Only Last Value Initialized Assertion Predicates need to be killed and updated.
initialized_assertion_predicate.kill(_phase);
}
}
};
#endif // SHARE_OPTO_PREDICATES_HPP