@@ -210,7 +210,7 @@ ProjNode* PhaseIdealLoop::create_new_if_for_predicate(ProjNode* cont_proj, Node*
210
210
}
211
211
212
212
// --------------------------clone_predicate-----------------------
213
- ProjNode* PhaseIdealLoop::clone_loop_predicate (ProjNode* predicate_proj, Node* new_entry, Deoptimization::DeoptReason reason,
213
+ ProjNode* PhaseIdealLoop::clone_predicate_to_unswitched_loop (ProjNode* predicate_proj, Node* new_entry, Deoptimization::DeoptReason reason,
214
214
bool is_slow_loop, uint idx_before_clone, Node_List &old_new) {
215
215
ProjNode* new_predicate_proj = create_new_if_for_predicate (predicate_proj, new_entry, reason, Op_If);
216
216
IfNode* iff = new_predicate_proj->in (0 )->as_If ();
@@ -225,13 +225,14 @@ ProjNode* PhaseIdealLoop::clone_loop_predicate(ProjNode* predicate_proj, Node* n
225
225
register_new_node (bol, ctrl);
226
226
_igvn.hash_delete (iff);
227
227
iff->set_req (1 , bol);
228
- clone_concrete_loop_predicates (reason, predicate_proj, new_predicate_proj, is_slow_loop, idx_before_clone, old_new);
228
+ clone_skeleton_predicates_to_unswitched_loop (reason, predicate_proj, new_predicate_proj, is_slow_loop, idx_before_clone, old_new);
229
229
return new_predicate_proj;
230
230
}
231
231
232
- // Clones all non-empty loop predicates (including skeleton predicates) starting at 'old_predicate_proj' to 'new_predicate_proj'
233
- // and rewires the control edges of data nodes in the loop to the old predicates to the new cloned predicates.
234
- void PhaseIdealLoop::clone_concrete_loop_predicates (Deoptimization::DeoptReason reason, ProjNode* old_predicate_proj,
232
+ // Clones skeleton predicates starting at 'old_predicate_proj' to
233
+ // 'new_predicate_proj' and rewires the control edges of data nodes in
234
+ // the loop from the old predicates to the new cloned predicates.
235
+ void PhaseIdealLoop::clone_skeleton_predicates_to_unswitched_loop (Deoptimization::DeoptReason reason, ProjNode* old_predicate_proj,
235
236
ProjNode* new_predicate_proj, bool is_slow_loop, uint idx_before_clone,
236
237
Node_List &old_new) {
237
238
assert (old_predicate_proj->is_Proj (), " must be projection" );
@@ -249,7 +250,7 @@ void PhaseIdealLoop::clone_concrete_loop_predicates(Deoptimization::DeoptReason
249
250
uncommon_proj = iff->proj_out (1 - predicate->as_Proj ()->_con );
250
251
if (uncommon_proj->unique_ctrl_out () != rgn)
251
252
break ;
252
- if (iff->is_RangeCheck ( )) {
253
+ if (iff->in ( 1 )-> Opcode () == Op_Opaque4 && skeleton_predicate_has_opaque (iff )) {
253
254
// Only need to clone range check predicates as those can be changed and duplicated by inserting pre/main/post loops
254
255
// and doing loop unrolling. Push the original predicates on a list to later process them in reverse order to keep the
255
256
// original predicate order.
@@ -274,11 +275,11 @@ void PhaseIdealLoop::clone_concrete_loop_predicates(Deoptimization::DeoptReason
274
275
predicate = list.at (i);
275
276
assert (predicate->in (0 )->is_If (), " must be If node" );
276
277
iff = predicate->in (0 )->as_If ();
277
- assert (predicate->is_Proj () && predicate->as_Proj ()->is_IfProj () && iff-> is_RangeCheck () , " predicate must be a projection of a range check " );
278
+ assert (predicate->is_Proj () && predicate->as_Proj ()->is_IfProj (), " predicate must be a projection of an if node " );
278
279
IfProjNode* predicate_proj = predicate->as_IfProj ();
279
280
280
281
// cloned_proj is the same type of projection as the original predicate projection (IfTrue or IfFalse)
281
- ProjNode* cloned_proj = create_new_if_for_predicate (new_predicate_proj, NULL , reason, Op_RangeCheck , predicate_proj->is_IfTrue ());
282
+ ProjNode* cloned_proj = create_new_if_for_predicate (new_predicate_proj, NULL , reason, iff-> Opcode () , predicate_proj->is_IfTrue ());
282
283
283
284
// Replace bool input by input from original predicate
284
285
_igvn.replace_input_of (cloned_proj->in (0 ), 1 , iff->in (1 ));
@@ -297,12 +298,6 @@ void PhaseIdealLoop::clone_concrete_loop_predicates(Deoptimization::DeoptReason
297
298
}
298
299
assert (slow_node->_idx <= idx_before_clone || old_new[slow_node->_idx ] == NULL , " mapping of cloned nodes must be null" );
299
300
}
300
-
301
- // Let old predicates before unswitched loops which were cloned die if all their control edges were rewired
302
- // to the cloned predicates in the unswitched loops.
303
- if (predicate->outcnt () == 1 ) {
304
- _igvn.replace_input_of (iff, 1 , _igvn.intcon (predicate_proj->_con ));
305
- }
306
301
} else {
307
302
// Fast loop
308
303
for (DUIterator i = predicate->outs (); predicate->has_out (i); i++) {
@@ -324,7 +319,7 @@ void PhaseIdealLoop::clone_concrete_loop_predicates(Deoptimization::DeoptReason
324
319
325
320
// --------------------------clone_loop_predicates-----------------------
326
321
// Clone loop predicates to cloned loops when unswitching a loop.
327
- Node* PhaseIdealLoop::clone_loop_predicates (Node* old_entry, Node* new_entry, bool clone_limit_check,
322
+ Node* PhaseIdealLoop::clone_predicates_to_unswitched_loop (Node* old_entry, Node* new_entry, bool clone_limit_check,
328
323
bool is_slow_loop, uint idx_before_clone, Node_List &old_new) {
329
324
#ifdef ASSERT
330
325
assert (LoopUnswitching, " sanity - only called when unswitching a loop" );
@@ -354,7 +349,7 @@ Node* PhaseIdealLoop::clone_loop_predicates(Node* old_entry, Node* new_entry, bo
354
349
}
355
350
if (predicate_proj != NULL ) { // right pattern that can be used by loop predication
356
351
// clone predicate
357
- new_entry = clone_loop_predicate (predicate_proj, new_entry, Deoptimization::Reason_predicate, is_slow_loop,
352
+ new_entry = clone_predicate_to_unswitched_loop (predicate_proj, new_entry, Deoptimization::Reason_predicate, is_slow_loop,
358
353
idx_before_clone, old_new);
359
354
assert (new_entry != NULL && new_entry->is_Proj (), " IfTrue or IfFalse after clone predicate" );
360
355
if (TraceLoopPredicate) {
@@ -364,7 +359,7 @@ Node* PhaseIdealLoop::clone_loop_predicates(Node* old_entry, Node* new_entry, bo
364
359
}
365
360
if (profile_predicate_proj != NULL ) { // right pattern that can be used by loop predication
366
361
// clone predicate
367
- new_entry = clone_loop_predicate (profile_predicate_proj, new_entry,Deoptimization::Reason_profile_predicate,
362
+ new_entry = clone_predicate_to_unswitched_loop (profile_predicate_proj, new_entry,Deoptimization::Reason_profile_predicate,
368
363
is_slow_loop, idx_before_clone, old_new);
369
364
assert (new_entry != NULL && new_entry->is_Proj (), " IfTrue or IfFalse after clone predicate" );
370
365
if (TraceLoopPredicate) {
@@ -376,7 +371,7 @@ Node* PhaseIdealLoop::clone_loop_predicates(Node* old_entry, Node* new_entry, bo
376
371
// Clone loop limit check last to insert it before loop.
377
372
// Don't clone a limit check which was already finalized
378
373
// for this counted loop (only one limit check is needed).
379
- new_entry = clone_loop_predicate (limit_check_proj, new_entry, Deoptimization::Reason_loop_limit_check,
374
+ new_entry = clone_predicate_to_unswitched_loop (limit_check_proj, new_entry, Deoptimization::Reason_loop_limit_check,
380
375
is_slow_loop, idx_before_clone, old_new);
381
376
assert (new_entry != NULL && new_entry->is_Proj (), " IfTrue or IfFalse after clone limit check" );
382
377
if (TraceLoopLimitCheck) {
0 commit comments