# HG changeset patch # User never # Date 1223067500 25200 # Node ID ee8f06bfb27cc0fdc771280ac4f6d91908dbe7a1 # Parent cc80376deb0cecc278d2c431f125cbbf61c5a101 6743188: incomplete fix for 6700047 C2 failed in idom_no_update Reviewed-by: rasbold, kvn diff -r cc80376deb0c -r ee8f06bfb27c src/share/vm/opto/loopTransform.cpp --- a/src/share/vm/opto/loopTransform.cpp Thu Oct 02 08:37:44 2008 -0700 +++ b/src/share/vm/opto/loopTransform.cpp Fri Oct 03 13:58:20 2008 -0700 @@ -1590,10 +1590,10 @@ //============================================================================= //------------------------------iteration_split_impl--------------------------- -void IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_new ) { +bool IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_new ) { // Check and remove empty loops (spam micro-benchmarks) if( policy_do_remove_empty_loop(phase) ) - return; // Here we removed an empty loop + return true; // Here we removed an empty loop bool should_peel = policy_peeling(phase); // Should we peel? @@ -1603,7 +1603,8 @@ // This removes loop-invariant tests (usually null checks). if( !_head->is_CountedLoop() ) { // Non-counted loop if (PartialPeelLoop && phase->partial_peel(this, old_new)) { - return; + // Partial peel succeeded so terminate this round of loop opts + return false; } if( should_peel ) { // Should we peel? #ifndef PRODUCT @@ -1613,14 +1614,14 @@ } else if( should_unswitch ) { phase->do_unswitching(this, old_new); } - return; + return true; } CountedLoopNode *cl = _head->as_CountedLoop(); - if( !cl->loopexit() ) return; // Ignore various kinds of broken loops + if( !cl->loopexit() ) return true; // Ignore various kinds of broken loops // Do nothing special to pre- and post- loops - if( cl->is_pre_loop() || cl->is_post_loop() ) return; + if( cl->is_pre_loop() || cl->is_post_loop() ) return true; // Compute loop trip count from profile data compute_profile_trip_cnt(phase); @@ -1633,11 +1634,11 @@ // Here we did some unrolling and peeling. Eventually we will // completely unroll this loop and it will no longer be a loop. phase->do_maximally_unroll(this,old_new); - return; + return true; } if (should_unswitch) { phase->do_unswitching(this, old_new); - return; + return true; } } @@ -1698,14 +1699,16 @@ if( should_peel ) // Might want to peel but do nothing else phase->do_peeling(this,old_new); } + return true; } //============================================================================= //------------------------------iteration_split-------------------------------- -void IdealLoopTree::iteration_split( PhaseIdealLoop *phase, Node_List &old_new ) { +bool IdealLoopTree::iteration_split( PhaseIdealLoop *phase, Node_List &old_new ) { // Recursively iteration split nested loops - if( _child ) _child->iteration_split( phase, old_new ); + if( _child && !_child->iteration_split( phase, old_new )) + return false; // Clean out prior deadwood DCE_loop_body(); @@ -1727,7 +1730,9 @@ _allow_optimizations && !tail()->is_top() ) { // Also ignore the occasional dead backedge if (!_has_call) { - iteration_split_impl( phase, old_new ); + if (!iteration_split_impl( phase, old_new )) { + return false; + } } else if (policy_unswitching(phase)) { phase->do_unswitching(this, old_new); } @@ -1736,5 +1741,7 @@ // Minor offset re-organization to remove loop-fallout uses of // trip counter. if( _head->is_CountedLoop() ) phase->reorg_offsets( this ); - if( _next ) _next->iteration_split( phase, old_new ); + if( _next && !_next->iteration_split( phase, old_new )) + return false; + return true; } diff -r cc80376deb0c -r ee8f06bfb27c src/share/vm/opto/loopnode.hpp --- a/src/share/vm/opto/loopnode.hpp Thu Oct 02 08:37:44 2008 -0700 +++ b/src/share/vm/opto/loopnode.hpp Fri Oct 03 13:58:20 2008 -0700 @@ -325,12 +325,14 @@ // Returns TRUE if loop tree is structurally changed. bool beautify_loops( PhaseIdealLoop *phase ); - // Perform iteration-splitting on inner loops. Split iterations to avoid - // range checks or one-shot null checks. - void iteration_split( PhaseIdealLoop *phase, Node_List &old_new ); + // Perform iteration-splitting on inner loops. Split iterations to + // avoid range checks or one-shot null checks. Returns false if the + // current round of loop opts should stop. + bool iteration_split( PhaseIdealLoop *phase, Node_List &old_new ); - // Driver for various flavors of iteration splitting - void iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_new ); + // Driver for various flavors of iteration splitting. Returns false + // if the current round of loop opts should stop. + bool iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_new ); // Given dominators, try to find loops with calls that must always be // executed (call dominates loop tail). These loops do not need non-call diff -r cc80376deb0c -r ee8f06bfb27c src/share/vm/opto/loopopts.cpp --- a/src/share/vm/opto/loopopts.cpp Thu Oct 02 08:37:44 2008 -0700 +++ b/src/share/vm/opto/loopopts.cpp Fri Oct 03 13:58:20 2008 -0700 @@ -1903,9 +1903,6 @@ // Use in a phi is considered a use in the associated predecessor block use_c = use->in(0)->in(j); } - if (use_c->is_CountedLoop()) { - use_c = use_c->in(LoopNode::EntryControl); - } set_ctrl(n_clone, use_c); assert(!loop->is_member(get_loop(use_c)), "should be outside loop"); get_loop(use_c)->_body.push(n_clone); diff -r cc80376deb0c -r ee8f06bfb27c test/compiler/6700047/Test6700047.java --- a/test/compiler/6700047/Test6700047.java Thu Oct 02 08:37:44 2008 -0700 +++ b/test/compiler/6700047/Test6700047.java Fri Oct 03 13:58:20 2008 -0700 @@ -29,6 +29,8 @@ */ public class Test6700047 { + static byte[] dummy = new byte[256]; + public static void main(String[] args) { for (int i = 0; i < 100000; i++) { intToLeftPaddedAsciiBytes(); @@ -53,6 +55,7 @@ if (offset > 0) { for(int j = 0; j < offset; j++) { result++; + dummy[i] = 0; } } return result;