mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-17 09:34:38 +02:00
6743188: incomplete fix for 6700047 C2 failed in idom_no_update
Reviewed-by: rasbold, kvn
This commit is contained in:
parent
adce6fc49a
commit
043fde10e5
4 changed files with 29 additions and 20 deletions
|
@ -1590,10 +1590,10 @@ bool IdealLoopTree::policy_do_remove_empty_loop( PhaseIdealLoop *phase ) {
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
//------------------------------iteration_split_impl---------------------------
|
//------------------------------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)
|
// Check and remove empty loops (spam micro-benchmarks)
|
||||||
if( policy_do_remove_empty_loop(phase) )
|
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?
|
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).
|
// This removes loop-invariant tests (usually null checks).
|
||||||
if( !_head->is_CountedLoop() ) { // Non-counted loop
|
if( !_head->is_CountedLoop() ) { // Non-counted loop
|
||||||
if (PartialPeelLoop && phase->partial_peel(this, old_new)) {
|
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?
|
if( should_peel ) { // Should we peel?
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
|
@ -1613,14 +1614,14 @@ void IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_
|
||||||
} else if( should_unswitch ) {
|
} else if( should_unswitch ) {
|
||||||
phase->do_unswitching(this, old_new);
|
phase->do_unswitching(this, old_new);
|
||||||
}
|
}
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
CountedLoopNode *cl = _head->as_CountedLoop();
|
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
|
// 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 loop trip count from profile data
|
||||||
compute_profile_trip_cnt(phase);
|
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
|
// Here we did some unrolling and peeling. Eventually we will
|
||||||
// completely unroll this loop and it will no longer be a loop.
|
// completely unroll this loop and it will no longer be a loop.
|
||||||
phase->do_maximally_unroll(this,old_new);
|
phase->do_maximally_unroll(this,old_new);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
if (should_unswitch) {
|
if (should_unswitch) {
|
||||||
phase->do_unswitching(this, old_new);
|
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
|
if( should_peel ) // Might want to peel but do nothing else
|
||||||
phase->do_peeling(this,old_new);
|
phase->do_peeling(this,old_new);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
//------------------------------iteration_split--------------------------------
|
//------------------------------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
|
// 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
|
// Clean out prior deadwood
|
||||||
DCE_loop_body();
|
DCE_loop_body();
|
||||||
|
@ -1727,7 +1730,9 @@ void IdealLoopTree::iteration_split( PhaseIdealLoop *phase, Node_List &old_new )
|
||||||
_allow_optimizations &&
|
_allow_optimizations &&
|
||||||
!tail()->is_top() ) { // Also ignore the occasional dead backedge
|
!tail()->is_top() ) { // Also ignore the occasional dead backedge
|
||||||
if (!_has_call) {
|
if (!_has_call) {
|
||||||
iteration_split_impl( phase, old_new );
|
if (!iteration_split_impl( phase, old_new )) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} else if (policy_unswitching(phase)) {
|
} else if (policy_unswitching(phase)) {
|
||||||
phase->do_unswitching(this, old_new);
|
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
|
// Minor offset re-organization to remove loop-fallout uses of
|
||||||
// trip counter.
|
// trip counter.
|
||||||
if( _head->is_CountedLoop() ) phase->reorg_offsets( this );
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -325,12 +325,14 @@ public:
|
||||||
// Returns TRUE if loop tree is structurally changed.
|
// Returns TRUE if loop tree is structurally changed.
|
||||||
bool beautify_loops( PhaseIdealLoop *phase );
|
bool beautify_loops( PhaseIdealLoop *phase );
|
||||||
|
|
||||||
// Perform iteration-splitting on inner loops. Split iterations to avoid
|
// Perform iteration-splitting on inner loops. Split iterations to
|
||||||
// range checks or one-shot null checks.
|
// avoid range checks or one-shot null checks. Returns false if the
|
||||||
void iteration_split( PhaseIdealLoop *phase, Node_List &old_new );
|
// current round of loop opts should stop.
|
||||||
|
bool iteration_split( PhaseIdealLoop *phase, Node_List &old_new );
|
||||||
|
|
||||||
// Driver for various flavors of iteration splitting
|
// Driver for various flavors of iteration splitting. Returns false
|
||||||
void iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_new );
|
// 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
|
// Given dominators, try to find loops with calls that must always be
|
||||||
// executed (call dominates loop tail). These loops do not need non-call
|
// executed (call dominates loop tail). These loops do not need non-call
|
||||||
|
|
|
@ -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 in a phi is considered a use in the associated predecessor block
|
||||||
use_c = use->in(0)->in(j);
|
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);
|
set_ctrl(n_clone, use_c);
|
||||||
assert(!loop->is_member(get_loop(use_c)), "should be outside loop");
|
assert(!loop->is_member(get_loop(use_c)), "should be outside loop");
|
||||||
get_loop(use_c)->_body.push(n_clone);
|
get_loop(use_c)->_body.push(n_clone);
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class Test6700047 {
|
public class Test6700047 {
|
||||||
|
static byte[] dummy = new byte[256];
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
for (int i = 0; i < 100000; i++) {
|
for (int i = 0; i < 100000; i++) {
|
||||||
intToLeftPaddedAsciiBytes();
|
intToLeftPaddedAsciiBytes();
|
||||||
|
@ -53,6 +55,7 @@ public class Test6700047 {
|
||||||
if (offset > 0) {
|
if (offset > 0) {
|
||||||
for(int j = 0; j < offset; j++) {
|
for(int j = 0; j < offset; j++) {
|
||||||
result++;
|
result++;
|
||||||
|
dummy[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue