--- a/src/hotspot/share/opto/loopnode.cpp Tue Jun 19 08:44:31 2018 +0200
+++ b/src/hotspot/share/opto/loopnode.cpp Tue Jun 19 09:08:39 2018 +0200
@@ -1281,9 +1281,7 @@
return l->outer_safepoint();
}
-Node* CountedLoopNode::skip_predicates() {
- if (is_main_loop()) {
- Node* ctrl = skip_strip_mined()->in(LoopNode::EntryControl);
+Node* CountedLoopNode::skip_predicates_from_entry(Node* ctrl) {
while (ctrl != NULL && ctrl->is_Proj() && ctrl->in(0)->is_If() &&
ctrl->in(0)->as_If()->proj_out(1-ctrl->as_Proj()->_con)->outcnt() == 1 &&
ctrl->in(0)->as_If()->proj_out(1-ctrl->as_Proj()->_con)->unique_out()->Opcode() == Op_Halt) {
@@ -1292,6 +1290,13 @@
return ctrl;
}
+
+Node* CountedLoopNode::skip_predicates() {
+ if (is_main_loop()) {
+ Node* ctrl = skip_strip_mined()->in(LoopNode::EntryControl);
+
+ return skip_predicates_from_entry(ctrl);
+ }
return in(LoopNode::EntryControl);
}
@@ -2400,6 +2405,13 @@
entry = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
if (entry != NULL) {
tty->print(" predicated");
+ entry = PhaseIdealLoop::skip_loop_predicates(entry);
+ }
+ }
+ if (UseProfiledLoopPredicate) {
+ entry = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_profile_predicate);
+ if (entry != NULL) {
+ tty->print(" profile_predicated");
}
}
if (_head->is_CountedLoop()) {
@@ -2507,11 +2519,18 @@
if (predicate_proj != NULL ) { // right pattern that can be used by loop predication
assert(entry->in(0)->in(1)->in(1)->Opcode() == Op_Opaque1, "must be");
useful_predicates.push(entry->in(0)->in(1)->in(1)); // good one
- entry = entry->in(0)->in(0);
+ entry = skip_loop_predicates(entry);
}
predicate_proj = find_predicate(entry); // Predicate
if (predicate_proj != NULL ) {
useful_predicates.push(entry->in(0)->in(1)->in(1)); // good one
+ entry = skip_loop_predicates(entry);
+ }
+ if (UseProfiledLoopPredicate) {
+ predicate_proj = find_predicate(entry); // Predicate
+ if (predicate_proj != NULL ) {
+ useful_predicates.push(entry->in(0)->in(1)->in(1)); // good one
+ }
}
}
@@ -4205,12 +4224,33 @@
// which can inhibit range check elimination.
if (least != early) {
Node* ctrl_out = least->unique_ctrl_out();
- if (ctrl_out && ctrl_out->is_Loop() &&
- least == ctrl_out->in(LoopNode::EntryControl) &&
- (ctrl_out->is_CountedLoop() || ctrl_out->is_OuterStripMinedLoop())) {
- Node* least_dom = idom(least);
- if (get_loop(least_dom)->is_member(get_loop(least))) {
- least = least_dom;
+ if (ctrl_out && ctrl_out->is_CountedLoop() &&
+ least == ctrl_out->in(LoopNode::EntryControl)) {
+ Node* new_ctrl = least;
+ // Move the node above predicates so a following pass of loop
+ // predication doesn't hoist a predicate that depends on it
+ // above that node.
+ if (find_predicate_insertion_point(new_ctrl, Deoptimization::Reason_loop_limit_check) != NULL) {
+ new_ctrl = new_ctrl->in(0)->in(0);
+ assert(is_dominator(early, new_ctrl), "least != early so we can move up the dominator tree");
+ }
+ if (find_predicate_insertion_point(new_ctrl, Deoptimization::Reason_profile_predicate) != NULL) {
+ Node* c = new_ctrl->in(0)->in(0);
+ assert(is_dominator(early, c), "least != early so we can move up the dominator tree");
+ new_ctrl = c;
+ }
+ if (find_predicate_insertion_point(new_ctrl, Deoptimization::Reason_predicate) != NULL) {
+ Node* c = new_ctrl->in(0)->in(0);
+ assert(is_dominator(early, c), "least != early so we can move up the dominator tree");
+ new_ctrl = c;
+ }
+ if (new_ctrl != ctrl_out) {
+ least = new_ctrl;
+ } else if (ctrl_out->is_CountedLoop() || ctrl_out->is_OuterStripMinedLoop()) {
+ Node* least_dom = idom(least);
+ if (get_loop(least_dom)->is_member(get_loop(least))) {
+ least = least_dom;
+ }
}
}
}