< prev index next >
src/hotspot/share/opto/loopnode.cpp
Print this page
*** 34,43 ****
--- 34,44 ----
#include "opto/convertnode.hpp"
#include "opto/divnode.hpp"
#include "opto/idealGraphPrinter.hpp"
#include "opto/loopnode.hpp"
#include "opto/mulnode.hpp"
+ #include "opto/opaquenode.hpp"
#include "opto/rootnode.hpp"
#include "opto/superword.hpp"
//=============================================================================
//------------------------------is_loop_iv-------------------------------------
*** 259,270 ****
// Fixup self
set_early_ctrl( n );
}
//------------------------------is_counted_loop--------------------------------
! bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
PhaseGVN *gvn = &_igvn;
// Counted loop head must be a good RegionNode with only 3 not NULL
// control input edges: Self, Entry, LoopBack.
if (x->in(LoopNode::Self) == NULL || x->req() != 3 || loop->_irreducible) {
--- 260,338 ----
// Fixup self
set_early_ctrl( n );
}
+ // Create a skeleton strip mined outer loop: a Loop head before the
+ // inner strip mined loop, a safepoint and an exit condition guarded
+ // by an opaque node after the inner strip mined loop with a backedge
+ // to the loop head. The inner strip mined loop is left as it is. Only
+ // once loop optimizations are over, do we adjust the inner loop exit
+ // condition to limit its number of iterations, set the outer loop
+ // exit condition and add Phis to the outer loop head. Some loop
+ // optimizations that operate on the inner strip mined loop need to be
+ // aware of the outer strip mined loop: loop unswitching needs to
+ // clone the outer loop as well as the inner, unrolling needs to only
+ // clone the inner loop etc. No optimizations need to change the outer
+ // strip mined loop as it is only a skeleton.
+ IdealLoopTree* PhaseIdealLoop::create_outer_strip_mined_loop(BoolNode *test, Node *cmp, Node *init_control,
+ IdealLoopTree* loop, float cl_prob, float le_fcnt,
+ Node*& entry_control, Node*& iffalse) {
+ Node* outer_test = test->clone();
+ Node* outer_cmp = cmp->clone();
+ Node* outer_limit = new Opaque5Node(C, outer_cmp->in(2));
+ outer_cmp->set_req(2, outer_limit);
+ outer_test->set_req(1, outer_cmp);
+ Node *orig = iffalse;
+ iffalse = iffalse->clone();
+ _igvn.register_new_node_with_optimizer(iffalse);
+ set_idom(iffalse, idom(orig), dom_depth(orig));
+
+ IfNode *outer_le = new IfNode(iffalse, outer_test, cl_prob, le_fcnt);
+ Node *outer_ift = new IfTrueNode (outer_le);
+ Node* outer_iff = orig;
+ _igvn.replace_input_of(outer_iff, 0, outer_le);
+
+ LoopNode *outer_l = new LoopNode(init_control, outer_ift);
+ entry_control = outer_l;
+
+ IdealLoopTree* outer_ilt = new IdealLoopTree(this, outer_l, outer_ift);
+ IdealLoopTree* parent = loop->_parent;
+ IdealLoopTree* sibling = parent->_child;
+ if (sibling == loop) {
+ parent->_child = outer_ilt;
+ } else {
+ while (sibling->_next != loop) {
+ sibling = sibling->_next;
+ }
+ sibling->_next = outer_ilt;
+ }
+ outer_ilt->_next = loop->_next;
+ outer_ilt->_parent = parent;
+ outer_ilt->_child = loop;
+ outer_ilt->_nest = loop->_nest;
+ loop->_parent = outer_ilt;
+ loop->_next = NULL;
+ loop->_nest++;
+
+ set_loop(iffalse, outer_ilt);
+ register_new_node(outer_test, iffalse);
+ register_new_node(outer_cmp, iffalse);
+ register_new_node(outer_limit, iffalse);
+ register_control(outer_le, outer_ilt, iffalse);
+ register_control(outer_ift, outer_ilt, outer_le);
+ set_idom(outer_iff, outer_le, dom_depth(outer_le));
+ _igvn.register_new_node_with_optimizer(outer_l);
+ set_loop(outer_l, outer_ilt);
+ set_idom(outer_l, init_control, dom_depth(init_control)+1);
+ outer_l->mark_strip_mined();
+
+ return outer_ilt;
+ }
+
//------------------------------is_counted_loop--------------------------------
! bool PhaseIdealLoop::is_counted_loop(Node* x, IdealLoopTree*& loop) {
PhaseGVN *gvn = &_igvn;
// Counted loop head must be a good RegionNode with only 3 not NULL
// control input edges: Self, Entry, LoopBack.
if (x->in(LoopNode::Self) == NULL || x->req() != 3 || loop->_irreducible) {
*** 278,288 ****
if (init_control->is_top() || back_control->is_top())
return false;
// Allow funny placement of Safepoint
if (back_control->Opcode() == Op_SafePoint) {
! if (UseCountedLoopSafepoints) {
// Leaving the safepoint on the backedge and creating a
// CountedLoop will confuse optimizations. We can't move the
// safepoint around because its jvm state wouldn't match a new
// location. Give up on that loop.
return false;
--- 346,356 ----
if (init_control->is_top() || back_control->is_top())
return false;
// Allow funny placement of Safepoint
if (back_control->Opcode() == Op_SafePoint) {
! if (LoopStripMiningIter != 0) {
// Leaving the safepoint on the backedge and creating a
// CountedLoop will confuse optimizations. We can't move the
// safepoint around because its jvm state wouldn't match a new
// location. Give up on that loop.
return false;
*** 598,608 ****
else
ShouldNotReachHere();
}
set_subtree_ctrl( limit );
! if (!UseCountedLoopSafepoints) {
// Check for SafePoint on backedge and remove
Node *sfpt = x->in(LoopNode::LoopBackControl);
if (sfpt->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt)) {
lazy_replace( sfpt, iftrue );
if (loop->_safepts != NULL) {
--- 666,676 ----
else
ShouldNotReachHere();
}
set_subtree_ctrl( limit );
! if (LoopStripMiningIter == 0) {
// Check for SafePoint on backedge and remove
Node *sfpt = x->in(LoopNode::LoopBackControl);
if (sfpt->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt)) {
lazy_replace( sfpt, iftrue );
if (loop->_safepts != NULL) {
*** 681,692 ****
set_idom(iftrue, le, dd+1);
set_idom(iffalse, le, dd+1);
assert(iff->outcnt() == 0, "should be dead now");
lazy_replace( iff, le ); // fix 'get_ctrl'
// Now setup a new CountedLoopNode to replace the existing LoopNode
! CountedLoopNode *l = new CountedLoopNode(init_control, back_control);
l->set_unswitch_count(x->as_Loop()->unswitch_count()); // Preserve
// The following assert is approximately true, and defines the intention
// of can_be_counted_loop. It fails, however, because phase->type
// is not yet initialized for this loop and its parts.
//assert(l->can_be_counted_loop(this), "sanity");
--- 749,772 ----
set_idom(iftrue, le, dd+1);
set_idom(iffalse, le, dd+1);
assert(iff->outcnt() == 0, "should be dead now");
lazy_replace( iff, le ); // fix 'get_ctrl'
+ Node *sfpt2 = le->in(0);
+
+ Node* entry_control = init_control;
+ bool strip_mine_loop = LoopStripMiningIter > 1 && loop->_child == NULL &&
+ sfpt2->Opcode() == Op_SafePoint && !loop->_has_call;
+ IdealLoopTree* outer_ilt = NULL;
+ if (strip_mine_loop) {
+ outer_ilt = create_outer_strip_mined_loop(test, cmp, init_control, loop,
+ cl_prob, le->_fcnt, entry_control,
+ iffalse);
+ }
+
// Now setup a new CountedLoopNode to replace the existing LoopNode
! CountedLoopNode *l = new CountedLoopNode(entry_control, back_control);
l->set_unswitch_count(x->as_Loop()->unswitch_count()); // Preserve
// The following assert is approximately true, and defines the intention
// of can_be_counted_loop. It fails, however, because phase->type
// is not yet initialized for this loop and its parts.
//assert(l->can_be_counted_loop(this), "sanity");
*** 694,709 ****
set_loop(l, loop);
loop->_head = l;
// Fix all data nodes placed at the old loop head.
// Uses the lazy-update mechanism of 'get_ctrl'.
lazy_replace( x, l );
! set_idom(l, init_control, dom_depth(x));
! if (!UseCountedLoopSafepoints) {
// Check for immediately preceding SafePoint and remove
! Node *sfpt2 = le->in(0);
! if (sfpt2->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt2)) {
lazy_replace( sfpt2, sfpt2->in(TypeFunc::Control));
if (loop->_safepts != NULL) {
loop->_safepts->yank(sfpt2);
}
}
--- 774,799 ----
set_loop(l, loop);
loop->_head = l;
// Fix all data nodes placed at the old loop head.
// Uses the lazy-update mechanism of 'get_ctrl'.
lazy_replace( x, l );
! set_idom(l, entry_control, dom_depth(entry_control) + 1);
! if (LoopStripMiningIter == 0 || strip_mine_loop) {
// Check for immediately preceding SafePoint and remove
! if (sfpt2->Opcode() == Op_SafePoint && (LoopStripMiningIter != 0 || is_deleteable_safept(sfpt2))) {
! if (strip_mine_loop) {
! Node* outer_le = outer_ilt->_tail->in(0);
! Node* outer_limit = outer_le->in(1)->in(1)->in(2);
! assert(outer_limit->Opcode() == Op_Opaque5, "where's the opaque node?");
! Node* sfpt = sfpt2->clone();
! sfpt->set_req(0, iffalse);
! outer_le->set_req(0, sfpt);
! outer_limit->set_req(0, sfpt);
! register_control(sfpt, outer_ilt, iffalse);
! set_idom(outer_le, sfpt, dom_depth(sfpt));
! }
lazy_replace( sfpt2, sfpt2->in(TypeFunc::Control));
if (loop->_safepts != NULL) {
loop->_safepts->yank(sfpt2);
}
}
*** 728,737 ****
--- 818,834 ----
// Capture bounds of the loop in the induction variable Phi before
// subsequent transformation (iteration splitting) obscures the
// bounds
l->phi()->as_Phi()->set_type(l->phi()->Value(&_igvn));
+ if (strip_mine_loop) {
+ l->mark_strip_mined();
+ l->verify_strip_mined(1);
+ outer_ilt->_head->as_Loop()->verify_strip_mined(1);
+ loop = outer_ilt;
+ }
+
return true;
}
//----------------------exact_limit-------------------------------------------
Node* PhaseIdealLoop::exact_limit( IdealLoopTree *loop ) {
*** 774,789 ****
//------------------------------Ideal------------------------------------------
// Return a node which is more "ideal" than the current node.
// Attempt to convert into a counted-loop.
Node *LoopNode::Ideal(PhaseGVN *phase, bool can_reshape) {
! if (!can_be_counted_loop(phase)) {
phase->C->set_major_progress();
}
return RegionNode::Ideal(phase, can_reshape);
}
//=============================================================================
//------------------------------Ideal------------------------------------------
// Return a node which is more "ideal" than the current node.
// Attempt to convert into a counted-loop.
--- 871,968 ----
//------------------------------Ideal------------------------------------------
// Return a node which is more "ideal" than the current node.
// Attempt to convert into a counted-loop.
Node *LoopNode::Ideal(PhaseGVN *phase, bool can_reshape) {
! if (!can_be_counted_loop(phase) && !is_strip_mined()) {
phase->C->set_major_progress();
}
return RegionNode::Ideal(phase, can_reshape);
}
+ void LoopNode::verify_strip_mined(int expect_opaq) const {
+ #ifdef ASSERT
+ if (is_strip_mined()) {
+ const LoopNode* outer = NULL;
+ const CountedLoopNode* inner = NULL;
+ if (is_CountedLoop()) {
+ inner = as_CountedLoop();
+ outer = inner->in(LoopNode::EntryControl)->as_Loop();
+ } else {
+ outer = this;
+ inner = outer->unique_ctrl_out()->as_CountedLoop();
+ }
+ assert(outer->Opcode() == Op_Loop, "no counted loop here");
+ assert(outer->is_strip_mined(), "incorrect outer loop");
+ Node* outer_tail = outer->in(LoopNode::LoopBackControl);
+ Node* outer_le = outer_tail->in(0);
+ assert(outer_le->Opcode() == Op_If, "tail of outer loop should be an If");
+ Node* sfpt = outer_le->in(0);
+ assert(sfpt->Opcode() == Op_SafePoint, "where's the safepoint?");
+ Node* inner_out = sfpt->in(0);
+ if (inner_out->outcnt() != 1) {
+ ResourceMark rm;
+ Unique_Node_List wq;
+
+ for (DUIterator_Fast imax, i = inner_out->fast_outs(imax); i < imax; i++) {
+ Node* u = inner_out->fast_out(i);
+ if (u == sfpt) {
+ continue;
+ }
+ wq.clear();
+ wq.push(u);
+ bool found_sfpt = false;
+ for (uint next = 0; next < wq.size() && !found_sfpt; next++) {
+ Node *n = wq.at(next);
+ for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax && !found_sfpt; i++) {
+ Node* u = n->fast_out(i);
+ if (u == sfpt) {
+ found_sfpt = true;
+ }
+ if (!u->is_CFG()) {
+ wq.push(u);
+ }
+ }
+ }
+ assert(found_sfpt, "no node in loop that's not input to safepoint");
+ }
+ }
+ CountedLoopEndNode* cle = inner_out->in(0)->as_CountedLoopEnd();
+ assert(cle == inner->loopexit(), "mismatch");
+ Node* cmp = outer_le->in(1)->in(1);
+ bool has_opaque = cmp->in(2)->Opcode() == Op_Opaque5;
+ assert(cmp->in(1) == inner->incr(), "strange exit condition");
+ if (has_opaque) {
+ assert(expect_opaq == 1 || expect_opaq == -1, "unexpected opaque node");
+ assert(outer->outcnt() == 2, "only phis");
+ } else {
+ assert(expect_opaq == 0 || expect_opaq == -1, "no opaque node?");
+ uint phis = 0;
+ for (DUIterator_Fast imax, i = inner->fast_outs(imax); i < imax; i++) {
+ Node* u = inner->fast_out(i);
+ if (u->is_Phi()) {
+ phis++;
+ }
+ }
+ for (DUIterator_Fast imax, i = outer->fast_outs(imax); i < imax; i++) {
+ Node* u = outer->fast_out(i);
+ assert(u == outer || u == inner || u->is_Phi(), "nothing between inner and outer loop");
+ }
+ uint stores = 0;
+ for (DUIterator_Fast imax, i = inner_out->fast_outs(imax); i < imax; i++) {
+ Node* u = inner_out->fast_out(i);
+ if (u->is_Store()) {
+ stores++;
+ }
+ }
+ assert(outer->outcnt() >= phis + 2 && outer->outcnt() <= phis + 2 + stores + 1, "only phis");
+ }
+ assert(sfpt->outcnt() == 1 + (has_opaque ? 1 : 0), "no data node");
+ assert(outer_tail->outcnt() == 1 || !has_opaque, "no data node");
+ }
+ #endif
+ }
//=============================================================================
//------------------------------Ideal------------------------------------------
// Return a node which is more "ideal" than the current node.
// Attempt to convert into a counted-loop.
*** 988,997 ****
--- 1167,1335 ----
// failed
return NULL;
}
+ LoopNode* CountedLoopNode::skip_strip_mined(int expect_opaq) {
+ if (is_strip_mined()) {
+ verify_strip_mined(expect_opaq);
+ return in(EntryControl)->as_Loop();
+ }
+ return this;
+ }
+
+ LoopNode* CountedLoopNode::outer_loop() const {
+ assert(is_strip_mined(), "not a strip mined loop");
+ Node* c = in(EntryControl);
+ if (c == NULL || c->is_top() || c->Opcode() != Op_Loop) {
+ return NULL;
+ }
+ LoopNode* l = c->as_Loop();
+ assert(l->is_strip_mined(), "where's the outer loop?");
+ return l;
+ }
+
+ IfTrueNode* LoopNode::outer_loop_tail() const {
+ assert(is_strip_mined() && Opcode() == Op_Loop, "not a strip mined loop");
+ Node* c = in(LoopBackControl);
+ if (c == NULL || c->is_top()) {
+ return NULL;
+ }
+ return c->as_IfTrue();
+ }
+
+ IfTrueNode* CountedLoopNode::outer_loop_tail() const {
+ LoopNode* l = outer_loop();
+ if (l == NULL) {
+ return NULL;
+ }
+ return l->outer_loop_tail();
+ }
+
+ IfNode* LoopNode::outer_loop_end() const {
+ IfTrueNode* proj = outer_loop_tail();
+ if (proj == NULL) {
+ return NULL;
+ }
+ Node* c = proj->in(0);
+ if (c == NULL || c->is_top() || c->outcnt() != 2) {
+ return NULL;
+ }
+ assert(c->Opcode() == Op_If, "broken outer loop");
+ return c->as_If();
+ }
+
+ IfNode* CountedLoopNode::outer_loop_end() const {
+ LoopNode* l = outer_loop();
+ if (l == NULL) {
+ return NULL;
+ }
+ return l->outer_loop_end();
+ }
+
+ IfFalseNode* LoopNode::outer_loop_exit() const {
+ IfNode* le = outer_loop_end();
+ if (le == NULL) {
+ return NULL;
+ }
+ Node* c = le->proj_out(false);
+ if (c == NULL) {
+ return NULL;
+ }
+ return c->as_IfFalse();
+ }
+
+ IfFalseNode* CountedLoopNode::outer_loop_exit() const {
+ LoopNode* l = outer_loop();
+ if (l == NULL) {
+ return NULL;
+ }
+ return l->outer_loop_exit();
+ }
+
+ SafePointNode* LoopNode::outer_safepoint() const {
+ IfNode* le = outer_loop_end();
+ if (le == NULL) {
+ return NULL;
+ }
+ Node* c = le->in(0);
+ if (c == NULL || c->is_top()) {
+ return NULL;
+ }
+ assert(c->Opcode() == Op_SafePoint, "broken outer loop");
+ return c->as_SafePoint();
+ }
+
+ SafePointNode* CountedLoopNode::outer_safepoint() const {
+ LoopNode* l = outer_loop();
+ if (l == NULL) {
+ return NULL;
+ }
+ return l->outer_safepoint();
+ }
+
+ BoolNode* LoopNode::outer_bol() const {
+ IfNode* le = outer_loop_end();
+ if (le == NULL) {
+ return NULL;
+ }
+ Node* n = le->in(1);
+ if (n == NULL || n->is_top()) {
+ return NULL;
+ }
+ return n->as_Bool();
+ }
+
+ BoolNode* CountedLoopNode::outer_bol() const {
+ LoopNode* l = outer_loop();
+ if (l == NULL) {
+ return NULL;
+ }
+ return l->outer_bol();
+ }
+
+ CmpINode* LoopNode::outer_cmp() const {
+ Node* bol = outer_bol();
+ if (bol == NULL) {
+ return NULL;
+ }
+ Node* n = bol->in(1);
+ if (n == NULL || n->is_top()) {
+ return NULL;
+ }
+ assert(n->Opcode() == Op_CmpI, "broken strip mined loop");
+ return (CmpINode*)n;
+ }
+
+ CmpINode* CountedLoopNode::outer_cmp() const {
+ LoopNode* l = outer_loop();
+ if (l == NULL) {
+ return NULL;
+ }
+ return l->outer_cmp();
+ }
+
+ Opaque5Node* LoopNode::outer_opaq() const {
+ Node* cmp = outer_cmp();
+ if (cmp == NULL) {
+ return NULL;
+ }
+ Node* n = cmp->in(2);
+ if (n == NULL || n->is_top()) {
+ return NULL;
+ }
+ assert(n->Opcode() == Op_Opaque5, "broken strip mined loop");
+ return (Opaque5Node*)n;
+ }
+
+ Opaque5Node* CountedLoopNode::outer_opaq() const {
+ LoopNode* l = outer_loop();
+ if (l == NULL) {
+ return NULL;
+ }
+ return l->outer_opaq();
+ }
//------------------------------filtered_type--------------------------------
// Return a type based on condition control flow
// A successful return will be a type that is restricted due
// to a series of dominating if-tests, such as:
*** 1776,1789 ****
// For grins, set the inner-loop flag here
if (!_child) {
if (_head->is_Loop()) _head->as_Loop()->set_inner_loop();
}
if (_head->is_CountedLoop() ||
! phase->is_counted_loop(_head, this)) {
! if (!UseCountedLoopSafepoints) {
// Indicate we do not need a safepoint here
_has_sfpt = 1;
}
// Remove safepoints
--- 2114,2128 ----
// For grins, set the inner-loop flag here
if (!_child) {
if (_head->is_Loop()) _head->as_Loop()->set_inner_loop();
}
+ IdealLoopTree* loop = this;
if (_head->is_CountedLoop() ||
! phase->is_counted_loop(_head, loop)) {
! if (LoopStripMiningIter == 0 || (LoopStripMiningIter > 1 && _child == NULL)) {
// Indicate we do not need a safepoint here
_has_sfpt = 1;
}
// Remove safepoints
*** 1798,1820 ****
bool keep_one_sfpt = true;
remove_safepoints(phase, keep_one_sfpt);
}
// Recursively
! if (_child) _child->counted_loop( phase );
! if (_next) _next ->counted_loop( phase );
}
#ifndef PRODUCT
//------------------------------dump_head--------------------------------------
// Dump 1 liner for loop header info
void IdealLoopTree::dump_head( ) const {
for (uint i=0; i<_nest; i++)
tty->print(" ");
tty->print("Loop: N%d/N%d ",_head->_idx,_tail->_idx);
if (_irreducible) tty->print(" IRREDUCIBLE");
! Node* entry = _head->in(LoopNode::EntryControl);
Node* predicate = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
if (predicate != NULL ) {
tty->print(" limit_check");
entry = entry->in(0)->in(0);
}
--- 2137,2161 ----
bool keep_one_sfpt = true;
remove_safepoints(phase, keep_one_sfpt);
}
// Recursively
! assert(loop->_child != this || (loop->_head->as_Loop()->is_strip_mined() && _head->as_CountedLoop()->is_strip_mined()), "what kind of loop was added?");
! assert(loop->_child != this || (loop->_child->_child == NULL && loop->_child->_next == NULL), "would miss some loops");
! if (loop->_child && loop->_child != this) loop->_child->counted_loop(phase);
! if (loop->_next) loop->_next ->counted_loop(phase);
}
#ifndef PRODUCT
//------------------------------dump_head--------------------------------------
// Dump 1 liner for loop header info
void IdealLoopTree::dump_head( ) const {
for (uint i=0; i<_nest; i++)
tty->print(" ");
tty->print("Loop: N%d/N%d ",_head->_idx,_tail->_idx);
if (_irreducible) tty->print(" IRREDUCIBLE");
! Node* entry = _head->as_Loop()->skip_strip_mined(-1)->in(LoopNode::EntryControl);
Node* predicate = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
if (predicate != NULL ) {
tty->print(" limit_check");
entry = entry->in(0)->in(0);
}
*** 1861,1870 ****
--- 2202,2214 ----
tty->print(" req={"); _required_safept->dump_simple(); tty->print(" }");
}
if (Verbose) {
tty->print(" body={"); _body.dump_simple(); tty->print(" }");
}
+ if (_head->as_Loop()->is_strip_mined()) {
+ tty->print(" strip mined");
+ }
tty->cr();
}
//------------------------------dump-------------------------------------------
// Dump loops by loop tree
*** 3230,3240 ****
// be guaranteed anymore.
bool PhaseIdealLoop::is_canonical_loop_entry(CountedLoopNode* cl) {
if (!cl->is_main_loop() && !cl->is_post_loop()) {
return false;
}
! Node* ctrl = cl->in(LoopNode::EntryControl);
if (ctrl == NULL || (!ctrl->is_IfTrue() && !ctrl->is_IfFalse())) {
return false;
}
Node* iffm = ctrl->in(0);
if (iffm == NULL || !iffm->is_If()) {
--- 3574,3584 ----
// be guaranteed anymore.
bool PhaseIdealLoop::is_canonical_loop_entry(CountedLoopNode* cl) {
if (!cl->is_main_loop() && !cl->is_post_loop()) {
return false;
}
! Node* ctrl = cl->skip_strip_mined()->in(LoopNode::EntryControl);
if (ctrl == NULL || (!ctrl->is_IfTrue() && !ctrl->is_IfFalse())) {
return false;
}
Node* iffm = ctrl->in(0);
if (iffm == NULL || !iffm->is_If()) {
*** 3290,3300 ****
Node* s = mem->fast_out(i);
worklist.push(s);
}
while(worklist.size() != 0 && LCA != early) {
Node* s = worklist.pop();
! if (s->is_Load()) {
continue;
} else if (s->is_MergeMem()) {
for (DUIterator_Fast imax, i = s->fast_outs(imax); i < imax; i++) {
Node* s1 = s->fast_out(i);
worklist.push(s1);
--- 3634,3644 ----
Node* s = mem->fast_out(i);
worklist.push(s);
}
while(worklist.size() != 0 && LCA != early) {
Node* s = worklist.pop();
! if (s->is_Load() || s->Opcode() == Op_SafePoint) {
continue;
} else if (s->is_MergeMem()) {
for (DUIterator_Fast imax, i = s->fast_outs(imax); i < imax; i++) {
Node* s1 = s->fast_out(i);
worklist.push(s1);
*** 3469,3478 ****
--- 3813,3858 ----
}
}
}
}
+ // Verify that no data node is schedules in the outer loop of a strip
+ // mined loop.
+ void PhaseIdealLoop::verify_strip_mined_scheduling(Node *n, Node* least) {
+ #ifdef ASSERT
+ if (get_loop(least)->_nest == 0) {
+ return;
+ }
+ IdealLoopTree* loop = get_loop(least);
+ Node* head = loop->_head;
+ if (head->Opcode() == Op_Loop && head->as_Loop()->is_strip_mined()) {
+ if (n != head->as_Loop()->outer_bol() &&
+ n != head->as_Loop()->outer_cmp() &&
+ n != head->as_Loop()->outer_opaq()) {
+ Node* sfpt = head->as_Loop()->outer_safepoint();
+ ResourceMark rm;
+ Unique_Node_List wq;
+ wq.push(sfpt);
+ for (uint i = 0; i < wq.size(); i++) {
+ Node *m = wq.at(i);
+ for (uint i = 1; i < m->req(); i++) {
+ Node* nn = m->in(i);
+ if (nn == n) {
+ return;
+ }
+ if (nn != NULL && has_ctrl(nn) && get_loop(get_ctrl(nn)) == loop) {
+ wq.push(nn);
+ }
+ }
+ }
+ ShouldNotReachHere();
+ }
+ }
+ #endif
+ }
+
+
//------------------------------build_loop_late_post---------------------------
// Put Data nodes into some loop nest, by setting the _nodes[]->loop mapping.
// Second pass finds latest legal placement, and ideal loop placement.
void PhaseIdealLoop::build_loop_late_post( Node *n ) {
*** 3578,3589 ****
// Try not to place code on a loop entry projection
// which can inhibit range check elimination.
if (least != early) {
Node* ctrl_out = least->unique_ctrl_out();
! if (ctrl_out && ctrl_out->is_CountedLoop() &&
! least == ctrl_out->in(LoopNode::EntryControl)) {
Node* least_dom = idom(least);
if (get_loop(least_dom)->is_member(get_loop(least))) {
least = least_dom;
}
}
--- 3958,3970 ----
// Try not to place code on a loop entry projection
// 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->as_Loop()->is_strip_mined())) {
Node* least_dom = idom(least);
if (get_loop(least_dom)->is_member(get_loop(least))) {
least = least_dom;
}
}
*** 3604,3613 ****
--- 3985,3995 ----
}
#endif
// Assign discovered "here or above" point
least = find_non_split_ctrl(least);
+ verify_strip_mined_scheduling(n, least);
set_ctrl(n, least);
// Collect inner loop bodies
IdealLoopTree *chosen_loop = get_loop(least);
if( !chosen_loop->_child ) // Inner loop?
< prev index next >