src/share/vm/opto/loopPredicate.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
hotspot Cdiff src/share/vm/opto/loopPredicate.cpp
src/share/vm/opto/loopPredicate.cpp
Print this page
rev 8157 : 8078426: mb/jvm/compiler/InterfaceCalls/testAC2 - assert(predicate_proj == 0L) failed: only one predicate entry expected
Summary: split if finds predicates on several incoming paths when unswitched's loops are optimized out
Reviewed-by:
rev 9360 : 8137168: Replace IfNode with a new RangeCheckNode for range checks
Summary: new RangeCheckNode to enable optimization of explicit library level range checks
Reviewed-by:
*** 89,99 ****
//
// We will create a region to guard the uct call if there is no one there.
// The true projecttion (if_cont) of the new_iff is returned.
// This code is also used to clone predicates to cloned loops.
ProjNode* PhaseIdealLoop::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry,
! Deoptimization::DeoptReason reason) {
assert(cont_proj->is_uncommon_trap_if_pattern(reason), "must be a uct if pattern!");
IfNode* iff = cont_proj->in(0)->as_If();
ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con);
Node *rgn = uncommon_proj->unique_ctrl_out();
--- 89,100 ----
//
// We will create a region to guard the uct call if there is no one there.
// The true projecttion (if_cont) of the new_iff is returned.
// This code is also used to clone predicates to cloned loops.
ProjNode* PhaseIdealLoop::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry,
! Deoptimization::DeoptReason reason,
! int opcode) {
assert(cont_proj->is_uncommon_trap_if_pattern(reason), "must be a uct if pattern!");
IfNode* iff = cont_proj->in(0)->as_If();
ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con);
Node *rgn = uncommon_proj->unique_ctrl_out();
*** 131,142 ****
// Clonning the predicate to new location.
entry = new_entry;
}
// Create new_iff
IdealLoopTree* lp = get_loop(entry);
! IfNode *new_iff = iff->clone()->as_If();
! new_iff->set_req(0, entry);
register_control(new_iff, lp, entry);
Node *if_cont = new IfTrueNode(new_iff);
Node *if_uct = new IfFalseNode(new_iff);
if (cont_proj->is_IfFalse()) {
// Swap
--- 132,148 ----
// Clonning the predicate to new location.
entry = new_entry;
}
// Create new_iff
IdealLoopTree* lp = get_loop(entry);
! IfNode* new_iff = NULL;
! if (opcode == Op_If) {
! new_iff = new IfNode(entry, iff->in(1), iff->_prob, iff->_fcnt);
! } else {
! assert(opcode == Op_RangeCheck, "no other if variant here");
! new_iff = new RangeCheckNode(entry, iff->in(1), iff->_prob, iff->_fcnt);
! }
register_control(new_iff, lp, entry);
Node *if_cont = new IfTrueNode(new_iff);
Node *if_uct = new IfFalseNode(new_iff);
if (cont_proj->is_IfFalse()) {
// Swap
*** 181,191 ****
}
//------------------------------create_new_if_for_predicate------------------------
// Create a new if below new_entry for the predicate to be cloned (IGVN optimization)
ProjNode* PhaseIterGVN::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry,
! Deoptimization::DeoptReason reason) {
assert(new_entry != 0, "only used for clone predicate");
assert(cont_proj->is_uncommon_trap_if_pattern(reason), "must be a uct if pattern!");
IfNode* iff = cont_proj->in(0)->as_If();
ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con);
--- 187,198 ----
}
//------------------------------create_new_if_for_predicate------------------------
// Create a new if below new_entry for the predicate to be cloned (IGVN optimization)
ProjNode* PhaseIterGVN::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry,
! Deoptimization::DeoptReason reason,
! int opcode) {
assert(new_entry != 0, "only used for clone predicate");
assert(cont_proj->is_uncommon_trap_if_pattern(reason), "must be a uct if pattern!");
IfNode* iff = cont_proj->in(0)->as_If();
ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con);
*** 206,217 ****
if (rgn->in(proj_index) == uncommon_proj) break;
assert(proj_index < rgn->req(), "sanity");
}
// Create new_iff in new location.
! IfNode *new_iff = iff->clone()->as_If();
! new_iff->set_req(0, new_entry);
register_new_node_with_optimizer(new_iff);
Node *if_cont = new IfTrueNode(new_iff);
Node *if_uct = new IfFalseNode(new_iff);
if (cont_proj->is_IfFalse()) {
--- 213,229 ----
if (rgn->in(proj_index) == uncommon_proj) break;
assert(proj_index < rgn->req(), "sanity");
}
// Create new_iff in new location.
! IfNode* new_iff = NULL;
! if (opcode == Op_If) {
! new_iff = new IfNode(new_entry, iff->in(1), iff->_prob, iff->_fcnt);
! } else {
! assert(opcode == Op_RangeCheck, "no other if variant here");
! new_iff = new RangeCheckNode(new_entry, iff->in(1), iff->_prob, iff->_fcnt);
! }
register_new_node_with_optimizer(new_iff);
Node *if_cont = new IfTrueNode(new_iff);
Node *if_uct = new IfFalseNode(new_iff);
if (cont_proj->is_IfFalse()) {
*** 247,259 ****
Deoptimization::DeoptReason reason,
PhaseIdealLoop* loop_phase,
PhaseIterGVN* igvn) {
ProjNode* new_predicate_proj;
if (loop_phase != NULL) {
! new_predicate_proj = loop_phase->create_new_if_for_predicate(predicate_proj, new_entry, reason);
} else {
! new_predicate_proj = igvn->create_new_if_for_predicate(predicate_proj, new_entry, reason);
}
IfNode* iff = new_predicate_proj->in(0)->as_If();
Node* ctrl = iff->in(0);
// Match original condition since predicate's projections could be swapped.
--- 259,271 ----
Deoptimization::DeoptReason reason,
PhaseIdealLoop* loop_phase,
PhaseIterGVN* igvn) {
ProjNode* new_predicate_proj;
if (loop_phase != NULL) {
! new_predicate_proj = loop_phase->create_new_if_for_predicate(predicate_proj, new_entry, reason, Op_If);
} else {
! new_predicate_proj = igvn->create_new_if_for_predicate(predicate_proj, new_entry, reason, Op_If);
}
IfNode* iff = new_predicate_proj->in(0)->as_If();
Node* ctrl = iff->in(0);
// Match original condition since predicate's projections could be swapped.
*** 712,722 ****
Node_List if_proj_list(area);
Node *current_proj = loop->tail(); //start from tail
while (current_proj != head) {
if (loop == get_loop(current_proj) && // still in the loop ?
current_proj->is_Proj() && // is a projection ?
! current_proj->in(0)->Opcode() == Op_If) { // is a if projection ?
if_proj_list.push(current_proj);
}
current_proj = idom(current_proj);
}
--- 724,735 ----
Node_List if_proj_list(area);
Node *current_proj = loop->tail(); //start from tail
while (current_proj != head) {
if (loop == get_loop(current_proj) && // still in the loop ?
current_proj->is_Proj() && // is a projection ?
! (current_proj->in(0)->Opcode() == Op_If ||
! current_proj->in(0)->Opcode() == Op_RangeCheck)) { // is a if projection ?
if_proj_list.push(current_proj);
}
current_proj = idom(current_proj);
}
*** 751,761 ****
}
BoolNode* bol = test->as_Bool();
if (invar.is_invariant(bol)) {
// Invariant test
new_predicate_proj = create_new_if_for_predicate(predicate_proj, NULL,
! Deoptimization::Reason_predicate);
Node* ctrl = new_predicate_proj->in(0)->as_If()->in(0);
BoolNode* new_predicate_bol = invar.clone(bol, ctrl)->as_Bool();
// Negate test if necessary
bool negated = false;
--- 764,775 ----
}
BoolNode* bol = test->as_Bool();
if (invar.is_invariant(bol)) {
// Invariant test
new_predicate_proj = create_new_if_for_predicate(predicate_proj, NULL,
! Deoptimization::Reason_predicate,
! iff->Opcode());
Node* ctrl = new_predicate_proj->in(0)->as_If()->in(0);
BoolNode* new_predicate_bol = invar.clone(bol, ctrl)->as_Bool();
// Negate test if necessary
bool negated = false;
*** 795,806 ****
// Build if's for the upper and lower bound tests. The
// lower_bound test will dominate the upper bound test and all
// cloned or created nodes will use the lower bound test as
// their declared control.
! ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate);
! ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate);
assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate");
Node *ctrl = lower_bound_proj->in(0)->as_If()->in(0);
// Perform cloning to keep Invariance state correct since the
// late schedule will place invariant things in the loop.
--- 809,820 ----
// Build if's for the upper and lower bound tests. The
// lower_bound test will dominate the upper bound test and all
// cloned or created nodes will use the lower bound test as
// their declared control.
! ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate, iff->Opcode());
! ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate, iff->Opcode());
assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate");
Node *ctrl = lower_bound_proj->in(0)->as_If()->in(0);
// Perform cloning to keep Invariance state correct since the
// late schedule will place invariant things in the loop.
src/share/vm/opto/loopPredicate.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File