提交 14cecfd4 编写于 作者: K kvn

8014811: loopTransform.cpp assert(cmp_end->in(2) == limit) failed

Summary: Stop current iteration of loop opts if partial_peel() failed and it created node clones outside processed loop.
Reviewed-by: roland
上级 2b50b3d3
...@@ -965,7 +965,7 @@ public: ...@@ -965,7 +965,7 @@ public:
// Has use internal to the vector set (ie. not in a phi at the loop head) // Has use internal to the vector set (ie. not in a phi at the loop head)
bool has_use_internal_to_set( Node* n, VectorSet& vset, IdealLoopTree *loop ); bool has_use_internal_to_set( Node* n, VectorSet& vset, IdealLoopTree *loop );
// clone "n" for uses that are outside of loop // clone "n" for uses that are outside of loop
void clone_for_use_outside_loop( IdealLoopTree *loop, Node* n, Node_List& worklist ); int clone_for_use_outside_loop( IdealLoopTree *loop, Node* n, Node_List& worklist );
// clone "n" for special uses that are in the not_peeled region // clone "n" for special uses that are in the not_peeled region
void clone_for_special_use_inside_loop( IdealLoopTree *loop, Node* n, void clone_for_special_use_inside_loop( IdealLoopTree *loop, Node* n,
VectorSet& not_peel, Node_List& sink_list, Node_List& worklist ); VectorSet& not_peel, Node_List& sink_list, Node_List& worklist );
......
...@@ -1939,8 +1939,8 @@ bool PhaseIdealLoop::has_use_internal_to_set( Node* n, VectorSet& vset, IdealLoo ...@@ -1939,8 +1939,8 @@ bool PhaseIdealLoop::has_use_internal_to_set( Node* n, VectorSet& vset, IdealLoo
//------------------------------ clone_for_use_outside_loop ------------------------------------- //------------------------------ clone_for_use_outside_loop -------------------------------------
// clone "n" for uses that are outside of loop // clone "n" for uses that are outside of loop
void PhaseIdealLoop::clone_for_use_outside_loop( IdealLoopTree *loop, Node* n, Node_List& worklist ) { int PhaseIdealLoop::clone_for_use_outside_loop( IdealLoopTree *loop, Node* n, Node_List& worklist ) {
int cloned = 0;
assert(worklist.size() == 0, "should be empty"); assert(worklist.size() == 0, "should be empty");
for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) { for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
Node* use = n->fast_out(j); Node* use = n->fast_out(j);
...@@ -1960,6 +1960,7 @@ void PhaseIdealLoop::clone_for_use_outside_loop( IdealLoopTree *loop, Node* n, N ...@@ -1960,6 +1960,7 @@ void PhaseIdealLoop::clone_for_use_outside_loop( IdealLoopTree *loop, Node* n, N
// clone "n" and insert it between the inputs of "n" and the use outside the loop // clone "n" and insert it between the inputs of "n" and the use outside the loop
Node* n_clone = n->clone(); Node* n_clone = n->clone();
_igvn.replace_input_of(use, j, n_clone); _igvn.replace_input_of(use, j, n_clone);
cloned++;
Node* use_c; Node* use_c;
if (!use->is_Phi()) { if (!use->is_Phi()) {
use_c = has_ctrl(use) ? get_ctrl(use) : use->in(0); use_c = has_ctrl(use) ? get_ctrl(use) : use->in(0);
...@@ -1977,6 +1978,7 @@ void PhaseIdealLoop::clone_for_use_outside_loop( IdealLoopTree *loop, Node* n, N ...@@ -1977,6 +1978,7 @@ void PhaseIdealLoop::clone_for_use_outside_loop( IdealLoopTree *loop, Node* n, N
} }
#endif #endif
} }
return cloned;
} }
...@@ -2495,6 +2497,7 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) { ...@@ -2495,6 +2497,7 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) {
// Evacuate nodes in peel region into the not_peeled region if possible // Evacuate nodes in peel region into the not_peeled region if possible
uint new_phi_cnt = 0; uint new_phi_cnt = 0;
uint cloned_for_outside_use = 0;
for (i = 0; i < peel_list.size();) { for (i = 0; i < peel_list.size();) {
Node* n = peel_list.at(i); Node* n = peel_list.at(i);
#if !defined(PRODUCT) #if !defined(PRODUCT)
...@@ -2513,8 +2516,7 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) { ...@@ -2513,8 +2516,7 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) {
// if not pinned and not a load (which maybe anti-dependent on a store) // if not pinned and not a load (which maybe anti-dependent on a store)
// and not a CMove (Matcher expects only bool->cmove). // and not a CMove (Matcher expects only bool->cmove).
if ( n->in(0) == NULL && !n->is_Load() && !n->is_CMove() ) { if ( n->in(0) == NULL && !n->is_Load() && !n->is_CMove() ) {
clone_for_use_outside_loop( loop, n, worklist ); cloned_for_outside_use += clone_for_use_outside_loop( loop, n, worklist );
sink_list.push(n); sink_list.push(n);
peel >>= n->_idx; // delete n from peel set. peel >>= n->_idx; // delete n from peel set.
not_peel <<= n->_idx; // add n to not_peel set. not_peel <<= n->_idx; // add n to not_peel set.
...@@ -2551,6 +2553,12 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) { ...@@ -2551,6 +2553,12 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) {
// Inhibit more partial peeling on this loop // Inhibit more partial peeling on this loop
assert(!head->is_partial_peel_loop(), "not partial peeled"); assert(!head->is_partial_peel_loop(), "not partial peeled");
head->mark_partial_peel_failed(); head->mark_partial_peel_failed();
if (cloned_for_outside_use > 0) {
// Terminate this round of loop opts because
// the graph outside this loop was changed.
C->set_major_progress();
return true;
}
return false; return false;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册