From 392f962e0e87de1b5183505c86a967cc9999e04c Mon Sep 17 00:00:00 2001 From: Yi Yang Date: Wed, 19 May 2021 09:06:59 +0000 Subject: [PATCH] 8267151: C2: Don't create dummy Opaque1Node for outmost unswitched IfNode Reviewed-by: thartmann, neliasso --- src/hotspot/share/opto/loopUnswitch.cpp | 36 ++++++++----------------- src/hotspot/share/opto/loopnode.hpp | 5 ++-- 2 files changed, 14 insertions(+), 27 deletions(-) diff --git a/src/hotspot/share/opto/loopUnswitch.cpp b/src/hotspot/share/opto/loopUnswitch.cpp index 2b6c635820b32..abdc7e66a492b 100644 --- a/src/hotspot/share/opto/loopUnswitch.cpp +++ b/src/hotspot/share/opto/loopUnswitch.cpp @@ -147,7 +147,9 @@ void PhaseIdealLoop::do_unswitching(IdealLoopTree *loop, Node_List &old_new) { head->as_CountedLoop()->set_normal_loop(); } - ProjNode* proj_true = create_slow_version_of_loop(loop, old_new, unswitch_iff->Opcode(), CloneIncludesStripMined); + IfNode* invar_iff = create_slow_version_of_loop(loop, old_new, unswitch_iff, CloneIncludesStripMined); + ProjNode* proj_true = invar_iff->proj_out(1); + ProjNode* proj_false = invar_iff->proj_out(0); #ifdef ASSERT assert(proj_true->is_IfTrue(), "must be true projection"); @@ -183,20 +185,10 @@ void PhaseIdealLoop::do_unswitching(IdealLoopTree *loop, Node_List &old_new) { head->set_unswitch_count(nct); head_clone->set_unswitch_count(nct); - // Add test to new "if" outside of loop - IfNode* invar_iff = proj_true->in(0)->as_If(); - Node* invar_iff_c = invar_iff->in(0); - BoolNode* bol = unswitch_iff->in(1)->as_Bool(); - invar_iff->set_req(1, bol); - invar_iff->_prob = unswitch_iff->_prob; - - ProjNode* proj_false = invar_iff->proj_out(0)->as_Proj(); - // Hoist invariant casts out of each loop to the appropriate // control projection. Node_List worklist; - for (DUIterator_Fast imax, i = unswitch_iff->fast_outs(imax); i < imax; i++) { ProjNode* proj= unswitch_iff->fast_out(i)->as_Proj(); // Copy to a worklist for easier manipulation @@ -249,27 +241,22 @@ void PhaseIdealLoop::do_unswitching(IdealLoopTree *loop, Node_List &old_new) { //-------------------------create_slow_version_of_loop------------------------ // Create a slow version of the loop by cloning the loop // and inserting an if to select fast-slow versions. -// Return control projection of the entry to the fast version. -ProjNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree *loop, +// Return the inserted if. +IfNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree *loop, Node_List &old_new, - int opcode, + IfNode* unswitch_iff, CloneLoopMode mode) { LoopNode* head = loop->_head->as_Loop(); - bool counted_loop = head->is_CountedLoop(); Node* entry = head->skip_strip_mined()->in(LoopNode::EntryControl); _igvn.rehash_node_delayed(entry); IdealLoopTree* outer_loop = loop->_parent; head->verify_strip_mined(1); - Node *cont = _igvn.intcon(1); - set_ctrl(cont, C->root()); - Node* opq = new Opaque1Node(C, cont); - register_node(opq, outer_loop, entry, dom_depth(entry)); - Node *bol = new Conv2BNode(opq); - register_node(bol, outer_loop, entry, dom_depth(entry)); - IfNode* iff = (opcode == Op_RangeCheck) ? new RangeCheckNode(entry, bol, PROB_MAX, COUNT_UNKNOWN) : - new IfNode(entry, bol, PROB_MAX, COUNT_UNKNOWN); + // Add test to new "if" outside of loop + Node *bol = unswitch_iff->in(1)->as_Bool(); + IfNode* iff = (unswitch_iff->Opcode() == Op_RangeCheck) ? new RangeCheckNode(entry, bol, unswitch_iff->_prob, unswitch_iff->_fcnt) : + new IfNode(entry, bol, unswitch_iff->_prob, unswitch_iff->_fcnt); register_node(iff, outer_loop, entry, dom_depth(entry)); ProjNode* iffast = new IfTrueNode(iff); register_node(iffast, outer_loop, iff, dom_depth(iff)); @@ -296,13 +283,12 @@ ProjNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree *loop, recompute_dom_depth(); - return iffast; + return iff; } LoopNode* PhaseIdealLoop::create_reserve_version_of_loop(IdealLoopTree *loop, CountedLoopReserveKit* lk) { Node_List old_new; LoopNode* head = loop->_head->as_Loop(); - bool counted_loop = head->is_CountedLoop(); Node* entry = head->skip_strip_mined()->in(LoopNode::EntryControl); _igvn.rehash_node_delayed(entry); IdealLoopTree* outer_loop = head->is_strip_mined() ? loop->_parent->_parent : loop->_parent; diff --git a/src/hotspot/share/opto/loopnode.hpp b/src/hotspot/share/opto/loopnode.hpp index 856a433784153..726ca9e9228d8 100644 --- a/src/hotspot/share/opto/loopnode.hpp +++ b/src/hotspot/share/opto/loopnode.hpp @@ -1345,9 +1345,10 @@ class PhaseIdealLoop : public PhaseTransform { // Create a slow version of the loop by cloning the loop // and inserting an if to select fast-slow versions. - ProjNode* create_slow_version_of_loop(IdealLoopTree *loop, + // Return the inserted if. + IfNode* create_slow_version_of_loop(IdealLoopTree *loop, Node_List &old_new, - int opcode, + IfNode* unswitch_iff, CloneLoopMode mode); // Clone a loop and return the clone head (clone_loop_head).