@@ -210,8 +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_predicate_to_unswitched_loop (ProjNode* predicate_proj, Node* new_entry, Deoptimization::DeoptReason reason,
214
- bool is_slow_loop, uint idx_before_clone, Node_List &old_new) {
213
+ ProjNode* PhaseIdealLoop::clone_predicate_to_unswitched_loop (ProjNode* predicate_proj, Node* new_entry, Deoptimization::DeoptReason reason) {
215
214
ProjNode* new_predicate_proj = create_new_if_for_predicate (predicate_proj, new_entry, reason, Op_If);
216
215
IfNode* iff = new_predicate_proj->in (0 )->as_If ();
217
216
Node* ctrl = iff->in (0 );
@@ -225,17 +224,14 @@ ProjNode* PhaseIdealLoop::clone_predicate_to_unswitched_loop(ProjNode* predicate
225
224
register_new_node (bol, ctrl);
226
225
_igvn.hash_delete (iff);
227
226
iff->set_req (1 , bol);
228
- clone_skeleton_predicates_to_unswitched_loop (reason, predicate_proj, new_predicate_proj, is_slow_loop, idx_before_clone, old_new);
229
227
return new_predicate_proj;
230
228
}
231
229
232
230
// Clones skeleton predicates starting at 'old_predicate_proj' to
233
231
// 'new_predicate_proj' and rewires the control edges of data nodes in
234
232
// 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,
236
- ProjNode* new_predicate_proj, bool is_slow_loop, uint idx_before_clone,
237
- Node_List &old_new) {
238
- assert (old_predicate_proj->is_Proj (), " must be projection" );
233
+ void PhaseIdealLoop::clone_skeleton_predicates_to_unswitched_loop (IdealLoopTree* loop, const Node_List& old_new, Deoptimization::DeoptReason reason,
234
+ ProjNode* old_predicate_proj, ProjNode* iffast, ProjNode* ifslow) {
239
235
IfNode* iff = old_predicate_proj->in (0 )->as_If ();
240
236
ProjNode* uncommon_proj = iff->proj_out (1 - old_predicate_proj->as_Proj ()->_con );
241
237
Node* rgn = uncommon_proj->unique_ctrl_out ();
@@ -255,21 +251,11 @@ void PhaseIdealLoop::clone_skeleton_predicates_to_unswitched_loop(Deoptimization
255
251
// and doing loop unrolling. Push the original predicates on a list to later process them in reverse order to keep the
256
252
// original predicate order.
257
253
list.push (predicate);
258
- #ifdef ASSERT
259
- } else {
260
- // All other If predicates should not have a control input to nodes belonging to the original loop
261
- for (DUIterator i = predicate->outs (); predicate->has_out (i); i++) {
262
- Node* old_node = predicate->out (i);
263
- Node* new_node = old_new[old_node->_idx ];
264
- if (!old_node->is_CFG () && new_node != NULL && old_node->_idx >= idx_before_clone) {
265
- assert (false , " should not be part of the original loop" );
266
- }
267
- }
268
- #endif
269
254
}
270
255
predicate = predicate->in (0 )->in (0 );
271
256
}
272
257
258
+ Node_List to_process;
273
259
// Process in reverse order such that 'create_new_if_for_predicate' can be used and the original order is maintained
274
260
for (int i = list.size ()-1 ; i >= 0 ; i--) {
275
261
predicate = list.at (i);
@@ -279,58 +265,41 @@ void PhaseIdealLoop::clone_skeleton_predicates_to_unswitched_loop(Deoptimization
279
265
IfProjNode* predicate_proj = predicate->as_IfProj ();
280
266
281
267
// cloned_proj is the same type of projection as the original predicate projection (IfTrue or IfFalse)
282
- ProjNode* cloned_proj = create_new_if_for_predicate (new_predicate_proj, NULL , reason, iff->Opcode (), predicate_proj->is_IfTrue ());
268
+ ProjNode* fast_proj = create_new_if_for_predicate (iffast, NULL , reason, iff->Opcode (), predicate_proj->is_IfTrue ());
269
+ ProjNode* slow_proj = create_new_if_for_predicate (ifslow, NULL , reason, iff->Opcode (), predicate_proj->is_IfTrue ());
283
270
284
271
// Replace bool input by input from original predicate
285
- _igvn.replace_input_of (cloned_proj->in (0 ), 1 , iff->in (1 ));
286
-
287
- if (is_slow_loop) {
288
- for (DUIterator i = predicate->outs (); predicate->has_out (i); i++) {
289
- Node* slow_node = predicate->out (i);
290
- Node* fast_node = old_new[slow_node->_idx ];
291
- if (!slow_node->is_CFG () && fast_node != NULL && slow_node->_idx > idx_before_clone) {
292
- // 'slow_node' is a data node and part of the slow loop. This is a clone of the fast loop node
293
- // which was temporarily added below in order to verify that 'slow_node' is a clone of 'fast_node'.
294
- // Update the control input and reset the mapping for 'slow_node' back to NULL.
295
- _igvn.replace_input_of (slow_node, 0 , cloned_proj);
296
- old_new.map (slow_node->_idx , NULL );
297
- --i;
298
- }
299
- assert (slow_node->_idx <= idx_before_clone || old_new[slow_node->_idx ] == NULL , " mapping of cloned nodes must be null" );
300
- }
301
- } else {
302
- // Fast loop
303
- for (DUIterator i = predicate->outs (); predicate->has_out (i); i++) {
304
- Node* fast_node = predicate->out (i);
272
+ _igvn.replace_input_of (fast_proj->in (0 ), 1 , iff->in (1 ));
273
+ _igvn.replace_input_of (slow_proj->in (0 ), 1 , iff->in (1 ));
274
+
275
+ for (DUIterator i = predicate->outs (); predicate->has_out (i); i++) {
276
+ Node* fast_node = predicate->out (i);
277
+ if (loop->is_member (get_loop (ctrl_or_self (fast_node)))) {
278
+ assert (fast_node->in (0 ) == predicate, " only control edge" );
305
279
Node* slow_node = old_new[fast_node->_idx ];
306
- if (!fast_node->is_CFG () && slow_node != NULL && slow_node->_idx > idx_before_clone) {
307
- // 'fast_node' is a data node and part of the fast loop. Add the clone of the fast loop node
308
- // to the 'old_new' mapping in order to verify later when cloning the predicates for the slow loop
309
- // that 'slow_node' is a clone of 'fast_node'. Update the control input for 'fast_node'.
310
- _igvn.replace_input_of (fast_node, 0 , cloned_proj);
311
- assert (old_new[slow_node->_idx ] == NULL , " mapping must be null for cloned nodes" );
312
- old_new.map (slow_node->_idx , fast_node);
313
- --i;
314
- }
280
+ assert (slow_node->in (0 ) == predicate, " only control edge" );
281
+ _igvn.replace_input_of (fast_node, 0 , fast_proj);
282
+ to_process.push (slow_node);
283
+ --i;
315
284
}
316
285
}
286
+ // Have to delay updates to the slow loop so uses of predicate are
287
+ // not modified while we iterate on them.
288
+ while (to_process.size () > 0 ) {
289
+ Node* slow_node = to_process.pop ();
290
+ _igvn.replace_input_of (slow_node, 0 , slow_proj);
291
+ }
317
292
}
318
293
}
319
294
320
295
// --------------------------clone_loop_predicates-----------------------
321
296
// Clone loop predicates to cloned loops when unswitching a loop.
322
- Node* PhaseIdealLoop::clone_predicates_to_unswitched_loop (Node* old_entry, Node* new_entry, bool clone_limit_check,
323
- bool is_slow_loop, uint idx_before_clone, Node_List &old_new) {
324
- #ifdef ASSERT
325
- assert (LoopUnswitching, " sanity - only called when unswitching a loop" );
326
- if (new_entry == NULL || !(new_entry->is_Proj () || new_entry->is_Region () || new_entry->is_SafePoint ())) {
327
- if (new_entry != NULL )
328
- new_entry->dump ();
329
- assert (false , " not IfTrue, IfFalse, Region or SafePoint" );
330
- }
331
- #endif
297
+ void PhaseIdealLoop::clone_predicates_to_unswitched_loop (IdealLoopTree* loop, const Node_List& old_new, ProjNode*& iffast, ProjNode*& ifslow) {
298
+ LoopNode* head = loop->_head ->as_Loop ();
299
+ bool clone_limit_check = !head->is_CountedLoop ();
300
+ Node* entry = head->skip_strip_mined ()->in (LoopNode::EntryControl);
301
+
332
302
// Search original predicates
333
- Node* entry = old_entry;
334
303
ProjNode* limit_check_proj = NULL ;
335
304
limit_check_proj = find_predicate_insertion_point (entry, Deoptimization::Reason_loop_limit_check);
336
305
if (limit_check_proj != NULL ) {
@@ -349,39 +318,45 @@ Node* PhaseIdealLoop::clone_predicates_to_unswitched_loop(Node* old_entry, Node*
349
318
}
350
319
if (predicate_proj != NULL ) { // right pattern that can be used by loop predication
351
320
// clone predicate
352
- new_entry = clone_predicate_to_unswitched_loop (predicate_proj, new_entry, Deoptimization::Reason_predicate, is_slow_loop,
353
- idx_before_clone, old_new);
354
- assert (new_entry != NULL && new_entry->is_Proj (), " IfTrue or IfFalse after clone predicate" );
355
- if (TraceLoopPredicate) {
356
- tty->print (" Loop Predicate cloned: " );
357
- debug_only ( new_entry->in (0 )->dump (); );
358
- }
321
+ iffast = clone_predicate_to_unswitched_loop (predicate_proj, iffast, Deoptimization::Reason_predicate);
322
+ ifslow = clone_predicate_to_unswitched_loop (predicate_proj, ifslow, Deoptimization::Reason_predicate);
323
+ clone_skeleton_predicates_to_unswitched_loop (loop, old_new, Deoptimization::Reason_predicate, predicate_proj, iffast, ifslow);
324
+
325
+ check_created_predicate_for_unswitching (iffast);
326
+ check_created_predicate_for_unswitching (ifslow);
359
327
}
360
328
if (profile_predicate_proj != NULL ) { // right pattern that can be used by loop predication
361
329
// clone predicate
362
- new_entry = clone_predicate_to_unswitched_loop (profile_predicate_proj, new_entry,Deoptimization::Reason_profile_predicate,
363
- is_slow_loop, idx_before_clone, old_new);
364
- assert (new_entry != NULL && new_entry->is_Proj (), " IfTrue or IfFalse after clone predicate" );
365
- if (TraceLoopPredicate) {
366
- tty->print (" Loop Predicate cloned: " );
367
- debug_only ( new_entry->in (0 )->dump (); );
368
- }
330
+ iffast = clone_predicate_to_unswitched_loop (profile_predicate_proj, iffast, Deoptimization::Reason_profile_predicate);
331
+ ifslow = clone_predicate_to_unswitched_loop (profile_predicate_proj, ifslow, Deoptimization::Reason_profile_predicate);
332
+ clone_skeleton_predicates_to_unswitched_loop (loop, old_new, Deoptimization::Reason_profile_predicate, profile_predicate_proj, iffast, ifslow);
333
+
334
+ check_created_predicate_for_unswitching (iffast);
335
+ check_created_predicate_for_unswitching (ifslow);
369
336
}
370
337
if (limit_check_proj != NULL && clone_limit_check) {
371
338
// Clone loop limit check last to insert it before loop.
372
339
// Don't clone a limit check which was already finalized
373
340
// for this counted loop (only one limit check is needed).
374
- new_entry = clone_predicate_to_unswitched_loop (limit_check_proj, new_entry, Deoptimization::Reason_loop_limit_check,
375
- is_slow_loop, idx_before_clone, old_new);
376
- assert (new_entry != NULL && new_entry->is_Proj (), " IfTrue or IfFalse after clone limit check" );
377
- if (TraceLoopLimitCheck) {
378
- tty->print (" Loop Limit Check cloned: " );
379
- debug_only ( new_entry->in (0 )->dump (); )
380
- }
341
+ iffast = clone_predicate_to_unswitched_loop (limit_check_proj, iffast, Deoptimization::Reason_loop_limit_check);
342
+ ifslow = clone_predicate_to_unswitched_loop (limit_check_proj, ifslow, Deoptimization::Reason_loop_limit_check);
343
+
344
+ check_created_predicate_for_unswitching (iffast);
345
+ check_created_predicate_for_unswitching (ifslow);
381
346
}
382
- return new_entry;
383
347
}
384
348
349
+ #ifndef PRODUCT
350
+ void PhaseIdealLoop::check_created_predicate_for_unswitching (const Node* new_entry) const {
351
+ assert (new_entry != NULL , " IfTrue or IfFalse after clone predicate" );
352
+ if (TraceLoopPredicate) {
353
+ tty->print (" Loop Predicate cloned: " );
354
+ debug_only (new_entry->in (0 )->dump (););
355
+ }
356
+ }
357
+ #endif
358
+
359
+
385
360
// --------------------------skip_loop_predicates------------------------------
386
361
// Skip related predicates.
387
362
Node* PhaseIdealLoop::skip_loop_predicates (Node* entry) {
0 commit comments