8343745: Only update Last Value Assertion Predicates in Loop Unrolling
Reviewed-by: thartmann, kvn
This commit is contained in:
parent
b53ee053f7
commit
3727f40461
@ -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);
|
||||
|
@ -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------------------------------------------
|
||||
|
@ -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();
|
||||
|
@ -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 {
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user