Mon, 21 Mar 2016 09:51:20 +0100
8148754: C2 loop unrolling fails due to unexpected graph shape
Summary: Check if graph shape is appropriate for optimization, bail out optimization if not.
Reviewed-by: kvn, twisti, shade, dnsimon
1.1 --- a/src/share/vm/opto/loopTransform.cpp Thu Jun 06 20:19:03 2019 +0200 1.2 +++ b/src/share/vm/opto/loopTransform.cpp Mon Mar 21 09:51:20 2016 +0100 1.3 @@ -1223,20 +1223,14 @@ 1.4 Node *opaq = NULL; 1.5 if (adjust_min_trip) { // If not maximally unrolling, need adjustment 1.6 // Search for zero-trip guard. 1.7 - assert( loop_head->is_main_loop(), "" ); 1.8 - assert( ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, "" ); 1.9 - Node *iff = ctrl->in(0); 1.10 - assert( iff->Opcode() == Op_If, "" ); 1.11 - Node *bol = iff->in(1); 1.12 - assert( bol->Opcode() == Op_Bool, "" ); 1.13 - Node *cmp = bol->in(1); 1.14 - assert( cmp->Opcode() == Op_CmpI, "" ); 1.15 - opaq = cmp->in(2); 1.16 - // Occasionally it's possible for a zero-trip guard Opaque1 node to be 1.17 - // optimized away and then another round of loop opts attempted. 1.18 - // We can not optimize this particular loop in that case. 1.19 - if (opaq->Opcode() != Op_Opaque1) 1.20 - return; // Cannot find zero-trip guard! Bail out! 1.21 + 1.22 + // Check the shape of the graph at the loop entry. If an inappropriate 1.23 + // graph shape is encountered, the compiler bails out loop unrolling; 1.24 + // compilation of the method will still succeed. 1.25 + if (!is_canonical_main_loop_entry(loop_head)) { 1.26 + return; 1.27 + } 1.28 + opaq = ctrl->in(0)->in(1)->in(1)->in(2); 1.29 // Zero-trip test uses an 'opaque' node which is not shared. 1.30 assert(opaq->outcnt() == 1 && opaq->in(1) == limit, ""); 1.31 } 1.32 @@ -1806,7 +1800,6 @@ 1.33 #endif 1.34 assert(RangeCheckElimination, ""); 1.35 CountedLoopNode *cl = loop->_head->as_CountedLoop(); 1.36 - assert(cl->is_main_loop(), ""); 1.37 1.38 // protect against stride not being a constant 1.39 if (!cl->stride_is_con()) 1.40 @@ -1818,20 +1811,17 @@ 1.41 // to not ever trip end tests 1.42 Node *main_limit = cl->limit(); 1.43 1.44 + // Check graph shape. Cannot optimize a loop if zero-trip 1.45 + // Opaque1 node is optimized away and then another round 1.46 + // of loop opts attempted. 1.47 + if (!is_canonical_main_loop_entry(cl)) { 1.48 + return; 1.49 + } 1.50 + 1.51 // Need to find the main-loop zero-trip guard 1.52 Node *ctrl = cl->in(LoopNode::EntryControl); 1.53 - assert(ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, ""); 1.54 Node *iffm = ctrl->in(0); 1.55 - assert(iffm->Opcode() == Op_If, ""); 1.56 - Node *bolzm = iffm->in(1); 1.57 - assert(bolzm->Opcode() == Op_Bool, ""); 1.58 - Node *cmpzm = bolzm->in(1); 1.59 - assert(cmpzm->is_Cmp(), ""); 1.60 - Node *opqzm = cmpzm->in(2); 1.61 - // Can not optimize a loop if zero-trip Opaque1 node is optimized 1.62 - // away and then another round of loop opts attempted. 1.63 - if (opqzm->Opcode() != Op_Opaque1) 1.64 - return; 1.65 + Node *opqzm = iffm->in(1)->in(1)->in(2); 1.66 assert(opqzm->in(1) == main_limit, "do not understand situation"); 1.67 1.68 // Find the pre-loop limit; we will expand it's iterations to
2.1 --- a/src/share/vm/opto/loopnode.cpp Thu Jun 06 20:19:03 2019 +0200 2.2 +++ b/src/share/vm/opto/loopnode.cpp Mon Mar 21 09:51:20 2016 +0100 2.3 @@ -3282,6 +3282,41 @@ 2.4 return LCA; 2.5 } 2.6 2.7 +// Check the shape of the graph at the loop entry. In some cases, 2.8 +// the shape of the graph does not match the shape outlined below. 2.9 +// That is caused by the Opaque1 node "protecting" the shape of 2.10 +// the graph being removed by, for example, the IGVN performed 2.11 +// in PhaseIdealLoop::build_and_optimize(). 2.12 +// 2.13 +// After the Opaque1 node has been removed, optimizations (e.g., split-if, 2.14 +// loop unswitching, and IGVN, or a combination of them) can freely change 2.15 +// the graph's shape. As a result, the graph shape outlined below cannot 2.16 +// be guaranteed anymore. 2.17 +bool PhaseIdealLoop::is_canonical_main_loop_entry(CountedLoopNode* cl) { 2.18 + assert(cl->is_main_loop(), "check should be applied to main loops"); 2.19 + Node* ctrl = cl->in(LoopNode::EntryControl); 2.20 + if (ctrl == NULL || (!ctrl->is_IfTrue() && !ctrl->is_IfFalse())) { 2.21 + return false; 2.22 + } 2.23 + Node* iffm = ctrl->in(0); 2.24 + if (iffm == NULL || !iffm->is_If()) { 2.25 + return false; 2.26 + } 2.27 + Node* bolzm = iffm->in(1); 2.28 + if (bolzm == NULL || !bolzm->is_Bool()) { 2.29 + return false; 2.30 + } 2.31 + Node* cmpzm = bolzm->in(1); 2.32 + if (cmpzm == NULL || !cmpzm->is_Cmp()) { 2.33 + return false; 2.34 + } 2.35 + Node* opqzm = cmpzm->in(2); 2.36 + if (opqzm == NULL || opqzm->Opcode() != Op_Opaque1) { 2.37 + return false; 2.38 + } 2.39 + return true; 2.40 +} 2.41 + 2.42 //------------------------------get_late_ctrl---------------------------------- 2.43 // Compute latest legal control. 2.44 Node *PhaseIdealLoop::get_late_ctrl( Node *n, Node *early ) {
3.1 --- a/src/share/vm/opto/loopnode.hpp Thu Jun 06 20:19:03 2019 +0200 3.2 +++ b/src/share/vm/opto/loopnode.hpp Mon Mar 21 09:51:20 2016 +0100 3.3 @@ -619,6 +619,9 @@ 3.4 bool cast_incr_before_loop(Node* incr, Node* ctrl, Node* loop); 3.5 3.6 public: 3.7 + 3.8 + static bool is_canonical_main_loop_entry(CountedLoopNode* cl); 3.9 + 3.10 bool has_node( Node* n ) const { 3.11 guarantee(n != NULL, "No Node."); 3.12 return _nodes[n->_idx] != NULL;
4.1 --- a/src/share/vm/opto/superword.cpp Thu Jun 06 20:19:03 2019 +0200 4.2 +++ b/src/share/vm/opto/superword.cpp Mon Mar 21 09:51:20 2016 +0100 4.3 @@ -2209,21 +2209,13 @@ 4.4 //----------------------------get_pre_loop_end--------------------------- 4.5 // Find pre loop end from main loop. Returns null if none. 4.6 CountedLoopEndNode* SuperWord::get_pre_loop_end(CountedLoopNode* cl) { 4.7 - Node* ctrl = cl->in(LoopNode::EntryControl); 4.8 - if (!ctrl->is_IfTrue() && !ctrl->is_IfFalse()) return NULL; 4.9 - Node* iffm = ctrl->in(0); 4.10 - if (!iffm->is_If()) return NULL; 4.11 - Node* bolzm = iffm->in(1); 4.12 - if (!bolzm->is_Bool()) return NULL; 4.13 - Node* cmpzm = bolzm->in(1); 4.14 - if (!cmpzm->is_Cmp()) return NULL; 4.15 - Node* opqzm = cmpzm->in(2); 4.16 - // Can not optimize a loop if zero-trip Opaque1 node is optimized 4.17 - // away and then another round of loop opts attempted. 4.18 - if (opqzm->Opcode() != Op_Opaque1) { 4.19 + // The loop cannot be optimized if the graph shape at 4.20 + // the loop entry is inappropriate. 4.21 + if (!PhaseIdealLoop::is_canonical_main_loop_entry(cl)) { 4.22 return NULL; 4.23 } 4.24 - Node* p_f = iffm->in(0); 4.25 + 4.26 + Node* p_f = cl->in(LoopNode::EntryControl)->in(0)->in(0); 4.27 if (!p_f->is_IfFalse()) return NULL; 4.28 if (!p_f->in(0)->is_CountedLoopEnd()) return NULL; 4.29 CountedLoopEndNode* pre_end = p_f->in(0)->as_CountedLoopEnd();