@@ -2041,26 +2041,28 @@ void PhaseIdealLoop::clone_loop_handle_data_uses(Node* old, Node_List &old_new,
2041
2041
}
2042
2042
}
2043
2043
2044
- static void clone_outer_loop_helper (Node* n, const IdealLoopTree *loop, const IdealLoopTree* outer_loop,
2045
- const Node_List &old_new, Unique_Node_List& wq, PhaseIdealLoop* phase,
2046
- bool check_old_new) {
2044
+ static void collect_nodes_in_outer_loop_not_reachable_from_sfpt (Node* n, const IdealLoopTree *loop, const IdealLoopTree* outer_loop,
2045
+ const Node_List &old_new, Unique_Node_List& wq, PhaseIdealLoop* phase,
2046
+ bool check_old_new) {
2047
2047
for (DUIterator_Fast jmax, j = n->fast_outs (jmax); j < jmax; j++) {
2048
2048
Node* u = n->fast_out (j);
2049
2049
assert (check_old_new || old_new[u->_idx ] == NULL , " shouldn't have been cloned" );
2050
2050
if (!u->is_CFG () && (!check_old_new || old_new[u->_idx ] == NULL )) {
2051
2051
Node* c = phase->get_ctrl (u);
2052
2052
IdealLoopTree* u_loop = phase->get_loop (c);
2053
- assert (!loop->is_member (u_loop), " can be in outer loop or out of both loops only" );
2054
- if (outer_loop->is_member (u_loop)) {
2055
- wq.push (u);
2056
- } else {
2057
- // nodes pinned with control in the outer loop but not referenced from the safepoint must be moved out of
2058
- // the outer loop too
2059
- Node* u_c = u->in (0 );
2060
- if (u_c != NULL ) {
2061
- IdealLoopTree* u_c_loop = phase->get_loop (u_c);
2062
- if (outer_loop->is_member (u_c_loop) && !loop->is_member (u_c_loop)) {
2063
- wq.push (u);
2053
+ assert (!loop->is_member (u_loop) || !loop->_body .contains (u), " can be in outer loop or out of both loops only" );
2054
+ if (!loop->is_member (u_loop)) {
2055
+ if (outer_loop->is_member (u_loop)) {
2056
+ wq.push (u);
2057
+ } else {
2058
+ // nodes pinned with control in the outer loop but not referenced from the safepoint must be moved out of
2059
+ // the outer loop too
2060
+ Node* u_c = u->in (0 );
2061
+ if (u_c != NULL ) {
2062
+ IdealLoopTree* u_c_loop = phase->get_loop (u_c);
2063
+ if (outer_loop->is_member (u_c_loop) && !loop->is_member (u_c_loop)) {
2064
+ wq.push (u);
2065
+ }
2064
2066
}
2065
2067
}
2066
2068
}
@@ -2179,12 +2181,17 @@ void PhaseIdealLoop::clone_outer_loop(LoopNode* head, CloneLoopMode mode, IdealL
2179
2181
Unique_Node_List wq;
2180
2182
for (uint i = 0 ; i < extra_data_nodes.size (); i++) {
2181
2183
Node* old = extra_data_nodes.at (i);
2182
- clone_outer_loop_helper (old, loop, outer_loop, old_new, wq, this , true );
2184
+ collect_nodes_in_outer_loop_not_reachable_from_sfpt (old, loop, outer_loop, old_new, wq, this , true );
2185
+ }
2186
+
2187
+ for (uint i = 0 ; i < loop->_body .size (); i++) {
2188
+ Node* old = loop->_body .at (i);
2189
+ collect_nodes_in_outer_loop_not_reachable_from_sfpt (old, loop, outer_loop, old_new, wq, this , true );
2183
2190
}
2184
2191
2185
2192
Node* inner_out = sfpt->in (0 );
2186
2193
if (inner_out->outcnt () > 1 ) {
2187
- clone_outer_loop_helper (inner_out, loop, outer_loop, old_new, wq, this , true );
2194
+ collect_nodes_in_outer_loop_not_reachable_from_sfpt (inner_out, loop, outer_loop, old_new, wq, this , true );
2188
2195
}
2189
2196
2190
2197
Node* new_ctrl = cl->outer_loop_exit ();
@@ -2195,7 +2202,7 @@ void PhaseIdealLoop::clone_outer_loop(LoopNode* head, CloneLoopMode mode, IdealL
2195
2202
if (n->in (0 ) != NULL ) {
2196
2203
_igvn.replace_input_of (n, 0 , new_ctrl);
2197
2204
}
2198
- clone_outer_loop_helper (n, loop, outer_loop, old_new, wq, this , false );
2205
+ collect_nodes_in_outer_loop_not_reachable_from_sfpt (n, loop, outer_loop, old_new, wq, this , false );
2199
2206
}
2200
2207
} else {
2201
2208
Node *newhead = old_new[loop->_head ->_idx ];
0 commit comments