Fri, 03 Oct 2008 13:58:20 -0700
6743188: incomplete fix for 6700047 C2 failed in idom_no_update
Reviewed-by: rasbold, kvn
1.1 --- a/src/share/vm/opto/loopTransform.cpp Thu Oct 02 08:37:44 2008 -0700 1.2 +++ b/src/share/vm/opto/loopTransform.cpp Fri Oct 03 13:58:20 2008 -0700 1.3 @@ -1590,10 +1590,10 @@ 1.4 1.5 //============================================================================= 1.6 //------------------------------iteration_split_impl--------------------------- 1.7 -void IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_new ) { 1.8 +bool IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_new ) { 1.9 // Check and remove empty loops (spam micro-benchmarks) 1.10 if( policy_do_remove_empty_loop(phase) ) 1.11 - return; // Here we removed an empty loop 1.12 + return true; // Here we removed an empty loop 1.13 1.14 bool should_peel = policy_peeling(phase); // Should we peel? 1.15 1.16 @@ -1603,7 +1603,8 @@ 1.17 // This removes loop-invariant tests (usually null checks). 1.18 if( !_head->is_CountedLoop() ) { // Non-counted loop 1.19 if (PartialPeelLoop && phase->partial_peel(this, old_new)) { 1.20 - return; 1.21 + // Partial peel succeeded so terminate this round of loop opts 1.22 + return false; 1.23 } 1.24 if( should_peel ) { // Should we peel? 1.25 #ifndef PRODUCT 1.26 @@ -1613,14 +1614,14 @@ 1.27 } else if( should_unswitch ) { 1.28 phase->do_unswitching(this, old_new); 1.29 } 1.30 - return; 1.31 + return true; 1.32 } 1.33 CountedLoopNode *cl = _head->as_CountedLoop(); 1.34 1.35 - if( !cl->loopexit() ) return; // Ignore various kinds of broken loops 1.36 + if( !cl->loopexit() ) return true; // Ignore various kinds of broken loops 1.37 1.38 // Do nothing special to pre- and post- loops 1.39 - if( cl->is_pre_loop() || cl->is_post_loop() ) return; 1.40 + if( cl->is_pre_loop() || cl->is_post_loop() ) return true; 1.41 1.42 // Compute loop trip count from profile data 1.43 compute_profile_trip_cnt(phase); 1.44 @@ -1633,11 +1634,11 @@ 1.45 // Here we did some unrolling and peeling. Eventually we will 1.46 // completely unroll this loop and it will no longer be a loop. 1.47 phase->do_maximally_unroll(this,old_new); 1.48 - return; 1.49 + return true; 1.50 } 1.51 if (should_unswitch) { 1.52 phase->do_unswitching(this, old_new); 1.53 - return; 1.54 + return true; 1.55 } 1.56 } 1.57 1.58 @@ -1698,14 +1699,16 @@ 1.59 if( should_peel ) // Might want to peel but do nothing else 1.60 phase->do_peeling(this,old_new); 1.61 } 1.62 + return true; 1.63 } 1.64 1.65 1.66 //============================================================================= 1.67 //------------------------------iteration_split-------------------------------- 1.68 -void IdealLoopTree::iteration_split( PhaseIdealLoop *phase, Node_List &old_new ) { 1.69 +bool IdealLoopTree::iteration_split( PhaseIdealLoop *phase, Node_List &old_new ) { 1.70 // Recursively iteration split nested loops 1.71 - if( _child ) _child->iteration_split( phase, old_new ); 1.72 + if( _child && !_child->iteration_split( phase, old_new )) 1.73 + return false; 1.74 1.75 // Clean out prior deadwood 1.76 DCE_loop_body(); 1.77 @@ -1727,7 +1730,9 @@ 1.78 _allow_optimizations && 1.79 !tail()->is_top() ) { // Also ignore the occasional dead backedge 1.80 if (!_has_call) { 1.81 - iteration_split_impl( phase, old_new ); 1.82 + if (!iteration_split_impl( phase, old_new )) { 1.83 + return false; 1.84 + } 1.85 } else if (policy_unswitching(phase)) { 1.86 phase->do_unswitching(this, old_new); 1.87 } 1.88 @@ -1736,5 +1741,7 @@ 1.89 // Minor offset re-organization to remove loop-fallout uses of 1.90 // trip counter. 1.91 if( _head->is_CountedLoop() ) phase->reorg_offsets( this ); 1.92 - if( _next ) _next->iteration_split( phase, old_new ); 1.93 + if( _next && !_next->iteration_split( phase, old_new )) 1.94 + return false; 1.95 + return true; 1.96 }
2.1 --- a/src/share/vm/opto/loopnode.hpp Thu Oct 02 08:37:44 2008 -0700 2.2 +++ b/src/share/vm/opto/loopnode.hpp Fri Oct 03 13:58:20 2008 -0700 2.3 @@ -325,12 +325,14 @@ 2.4 // Returns TRUE if loop tree is structurally changed. 2.5 bool beautify_loops( PhaseIdealLoop *phase ); 2.6 2.7 - // Perform iteration-splitting on inner loops. Split iterations to avoid 2.8 - // range checks or one-shot null checks. 2.9 - void iteration_split( PhaseIdealLoop *phase, Node_List &old_new ); 2.10 + // Perform iteration-splitting on inner loops. Split iterations to 2.11 + // avoid range checks or one-shot null checks. Returns false if the 2.12 + // current round of loop opts should stop. 2.13 + bool iteration_split( PhaseIdealLoop *phase, Node_List &old_new ); 2.14 2.15 - // Driver for various flavors of iteration splitting 2.16 - void iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_new ); 2.17 + // Driver for various flavors of iteration splitting. Returns false 2.18 + // if the current round of loop opts should stop. 2.19 + bool iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_new ); 2.20 2.21 // Given dominators, try to find loops with calls that must always be 2.22 // executed (call dominates loop tail). These loops do not need non-call
3.1 --- a/src/share/vm/opto/loopopts.cpp Thu Oct 02 08:37:44 2008 -0700 3.2 +++ b/src/share/vm/opto/loopopts.cpp Fri Oct 03 13:58:20 2008 -0700 3.3 @@ -1903,9 +1903,6 @@ 3.4 // Use in a phi is considered a use in the associated predecessor block 3.5 use_c = use->in(0)->in(j); 3.6 } 3.7 - if (use_c->is_CountedLoop()) { 3.8 - use_c = use_c->in(LoopNode::EntryControl); 3.9 - } 3.10 set_ctrl(n_clone, use_c); 3.11 assert(!loop->is_member(get_loop(use_c)), "should be outside loop"); 3.12 get_loop(use_c)->_body.push(n_clone);
4.1 --- a/test/compiler/6700047/Test6700047.java Thu Oct 02 08:37:44 2008 -0700 4.2 +++ b/test/compiler/6700047/Test6700047.java Fri Oct 03 13:58:20 2008 -0700 4.3 @@ -29,6 +29,8 @@ 4.4 */ 4.5 4.6 public class Test6700047 { 4.7 + static byte[] dummy = new byte[256]; 4.8 + 4.9 public static void main(String[] args) { 4.10 for (int i = 0; i < 100000; i++) { 4.11 intToLeftPaddedAsciiBytes(); 4.12 @@ -53,6 +55,7 @@ 4.13 if (offset > 0) { 4.14 for(int j = 0; j < offset; j++) { 4.15 result++; 4.16 + dummy[i] = 0; 4.17 } 4.18 } 4.19 return result;