@@ -100,8 +100,7 @@ void PhaseIdealLoop::register_control(Node* n, IdealLoopTree *loop, Node* pred,
100
100
// is an IfTrue projection. This code is also used to clone predicates to cloned loops.
101
101
IfTrueNode* PhaseIdealLoop::create_new_if_for_predicate (ParsePredicateSuccessProj* parse_predicate_success_proj,
102
102
Node* new_entry, const Deoptimization::DeoptReason reason,
103
- const int opcode, const bool rewire_uncommon_proj_phi_inputs,
104
- AssertionPredicateType assertion_predicate_type) {
103
+ const int opcode, const bool rewire_uncommon_proj_phi_inputs) {
105
104
assert (parse_predicate_success_proj->is_uncommon_trap_if_pattern (reason), " must be a uct if pattern!" );
106
105
ParsePredicateNode* parse_predicate = parse_predicate_success_proj->in (0 )->as_ParsePredicate ();
107
106
ParsePredicateUncommonProj* uncommon_proj = parse_predicate->uncommon_proj ();
@@ -143,12 +142,10 @@ IfTrueNode* PhaseIdealLoop::create_new_if_for_predicate(ParsePredicateSuccessPro
143
142
IfNode* new_iff = nullptr ;
144
143
switch (opcode) {
145
144
case Op_If:
146
- new_iff = new IfNode (entry, parse_predicate->in (1 ), parse_predicate->_prob , parse_predicate->_fcnt
147
- NOT_PRODUCT (COMMA assertion_predicate_type));
145
+ new_iff = new IfNode (entry, parse_predicate->in (1 ), parse_predicate->_prob , parse_predicate->_fcnt );
148
146
break ;
149
147
case Op_RangeCheck:
150
- new_iff = new RangeCheckNode (entry, parse_predicate->in (1 ), parse_predicate->_prob , parse_predicate->_fcnt
151
- NOT_PRODUCT (COMMA assertion_predicate_type));
148
+ new_iff = new RangeCheckNode (entry, parse_predicate->in (1 ), parse_predicate->_prob , parse_predicate->_fcnt );
152
149
break ;
153
150
case Op_ParsePredicate:
154
151
new_iff = new ParsePredicateNode (entry, reason, &_igvn);
@@ -272,150 +269,15 @@ void PhaseIdealLoop::fix_cloned_data_node_controls(const ProjNode* old_uncommon_
272
269
orig_to_clone.iterate_all (orig_clone_action);
273
270
}
274
271
275
- IfProjNode* PhaseIdealLoop::clone_parse_predicate_to_unswitched_loop (ParsePredicateSuccessProj* parse_predicate_proj,
276
- Node* new_entry, Deoptimization::DeoptReason reason,
277
- const bool slow_loop) {
278
-
279
- IfProjNode* new_predicate_proj = create_new_if_for_predicate (parse_predicate_proj, new_entry, reason, Op_ParsePredicate,
280
- slow_loop);
281
- assert (new_predicate_proj->is_IfTrue (), " the success projection of a Parse Predicate is a true projection" );
282
- ParsePredicateNode* parse_predicate = new_predicate_proj->in (0 )->as_ParsePredicate ();
283
- return new_predicate_proj;
284
- }
285
-
286
- // Clones Template Assertion Predicates to both unswitched loops starting at 'old_predicate_proj' by following its
287
- // control inputs. It also rewires the control edges of data nodes with dependencies in the loop from the old predicates
288
- // to the new cloned predicates.
289
- void PhaseIdealLoop::clone_assertion_predicates_to_unswitched_loop (IdealLoopTree* loop, const Node_List& old_new,
290
- ParsePredicateSuccessProj* old_parse_predicate_proj,
291
- ParsePredicateNode* true_path_loop_parse_predicate,
292
- ParsePredicateNode* false_path_loop_parse_predicate) {
293
- // Push the original Template Assertion Predicates on a list to later process them in reverse order to keep the
294
- // original predicate order.
295
- Unique_Node_List list;
296
- get_template_assertion_predicates (old_parse_predicate_proj, list);
297
-
298
- Node_List to_process;
299
- for (int i = list.size () - 1 ; i >= 0 ; i--) {
300
- IfTrueNode* template_assertion_predicate_success_proj = list.at (i)->as_IfTrue ();
301
- assert (template_assertion_predicate_success_proj->in (0 )->is_If (), " must be If node" );
302
-
303
- IfTrueNode* true_path_loop_proj =
304
- clone_assertion_predicate_for_unswitched_loops (template_assertion_predicate_success_proj,
305
- true_path_loop_parse_predicate);
306
- IfTrueNode* false_path_loop_proj =
307
- clone_assertion_predicate_for_unswitched_loops (template_assertion_predicate_success_proj,
308
- false_path_loop_parse_predicate);
309
-
310
- // Update control dependent data nodes.
311
- for (DUIterator j = template_assertion_predicate_success_proj->outs ();
312
- template_assertion_predicate_success_proj->has_out (j);
313
- j++) {
314
- Node* true_path_loop_node = template_assertion_predicate_success_proj->out (j);
315
- if (loop->is_member (get_loop (ctrl_or_self (true_path_loop_node)))) {
316
- assert (true_path_loop_node->in (0 ) == template_assertion_predicate_success_proj, " only control edge" );
317
- Node* false_path_loop_node = old_new[true_path_loop_node->_idx ];
318
- assert (false_path_loop_node->in (0 ) == template_assertion_predicate_success_proj, " only control edge" );
319
- _igvn.replace_input_of (true_path_loop_node, 0 , true_path_loop_proj);
320
- to_process.push (false_path_loop_node);
321
- --j;
322
- }
323
- }
324
- // Have to delay updates to the false path loop so uses of predicate are not modified while we iterate on them.
325
- while (to_process.size () > 0 ) {
326
- Node* slow_node = to_process.pop ();
327
- _igvn.replace_input_of (slow_node, 0 , false_path_loop_proj);
328
- }
329
- }
330
- }
331
-
332
- // Put all Template Assertion Predicate projections on a list, starting at 'predicate' and going up in the tree. If 'get_opaque'
333
- // is set, then the OpaqueTemplateAssertionPredicateNode nodes of the Assertion Predicates are put on the list instead
334
- // of the projections.
335
- void PhaseIdealLoop::get_template_assertion_predicates (ParsePredicateSuccessProj* parse_predicate_proj, Unique_Node_List& list,
336
- const bool get_opaque) {
272
+ // Put all OpaqueTemplateAssertionPredicate nodes on a list, starting at 'predicate' and going up in the tree.
273
+ void PhaseIdealLoop::get_opaque_template_assertion_predicate_nodes (ParsePredicateSuccessProj* parse_predicate_proj,
274
+ Unique_Node_List& list) {
337
275
Deoptimization::DeoptReason deopt_reason = parse_predicate_proj->in (0 )->as_ParsePredicate ()->deopt_reason ();
338
276
PredicateBlockIterator predicate_iterator (parse_predicate_proj, deopt_reason);
339
- TemplateAssertionPredicateCollector template_assertion_predicate_collector (list, get_opaque);
340
- predicate_iterator.for_each (template_assertion_predicate_collector);
341
- }
342
-
343
- // Clone an Assertion Predicate for an unswitched loop. OpaqueLoopInit and OpaqueLoopStride nodes are cloned and uncommon
344
- // traps are kept for the predicate (a Halt node is used later when creating pre/main/post loops and copying this cloned
345
- // predicate again).
346
- IfTrueNode*
347
- PhaseIdealLoop::clone_assertion_predicate_for_unswitched_loops (IfTrueNode* template_assertion_predicate_success_proj,
348
- ParsePredicateNode* unswitched_loop_parse_predicate) {
349
- TemplateAssertionPredicate template_assertion_predicate (template_assertion_predicate_success_proj);
350
- IfTrueNode* template_success_proj = template_assertion_predicate.clone (unswitched_loop_parse_predicate->in (0 ), this );
351
- _igvn.replace_input_of (unswitched_loop_parse_predicate, 0 , template_success_proj);
352
- set_idom (unswitched_loop_parse_predicate, template_success_proj, dom_depth (template_success_proj));
353
- return template_success_proj;
277
+ OpaqueTemplateAssertionPredicateCollector opaque_template_assertion_predicate_collector (list);
278
+ predicate_iterator.for_each (opaque_template_assertion_predicate_collector);
354
279
}
355
280
356
- // Clone the old Parse Predicates and Assertion Predicates before the unswitch If to the unswitched loops after the
357
- // unswitch If.
358
- void PhaseIdealLoop::clone_parse_and_assertion_predicates_to_unswitched_loop (IdealLoopTree* loop, Node_List& old_new,
359
- IfProjNode*& true_path_loop_entry,
360
- IfProjNode*& false_path_loop_entry) {
361
- LoopNode* head = loop->_head ->as_Loop ();
362
- Node* entry = head->skip_strip_mined ()->in (LoopNode::EntryControl);
363
-
364
- const Predicates predicates (entry);
365
- clone_loop_predication_predicates_to_unswitched_loop (loop, old_new, predicates.loop_predicate_block (),
366
- Deoptimization::Reason_predicate, true_path_loop_entry, false_path_loop_entry);
367
- clone_loop_predication_predicates_to_unswitched_loop (loop, old_new, predicates.profiled_loop_predicate_block (),
368
- Deoptimization::Reason_profile_predicate, true_path_loop_entry, false_path_loop_entry);
369
-
370
- const PredicateBlock* loop_limit_check_predicate_block = predicates.loop_limit_check_predicate_block ();
371
- if (loop_limit_check_predicate_block->has_parse_predicate () && !head->is_CountedLoop ()) {
372
- // Don't clone the Loop Limit Check Parse Predicate if we already have a counted loop (a Loop Limit Check Predicate
373
- // is only created when converting a LoopNode to a CountedLoopNode).
374
- clone_parse_predicate_to_unswitched_loops (loop_limit_check_predicate_block, Deoptimization::Reason_loop_limit_check,
375
- true_path_loop_entry, false_path_loop_entry);
376
- }
377
- }
378
-
379
- // Clone the Parse Predicate and Template Assertion Predicates of a Loop Predication related Predicate Block.
380
- void PhaseIdealLoop::clone_loop_predication_predicates_to_unswitched_loop (IdealLoopTree* loop, const Node_List& old_new,
381
- const PredicateBlock* predicate_block,
382
- Deoptimization::DeoptReason reason,
383
- IfProjNode*& true_path_loop_entry,
384
- IfProjNode*& false_path_loop_entry) {
385
- if (predicate_block->has_parse_predicate ()) {
386
- // We currently only clone Assertion Predicates if there are Parse Predicates. This is not entirely correct and will
387
- // be changed with the complete fix for Assertion Predicates.
388
- clone_parse_predicate_to_unswitched_loops (predicate_block, reason, true_path_loop_entry, false_path_loop_entry);
389
- assert (true_path_loop_entry->in (0 )->is_ParsePredicate () && false_path_loop_entry->in (0 )->is_ParsePredicate (),
390
- " must be success projections of the cloned Parse Predicates" );
391
- clone_assertion_predicates_to_unswitched_loop (loop, old_new, predicate_block->parse_predicate_success_proj (),
392
- true_path_loop_entry->in (0 )->as_ParsePredicate (),
393
- false_path_loop_entry->in (0 )->as_ParsePredicate ());
394
- }
395
- }
396
-
397
- void PhaseIdealLoop::clone_parse_predicate_to_unswitched_loops (const PredicateBlock* predicate_block,
398
- Deoptimization::DeoptReason reason,
399
- IfProjNode*& iffast_pred, IfProjNode*& ifslow_pred) {
400
- assert (predicate_block->has_parse_predicate (), " must have parse predicate" );
401
- ParsePredicateSuccessProj* parse_predicate_proj = predicate_block->parse_predicate_success_proj ();
402
- iffast_pred = clone_parse_predicate_to_unswitched_loop (parse_predicate_proj, iffast_pred, reason, false );
403
- check_cloned_parse_predicate_for_unswitching (iffast_pred, true );
404
-
405
- ifslow_pred = clone_parse_predicate_to_unswitched_loop (parse_predicate_proj, ifslow_pred, reason, true );
406
- check_cloned_parse_predicate_for_unswitching (ifslow_pred, false );
407
- }
408
-
409
- #ifndef PRODUCT
410
- void PhaseIdealLoop::check_cloned_parse_predicate_for_unswitching (const Node* new_entry, const bool is_fast_loop) {
411
- assert (new_entry != nullptr , " IfTrue or IfFalse after clone predicate" );
412
- if (TraceLoopPredicate) {
413
- tty->print (" Parse Predicate cloned to %s loop: " , is_fast_loop ? " fast" : " slow" );
414
- new_entry->in (0 )->dump ();
415
- }
416
- }
417
- #endif
418
-
419
281
// ------------------------------Invariance-----------------------------------
420
282
// Helper class for loop_predication_impl to compute invariance on the fly and
421
283
// clone invariants.
0 commit comments