diff --git a/src/share/vm/opto/loopTransform.cpp b/src/share/vm/opto/loopTransform.cpp index 60e21500048bd1699e69b5560d2a84556fa3e758..f1c15b08344bb89896ae2add99a2a21e74edf332 100644 --- a/src/share/vm/opto/loopTransform.cpp +++ b/src/share/vm/opto/loopTransform.cpp @@ -1590,10 +1590,10 @@ bool IdealLoopTree::policy_do_remove_empty_loop( PhaseIdealLoop *phase ) { //============================================================================= //------------------------------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 @@ void IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_ // 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 @@ void IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_ } 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 @@ void IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_ // 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 @@ void IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_ 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 @@ void IdealLoopTree::iteration_split( PhaseIdealLoop *phase, Node_List &old_new ) _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 @@ void IdealLoopTree::iteration_split( PhaseIdealLoop *phase, Node_List &old_new ) // 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 --git a/src/share/vm/opto/loopnode.hpp b/src/share/vm/opto/loopnode.hpp index 968cf8653650baa7e5728667522962200e153fd7..5377564669622e3b5b330198f7ecbdf5e6aabb58 100644 --- a/src/share/vm/opto/loopnode.hpp +++ b/src/share/vm/opto/loopnode.hpp @@ -325,12 +325,14 @@ public: // 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 ); - - // Driver for various flavors of iteration splitting - void iteration_split_impl( 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. 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 --git a/src/share/vm/opto/loopopts.cpp b/src/share/vm/opto/loopopts.cpp index e0f55603b7a7863d4ab922fe7950d03485a884c7..41048cbcbe9e19f4c54a964deb5e8513f19bf9d9 100644 --- a/src/share/vm/opto/loopopts.cpp +++ b/src/share/vm/opto/loopopts.cpp @@ -1903,9 +1903,6 @@ void PhaseIdealLoop::clone_for_use_outside_loop( IdealLoopTree *loop, Node* n, N // 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 --git a/test/compiler/6700047/Test6700047.java b/test/compiler/6700047/Test6700047.java index 55921d59465972c4ac9fcb7cfce56996a31ae298..64e6ddb19330cd416e97ea4c055da9fd9eb5e4c7 100644 --- a/test/compiler/6700047/Test6700047.java +++ b/test/compiler/6700047/Test6700047.java @@ -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 @@ public class Test6700047 { if (offset > 0) { for(int j = 0; j < offset; j++) { result++; + dummy[i] = 0; } } return result;