@@ -231,33 +231,20 @@ ProjNode* PhaseIdealLoop::clone_predicate_to_unswitched_loop(ProjNode* predicate
231231// the old predicates to the new cloned predicates.
232232void PhaseIdealLoop::clone_skeleton_predicates_to_unswitched_loop (IdealLoopTree* loop, const Node_List& old_new, Deoptimization::DeoptReason reason,
233233 ProjNode* old_predicate_proj, ProjNode* iffast_pred, ProjNode* ifslow_pred) {
234- IfNode* iff = old_predicate_proj->in (0 )->as_If ();
235234 assert (iffast_pred->in (0 )->is_If () && ifslow_pred->in (0 )->is_If (), " sanity check" );
236- ProjNode* uncommon_proj = iff->proj_out (1 - old_predicate_proj->as_Proj ()->_con );
237- Node* rgn = uncommon_proj->unique_ctrl_out ();
238- assert (rgn->is_Region () || rgn->is_Call (), " must be a region or call uct" );
239- assert (iff->in (1 )->in (1 )->Opcode () == Op_Opaque1, " unexpected predicate shape" );
240- Node* predicate = iff->in (0 );
235+ // Only need to clone range check predicates as those can be changed and duplicated by inserting pre/main/post loops
236+ // and doing loop unrolling. Push the original predicates on a list to later process them in reverse order to keep the
237+ // original predicate order.
241238 Unique_Node_List list;
242- while (predicate != NULL && predicate->is_Proj () && predicate->in (0 )->is_If ()) {
243- iff = predicate->in (0 )->as_If ();
244- uncommon_proj = iff->proj_out (1 - predicate->as_Proj ()->_con );
245- if (uncommon_proj->unique_ctrl_out () != rgn)
246- break ;
247- if (iff->in (1 )->Opcode () == Op_Opaque4 && skeleton_predicate_has_opaque (iff)) {
248- // Only need to clone range check predicates as those can be changed and duplicated by inserting pre/main/post loops
249- // and doing loop unrolling. Push the original predicates on a list to later process them in reverse order to keep the
250- // original predicate order.
251- list.push (predicate);
252- }
253- predicate = predicate->in (0 )->in (0 );
254- }
239+ get_skeleton_predicates (old_predicate_proj, list);
255240
256241 Node_List to_process;
242+ IfNode* iff = old_predicate_proj->in (0 )->as_If ();
243+ ProjNode* uncommon_proj = iff->proj_out (1 - old_predicate_proj->as_Proj ()->_con );
257244 // Process in reverse order such that 'create_new_if_for_predicate' can be used in 'clone_skeleton_predicate_for_unswitched_loops'
258245 // and the original order is maintained.
259246 for (int i = list.size () - 1 ; i >= 0 ; i--) {
260- predicate = list.at (i);
247+ Node* predicate = list.at (i);
261248 assert (predicate->in (0 )->is_If (), " must be If node" );
262249 iff = predicate->in (0 )->as_If ();
263250 assert (predicate->is_Proj () && predicate->as_Proj ()->is_IfProj (), " predicate must be a projection of an if node" );
@@ -288,6 +275,34 @@ void PhaseIdealLoop::clone_skeleton_predicates_to_unswitched_loop(IdealLoopTree*
288275 }
289276}
290277
278+ // Put all skeleton predicate projections on a list, starting at 'predicate' and going up in the tree. If 'get_opaque'
279+ // is set, then the Opaque4 nodes of the skeleton predicates are put on the list instead of the projections.
280+ void PhaseIdealLoop::get_skeleton_predicates (Node* predicate, Unique_Node_List& list, bool get_opaque) {
281+ IfNode* iff = predicate->in (0 )->as_If ();
282+ ProjNode* uncommon_proj = iff->proj_out (1 - predicate->as_Proj ()->_con );
283+ Node* rgn = uncommon_proj->unique_ctrl_out ();
284+ assert (rgn->is_Region () || rgn->is_Call (), " must be a region or call uct" );
285+ assert (iff->in (1 )->in (1 )->Opcode () == Op_Opaque1, " unexpected predicate shape" );
286+ predicate = iff->in (0 );
287+ while (predicate != NULL && predicate->is_Proj () && predicate->in (0 )->is_If ()) {
288+ iff = predicate->in (0 )->as_If ();
289+ uncommon_proj = iff->proj_out (1 - predicate->as_Proj ()->_con );
290+ if (uncommon_proj->unique_ctrl_out () != rgn) {
291+ break ;
292+ }
293+ if (iff->in (1 )->Opcode () == Op_Opaque4 && skeleton_predicate_has_opaque (iff)) {
294+ if (get_opaque) {
295+ // Collect the predicate Opaque4 node.
296+ list.push (iff->in (1 ));
297+ } else {
298+ // Collect the predicate projection.
299+ list.push (predicate);
300+ }
301+ }
302+ predicate = predicate->in (0 )->in (0 );
303+ }
304+ }
305+
291306// Clone a skeleton predicate for an unswitched loop. OpaqueLoopInit and OpaqueLoopStride nodes are cloned and uncommon
292307// traps are kept for the predicate (a Halt node is used later when creating pre/main/post loops and copying this cloned
293308// predicate again).
@@ -1241,6 +1256,7 @@ ProjNode* PhaseIdealLoop::insert_initial_skeleton_predicate(IfNode* iff, IdealLo
12411256 register_new_node (opaque_init, upper_bound_proj);
12421257 BoolNode* bol = rc_predicate (loop, upper_bound_proj, scale, offset, opaque_init, limit, stride, rng, (stride > 0 ) != (scale > 0 ), overflow);
12431258 Node* opaque_bol = new Opaque4Node (C, bol, _igvn.intcon (1 )); // This will go away once loop opts are over
1259+ C->add_skeleton_predicate_opaq (opaque_bol);
12441260 register_new_node (opaque_bol, upper_bound_proj);
12451261 ProjNode* new_proj = create_new_if_for_predicate (predicate_proj, NULL , reason, overflow ? Op_If : iff->Opcode ());
12461262 _igvn.replace_input_of (new_proj->in (0 ), 1 , opaque_bol);
@@ -1258,6 +1274,7 @@ ProjNode* PhaseIdealLoop::insert_initial_skeleton_predicate(IfNode* iff, IdealLo
12581274 register_new_node (max_value, new_proj);
12591275 bol = rc_predicate (loop, new_proj, scale, offset, max_value, limit, stride, rng, (stride > 0 ) != (scale > 0 ), overflow);
12601276 opaque_bol = new Opaque4Node (C, bol, _igvn.intcon (1 ));
1277+ C->add_skeleton_predicate_opaq (opaque_bol);
12611278 register_new_node (opaque_bol, new_proj);
12621279 new_proj = create_new_if_for_predicate (predicate_proj, NULL , reason, overflow ? Op_If : iff->Opcode ());
12631280 _igvn.replace_input_of (new_proj->in (0 ), 1 , opaque_bol);
0 commit comments