8072422: Cleanup: Remove some unused flags/code in loop optimizations
Remove unused flags, change test using them. Reviewed-by: kvn, twisti
This commit is contained in:
parent
fa667c5409
commit
69d14c811b
@ -229,21 +229,12 @@
|
|||||||
develop(bool, TraceLoopOpts, false, \
|
develop(bool, TraceLoopOpts, false, \
|
||||||
"Trace executed loop optimizations") \
|
"Trace executed loop optimizations") \
|
||||||
\
|
\
|
||||||
diagnostic(bool, LoopLimitCheck, true, \
|
|
||||||
"Generate a loop limits check for overflow") \
|
|
||||||
\
|
|
||||||
develop(bool, TraceLoopLimitCheck, false, \
|
develop(bool, TraceLoopLimitCheck, false, \
|
||||||
"Trace generation of loop limits checks") \
|
"Trace generation of loop limits checks") \
|
||||||
\
|
\
|
||||||
diagnostic(bool, RangeLimitCheck, true, \
|
|
||||||
"Additional overflow checks during range check elimination") \
|
|
||||||
\
|
|
||||||
develop(bool, TraceRangeLimitCheck, false, \
|
develop(bool, TraceRangeLimitCheck, false, \
|
||||||
"Trace additional overflow checks in RCE") \
|
"Trace additional overflow checks in RCE") \
|
||||||
\
|
\
|
||||||
diagnostic(bool, UnrollLimitCheck, true, \
|
|
||||||
"Additional overflow checks during loop unroll") \
|
|
||||||
\
|
|
||||||
/* OptimizeFill not yet supported on PowerPC. */ \
|
/* OptimizeFill not yet supported on PowerPC. */ \
|
||||||
product(bool, OptimizeFill, true PPC64_ONLY(&& false), \
|
product(bool, OptimizeFill, true PPC64_ONLY(&& false), \
|
||||||
"convert fill/copy loops into intrinsic") \
|
"convert fill/copy loops into intrinsic") \
|
||||||
|
@ -3773,9 +3773,7 @@ void GraphKit::add_predicate(int nargs) {
|
|||||||
add_predicate_impl(Deoptimization::Reason_predicate, nargs);
|
add_predicate_impl(Deoptimization::Reason_predicate, nargs);
|
||||||
}
|
}
|
||||||
// loop's limit check predicate should be near the loop.
|
// loop's limit check predicate should be near the loop.
|
||||||
if (LoopLimitCheck) {
|
|
||||||
add_predicate_impl(Deoptimization::Reason_loop_limit_check, nargs);
|
add_predicate_impl(Deoptimization::Reason_loop_limit_check, nargs);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------- store barriers ----------------------------
|
//----------------------------- store barriers ----------------------------
|
||||||
|
@ -313,12 +313,10 @@ Node* PhaseIdealLoop::clone_loop_predicates(Node* old_entry, Node* new_entry,
|
|||||||
// Search original predicates
|
// Search original predicates
|
||||||
Node* entry = old_entry;
|
Node* entry = old_entry;
|
||||||
ProjNode* limit_check_proj = NULL;
|
ProjNode* limit_check_proj = NULL;
|
||||||
if (LoopLimitCheck) {
|
|
||||||
limit_check_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
|
limit_check_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
|
||||||
if (limit_check_proj != NULL) {
|
if (limit_check_proj != NULL) {
|
||||||
entry = entry->in(0)->in(0);
|
entry = entry->in(0)->in(0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (UseLoopPredicate) {
|
if (UseLoopPredicate) {
|
||||||
ProjNode* predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
|
ProjNode* predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
|
||||||
if (predicate_proj != NULL) { // right pattern that can be used by loop predication
|
if (predicate_proj != NULL) { // right pattern that can be used by loop predication
|
||||||
@ -353,12 +351,10 @@ Node* PhaseIdealLoop::clone_loop_predicates(Node* old_entry, Node* new_entry,
|
|||||||
// Skip related predicates.
|
// Skip related predicates.
|
||||||
Node* PhaseIdealLoop::skip_loop_predicates(Node* entry) {
|
Node* PhaseIdealLoop::skip_loop_predicates(Node* entry) {
|
||||||
Node* predicate = NULL;
|
Node* predicate = NULL;
|
||||||
if (LoopLimitCheck) {
|
|
||||||
predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
|
predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
|
||||||
if (predicate != NULL) {
|
if (predicate != NULL) {
|
||||||
entry = entry->in(0)->in(0);
|
entry = entry->in(0)->in(0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (UseLoopPredicate) {
|
if (UseLoopPredicate) {
|
||||||
predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
|
predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
|
||||||
if (predicate != NULL) { // right pattern that can be used by loop predication
|
if (predicate != NULL) { // right pattern that can be used by loop predication
|
||||||
@ -393,12 +389,10 @@ ProjNode* PhaseIdealLoop::find_predicate_insertion_point(Node* start_c, Deoptimi
|
|||||||
// Find a predicate
|
// Find a predicate
|
||||||
Node* PhaseIdealLoop::find_predicate(Node* entry) {
|
Node* PhaseIdealLoop::find_predicate(Node* entry) {
|
||||||
Node* predicate = NULL;
|
Node* predicate = NULL;
|
||||||
if (LoopLimitCheck) {
|
|
||||||
predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
|
predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
|
||||||
if (predicate != NULL) { // right pattern that can be used by loop predication
|
if (predicate != NULL) { // right pattern that can be used by loop predication
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (UseLoopPredicate) {
|
if (UseLoopPredicate) {
|
||||||
predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
|
predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
|
||||||
if (predicate != NULL) { // right pattern that can be used by loop predication
|
if (predicate != NULL) { // right pattern that can be used by loop predication
|
||||||
@ -646,19 +640,13 @@ BoolNode* PhaseIdealLoop::rc_predicate(IdealLoopTree *loop, Node* ctrl,
|
|||||||
Node* max_idx_expr = init;
|
Node* max_idx_expr = init;
|
||||||
int stride_con = stride->get_int();
|
int stride_con = stride->get_int();
|
||||||
if ((stride_con > 0) == (scale > 0) == upper) {
|
if ((stride_con > 0) == (scale > 0) == upper) {
|
||||||
if (LoopLimitCheck) {
|
// Limit is not exact.
|
||||||
// With LoopLimitCheck limit is not exact.
|
|
||||||
// Calculate exact limit here.
|
// Calculate exact limit here.
|
||||||
// Note, counted loop's test is '<' or '>'.
|
// Note, counted loop's test is '<' or '>'.
|
||||||
limit = exact_limit(loop);
|
limit = exact_limit(loop);
|
||||||
max_idx_expr = new SubINode(limit, stride);
|
max_idx_expr = new SubINode(limit, stride);
|
||||||
register_new_node(max_idx_expr, ctrl);
|
register_new_node(max_idx_expr, ctrl);
|
||||||
if (TraceLoopPredicate) predString->print("(limit - stride) ");
|
if (TraceLoopPredicate) predString->print("(limit - stride) ");
|
||||||
} else {
|
|
||||||
max_idx_expr = new SubINode(limit, stride);
|
|
||||||
register_new_node(max_idx_expr, ctrl);
|
|
||||||
if (TraceLoopPredicate) predString->print("(limit - stride) ");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (TraceLoopPredicate) predString->print("init ");
|
if (TraceLoopPredicate) predString->print("init ");
|
||||||
}
|
}
|
||||||
@ -721,12 +709,9 @@ bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
|
|||||||
Node* entry = head->in(LoopNode::EntryControl);
|
Node* entry = head->in(LoopNode::EntryControl);
|
||||||
ProjNode *predicate_proj = NULL;
|
ProjNode *predicate_proj = NULL;
|
||||||
// Loop limit check predicate should be near the loop.
|
// Loop limit check predicate should be near the loop.
|
||||||
if (LoopLimitCheck) {
|
|
||||||
predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
|
predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
|
||||||
if (predicate_proj != NULL)
|
if (predicate_proj != NULL)
|
||||||
entry = predicate_proj->in(0)->in(0);
|
entry = predicate_proj->in(0)->in(0);
|
||||||
}
|
|
||||||
|
|
||||||
predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
|
predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
|
||||||
if (!predicate_proj) {
|
if (!predicate_proj) {
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
|
@ -1468,7 +1468,6 @@ void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool ad
|
|||||||
C->set_major_progress();
|
C->set_major_progress();
|
||||||
|
|
||||||
Node* new_limit = NULL;
|
Node* new_limit = NULL;
|
||||||
if (UnrollLimitCheck) {
|
|
||||||
int stride_con = stride->get_int();
|
int stride_con = stride->get_int();
|
||||||
int stride_p = (stride_con > 0) ? stride_con : -stride_con;
|
int stride_p = (stride_con > 0) ? stride_con : -stride_con;
|
||||||
uint old_trip_count = loop_head->trip_count();
|
uint old_trip_count = loop_head->trip_count();
|
||||||
@ -1620,58 +1619,6 @@ void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool ad
|
|||||||
// Double the count of original iterations in the unrolled loop body.
|
// Double the count of original iterations in the unrolled loop body.
|
||||||
loop_head->double_unrolled_count();
|
loop_head->double_unrolled_count();
|
||||||
|
|
||||||
} else { // LoopLimitCheck
|
|
||||||
|
|
||||||
// Adjust max trip count. The trip count is intentionally rounded
|
|
||||||
// down here (e.g. 15-> 7-> 3-> 1) because if we unwittingly over-unroll,
|
|
||||||
// the main, unrolled, part of the loop will never execute as it is protected
|
|
||||||
// by the min-trip test. See bug 4834191 for a case where we over-unrolled
|
|
||||||
// and later determined that part of the unrolled loop was dead.
|
|
||||||
loop_head->set_trip_count(loop_head->trip_count() / 2);
|
|
||||||
|
|
||||||
// Double the count of original iterations in the unrolled loop body.
|
|
||||||
loop_head->double_unrolled_count();
|
|
||||||
|
|
||||||
// -----------
|
|
||||||
// Step 2: Cut back the trip counter for an unroll amount of 2.
|
|
||||||
// Loop will normally trip (limit - init)/stride_con. Since it's a
|
|
||||||
// CountedLoop this is exact (stride divides limit-init exactly).
|
|
||||||
// We are going to double the loop body, so we want to knock off any
|
|
||||||
// odd iteration: (trip_cnt & ~1). Then back compute a new limit.
|
|
||||||
Node *span = new SubINode( limit, init );
|
|
||||||
register_new_node( span, ctrl );
|
|
||||||
Node *trip = new DivINode( 0, span, stride );
|
|
||||||
register_new_node( trip, ctrl );
|
|
||||||
Node *mtwo = _igvn.intcon(-2);
|
|
||||||
set_ctrl(mtwo, C->root());
|
|
||||||
Node *rond = new AndINode( trip, mtwo );
|
|
||||||
register_new_node( rond, ctrl );
|
|
||||||
Node *spn2 = new MulINode( rond, stride );
|
|
||||||
register_new_node( spn2, ctrl );
|
|
||||||
new_limit = new AddINode( spn2, init );
|
|
||||||
register_new_node( new_limit, ctrl );
|
|
||||||
|
|
||||||
// Hammer in the new limit
|
|
||||||
Node *ctrl2 = loop_end->in(0);
|
|
||||||
Node *cmp2 = new CmpINode( loop_head->incr(), new_limit );
|
|
||||||
register_new_node( cmp2, ctrl2 );
|
|
||||||
Node *bol2 = new BoolNode( cmp2, loop_end->test_trip() );
|
|
||||||
register_new_node( bol2, ctrl2 );
|
|
||||||
_igvn.replace_input_of(loop_end, CountedLoopEndNode::TestValue, bol2);
|
|
||||||
|
|
||||||
// Step 3: Find the min-trip test guaranteed before a 'main' loop.
|
|
||||||
// Make it a 1-trip test (means at least 2 trips).
|
|
||||||
if( adjust_min_trip ) {
|
|
||||||
assert( new_limit != NULL, "" );
|
|
||||||
// Guard test uses an 'opaque' node which is not shared. Hence I
|
|
||||||
// can edit it's inputs directly. Hammer in the new limit for the
|
|
||||||
// minimum-trip guard.
|
|
||||||
assert( opaq->outcnt() == 1, "" );
|
|
||||||
_igvn.hash_delete(opaq);
|
|
||||||
opaq->set_req(1, new_limit);
|
|
||||||
}
|
|
||||||
} // LoopLimitCheck
|
|
||||||
|
|
||||||
// ---------
|
// ---------
|
||||||
// Step 4: Clone the loop body. Move it inside the loop. This loop body
|
// Step 4: Clone the loop body. Move it inside the loop. This loop body
|
||||||
// represents the odd iterations; since the loop trips an even number of
|
// represents the odd iterations; since the loop trips an even number of
|
||||||
@ -1904,7 +1851,6 @@ void PhaseIdealLoop::add_constraint( int stride_con, int scale_con, Node *offset
|
|||||||
// )
|
// )
|
||||||
|
|
||||||
if (low_limit->get_int() == -max_jint) {
|
if (low_limit->get_int() == -max_jint) {
|
||||||
if (!RangeLimitCheck) return;
|
|
||||||
// We need this guard when scale*pre_limit+offset >= limit
|
// We need this guard when scale*pre_limit+offset >= limit
|
||||||
// due to underflow. So we need execute pre-loop until
|
// due to underflow. So we need execute pre-loop until
|
||||||
// scale*I+offset >= min_int. But (min_int-offset) will
|
// scale*I+offset >= min_int. But (min_int-offset) will
|
||||||
@ -1956,7 +1902,6 @@ void PhaseIdealLoop::add_constraint( int stride_con, int scale_con, Node *offset
|
|||||||
*pre_limit = adjust_limit((-stride_con), scale, plus_one, upper_limit, *pre_limit, pre_ctrl);
|
*pre_limit = adjust_limit((-stride_con), scale, plus_one, upper_limit, *pre_limit, pre_ctrl);
|
||||||
|
|
||||||
if (low_limit->get_int() == -max_jint) {
|
if (low_limit->get_int() == -max_jint) {
|
||||||
if (!RangeLimitCheck) return;
|
|
||||||
// We need this guard when scale*main_limit+offset >= limit
|
// We need this guard when scale*main_limit+offset >= limit
|
||||||
// due to underflow. So we need execute main-loop while
|
// due to underflow. So we need execute main-loop while
|
||||||
// scale*I+offset+1 > min_int. But (min_int-offset-1) will
|
// scale*I+offset+1 > min_int. But (min_int-offset-1) will
|
||||||
@ -2258,7 +2203,7 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
|
|||||||
add_constraint( stride_con, scale_con, offset, zero, limit, pre_ctrl, &pre_limit, &main_limit );
|
add_constraint( stride_con, scale_con, offset, zero, limit, pre_ctrl, &pre_limit, &main_limit );
|
||||||
if (!conditional_rc) {
|
if (!conditional_rc) {
|
||||||
// (0-offset)/scale could be outside of loop iterations range.
|
// (0-offset)/scale could be outside of loop iterations range.
|
||||||
conditional_rc = !loop->dominates_backedge(iff) || RangeLimitCheck;
|
conditional_rc = !loop->dominates_backedge(iff);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (PrintOpto) {
|
if (PrintOpto) {
|
||||||
@ -2294,7 +2239,7 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
|
|||||||
// ((MIN_INT+1)-offset)/scale could be outside of loop iterations range.
|
// ((MIN_INT+1)-offset)/scale could be outside of loop iterations range.
|
||||||
// Note: negative offset is replaced with 0 but (MIN_INT+1)/scale could
|
// Note: negative offset is replaced with 0 but (MIN_INT+1)/scale could
|
||||||
// still be outside of loop range.
|
// still be outside of loop range.
|
||||||
conditional_rc = !loop->dominates_backedge(iff) || RangeLimitCheck;
|
conditional_rc = !loop->dominates_backedge(iff);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -2340,26 +2285,6 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
|
|||||||
// Note:: we are making the main loop limit no longer precise;
|
// Note:: we are making the main loop limit no longer precise;
|
||||||
// need to round up based on stride.
|
// need to round up based on stride.
|
||||||
cl->set_nonexact_trip_count();
|
cl->set_nonexact_trip_count();
|
||||||
if (!LoopLimitCheck && stride_con != 1 && stride_con != -1) { // Cutout for common case
|
|
||||||
// "Standard" round-up logic: ([main_limit-init+(y-1)]/y)*y+init
|
|
||||||
// Hopefully, compiler will optimize for powers of 2.
|
|
||||||
Node *ctrl = get_ctrl(main_limit);
|
|
||||||
Node *stride = cl->stride();
|
|
||||||
Node *init = cl->init_trip()->uncast();
|
|
||||||
Node *span = new SubINode(main_limit,init);
|
|
||||||
register_new_node(span,ctrl);
|
|
||||||
Node *rndup = _igvn.intcon(stride_con + ((stride_con>0)?-1:1));
|
|
||||||
Node *add = new AddINode(span,rndup);
|
|
||||||
register_new_node(add,ctrl);
|
|
||||||
Node *div = new DivINode(0,add,stride);
|
|
||||||
register_new_node(div,ctrl);
|
|
||||||
Node *mul = new MulINode(div,stride);
|
|
||||||
register_new_node(mul,ctrl);
|
|
||||||
Node *newlim = new AddINode(mul,init);
|
|
||||||
register_new_node(newlim,ctrl);
|
|
||||||
main_limit = newlim;
|
|
||||||
}
|
|
||||||
|
|
||||||
Node *main_cle = cl->loopexit();
|
Node *main_cle = cl->loopexit();
|
||||||
Node *main_bol = main_cle->in(1);
|
Node *main_bol = main_cle->in(1);
|
||||||
// Hacking loop bounds; need private copies of exit test
|
// Hacking loop bounds; need private copies of exit test
|
||||||
|
@ -138,7 +138,7 @@ void PhaseIdealLoop::do_unswitching (IdealLoopTree *loop, Node_List &old_new) {
|
|||||||
Node* uniqc = proj_true->unique_ctrl_out();
|
Node* uniqc = proj_true->unique_ctrl_out();
|
||||||
Node* entry = head->in(LoopNode::EntryControl);
|
Node* entry = head->in(LoopNode::EntryControl);
|
||||||
Node* predicate = find_predicate(entry);
|
Node* predicate = find_predicate(entry);
|
||||||
if (predicate != NULL && LoopLimitCheck && UseLoopPredicate) {
|
if (predicate != NULL && UseLoopPredicate) {
|
||||||
// We may have two predicates, find first.
|
// We may have two predicates, find first.
|
||||||
entry = find_predicate(entry->in(0)->in(0));
|
entry = find_predicate(entry->in(0)->in(0));
|
||||||
if (entry != NULL) predicate = entry;
|
if (entry != NULL) predicate = entry;
|
||||||
|
@ -463,8 +463,6 @@ bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
|
|||||||
|
|
||||||
Node *hook = new Node(6);
|
Node *hook = new Node(6);
|
||||||
|
|
||||||
if (LoopLimitCheck) {
|
|
||||||
|
|
||||||
// ===================================================
|
// ===================================================
|
||||||
// Generate loop limit check to avoid integer overflow
|
// Generate loop limit check to avoid integer overflow
|
||||||
// in cases like next (cyclic loops):
|
// in cases like next (cyclic loops):
|
||||||
@ -593,103 +591,6 @@ bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
|
|||||||
}
|
}
|
||||||
set_subtree_ctrl( limit );
|
set_subtree_ctrl( limit );
|
||||||
|
|
||||||
} else { // LoopLimitCheck
|
|
||||||
|
|
||||||
// If compare points to incr, we are ok. Otherwise the compare
|
|
||||||
// can directly point to the phi; in this case adjust the compare so that
|
|
||||||
// it points to the incr by adjusting the limit.
|
|
||||||
if (cmp->in(1) == phi || cmp->in(2) == phi)
|
|
||||||
limit = gvn->transform(new AddINode(limit,stride));
|
|
||||||
|
|
||||||
// trip-count for +-tive stride should be: (limit - init_trip + stride - 1)/stride.
|
|
||||||
// Final value for iterator should be: trip_count * stride + init_trip.
|
|
||||||
Node *one_p = gvn->intcon( 1);
|
|
||||||
Node *one_m = gvn->intcon(-1);
|
|
||||||
|
|
||||||
Node *trip_count = NULL;
|
|
||||||
switch( bt ) {
|
|
||||||
case BoolTest::eq:
|
|
||||||
ShouldNotReachHere();
|
|
||||||
case BoolTest::ne: // Ahh, the case we desire
|
|
||||||
if (stride_con == 1)
|
|
||||||
trip_count = gvn->transform(new SubINode(limit,init_trip));
|
|
||||||
else if (stride_con == -1)
|
|
||||||
trip_count = gvn->transform(new SubINode(init_trip,limit));
|
|
||||||
else
|
|
||||||
ShouldNotReachHere();
|
|
||||||
set_subtree_ctrl(trip_count);
|
|
||||||
//_loop.map(trip_count->_idx,loop(limit));
|
|
||||||
break;
|
|
||||||
case BoolTest::le: // Maybe convert to '<' case
|
|
||||||
limit = gvn->transform(new AddINode(limit,one_p));
|
|
||||||
set_subtree_ctrl( limit );
|
|
||||||
hook->init_req(4, limit);
|
|
||||||
|
|
||||||
bt = BoolTest::lt;
|
|
||||||
// Make the new limit be in the same loop nest as the old limit
|
|
||||||
//_loop.map(limit->_idx,limit_loop);
|
|
||||||
// Fall into next case
|
|
||||||
case BoolTest::lt: { // Maybe convert to '!=' case
|
|
||||||
if (stride_con < 0) // Count down loop rolls through MAXINT
|
|
||||||
ShouldNotReachHere();
|
|
||||||
Node *range = gvn->transform(new SubINode(limit,init_trip));
|
|
||||||
set_subtree_ctrl( range );
|
|
||||||
hook->init_req(0, range);
|
|
||||||
|
|
||||||
Node *bias = gvn->transform(new AddINode(range,stride));
|
|
||||||
set_subtree_ctrl( bias );
|
|
||||||
hook->init_req(1, bias);
|
|
||||||
|
|
||||||
Node *bias1 = gvn->transform(new AddINode(bias,one_m));
|
|
||||||
set_subtree_ctrl( bias1 );
|
|
||||||
hook->init_req(2, bias1);
|
|
||||||
|
|
||||||
trip_count = gvn->transform(new DivINode(0,bias1,stride));
|
|
||||||
set_subtree_ctrl( trip_count );
|
|
||||||
hook->init_req(3, trip_count);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case BoolTest::ge: // Maybe convert to '>' case
|
|
||||||
limit = gvn->transform(new AddINode(limit,one_m));
|
|
||||||
set_subtree_ctrl( limit );
|
|
||||||
hook->init_req(4 ,limit);
|
|
||||||
|
|
||||||
bt = BoolTest::gt;
|
|
||||||
// Make the new limit be in the same loop nest as the old limit
|
|
||||||
//_loop.map(limit->_idx,limit_loop);
|
|
||||||
// Fall into next case
|
|
||||||
case BoolTest::gt: { // Maybe convert to '!=' case
|
|
||||||
if (stride_con > 0) // count up loop rolls through MININT
|
|
||||||
ShouldNotReachHere();
|
|
||||||
Node *range = gvn->transform(new SubINode(limit,init_trip));
|
|
||||||
set_subtree_ctrl( range );
|
|
||||||
hook->init_req(0, range);
|
|
||||||
|
|
||||||
Node *bias = gvn->transform(new AddINode(range,stride));
|
|
||||||
set_subtree_ctrl( bias );
|
|
||||||
hook->init_req(1, bias);
|
|
||||||
|
|
||||||
Node *bias1 = gvn->transform(new AddINode(bias,one_p));
|
|
||||||
set_subtree_ctrl( bias1 );
|
|
||||||
hook->init_req(2, bias1);
|
|
||||||
|
|
||||||
trip_count = gvn->transform(new DivINode(0,bias1,stride));
|
|
||||||
set_subtree_ctrl( trip_count );
|
|
||||||
hook->init_req(3, trip_count);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} // switch( bt )
|
|
||||||
|
|
||||||
Node *span = gvn->transform(new MulINode(trip_count,stride));
|
|
||||||
set_subtree_ctrl( span );
|
|
||||||
hook->init_req(5, span);
|
|
||||||
|
|
||||||
limit = gvn->transform(new AddINode(span,init_trip));
|
|
||||||
set_subtree_ctrl( limit );
|
|
||||||
|
|
||||||
} // LoopLimitCheck
|
|
||||||
|
|
||||||
if (!UseCountedLoopSafepoints) {
|
if (!UseCountedLoopSafepoints) {
|
||||||
// Check for SafePoint on backedge and remove
|
// Check for SafePoint on backedge and remove
|
||||||
Node *sfpt = x->in(LoopNode::LoopBackControl);
|
Node *sfpt = x->in(LoopNode::LoopBackControl);
|
||||||
@ -829,7 +730,7 @@ Node* PhaseIdealLoop::exact_limit( IdealLoopTree *loop ) {
|
|||||||
CountedLoopNode *cl = loop->_head->as_CountedLoop();
|
CountedLoopNode *cl = loop->_head->as_CountedLoop();
|
||||||
assert(cl->is_valid_counted_loop(), "");
|
assert(cl->is_valid_counted_loop(), "");
|
||||||
|
|
||||||
if (!LoopLimitCheck || ABS(cl->stride_con()) == 1 ||
|
if (ABS(cl->stride_con()) == 1 ||
|
||||||
cl->limit()->Opcode() == Op_LoopLimit) {
|
cl->limit()->Opcode() == Op_LoopLimit) {
|
||||||
// Old code has exact limit (it could be incorrect in case of int overflow).
|
// Old code has exact limit (it could be incorrect in case of int overflow).
|
||||||
// Loop limit is exact with stride == 1. And loop may already have exact limit.
|
// Loop limit is exact with stride == 1. And loop may already have exact limit.
|
||||||
@ -1897,13 +1798,11 @@ void IdealLoopTree::dump_head( ) const {
|
|||||||
tty->print("Loop: N%d/N%d ",_head->_idx,_tail->_idx);
|
tty->print("Loop: N%d/N%d ",_head->_idx,_tail->_idx);
|
||||||
if (_irreducible) tty->print(" IRREDUCIBLE");
|
if (_irreducible) tty->print(" IRREDUCIBLE");
|
||||||
Node* entry = _head->in(LoopNode::EntryControl);
|
Node* entry = _head->in(LoopNode::EntryControl);
|
||||||
if (LoopLimitCheck) {
|
|
||||||
Node* predicate = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
|
Node* predicate = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
|
||||||
if (predicate != NULL ) {
|
if (predicate != NULL ) {
|
||||||
tty->print(" limit_check");
|
tty->print(" limit_check");
|
||||||
entry = entry->in(0)->in(0);
|
entry = entry->in(0)->in(0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (UseLoopPredicate) {
|
if (UseLoopPredicate) {
|
||||||
entry = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
|
entry = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
|
||||||
if (entry != NULL) {
|
if (entry != NULL) {
|
||||||
@ -2322,7 +2221,7 @@ void PhaseIdealLoop::build_and_optimize(bool do_split_ifs, bool skip_loop_opts)
|
|||||||
// Some parser-inserted loop predicates could never be used by loop
|
// Some parser-inserted loop predicates could never be used by loop
|
||||||
// predication or they were moved away from loop during some optimizations.
|
// predication or they were moved away from loop during some optimizations.
|
||||||
// For example, peeling. Eliminate them before next loop optimizations.
|
// For example, peeling. Eliminate them before next loop optimizations.
|
||||||
if (UseLoopPredicate || LoopLimitCheck) {
|
if (UseLoopPredicate) {
|
||||||
eliminate_useless_predicates();
|
eliminate_useless_predicates();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -661,8 +661,7 @@ void Parse::do_all_blocks() {
|
|||||||
// (Note that dead locals do not get phis built, ever.)
|
// (Note that dead locals do not get phis built, ever.)
|
||||||
ensure_phis_everywhere();
|
ensure_phis_everywhere();
|
||||||
|
|
||||||
if (block->is_SEL_head() &&
|
if (block->is_SEL_head() && UseLoopPredicate) {
|
||||||
(UseLoopPredicate || LoopLimitCheck)) {
|
|
||||||
// Add predicate to single entry (not irreducible) loop head.
|
// Add predicate to single entry (not irreducible) loop head.
|
||||||
assert(!block->has_merged_backedge(), "only entry paths should be merged for now");
|
assert(!block->has_merged_backedge(), "only entry paths should be merged for now");
|
||||||
// Need correct bci for predicate.
|
// Need correct bci for predicate.
|
||||||
|
@ -26,10 +26,19 @@
|
|||||||
* @test
|
* @test
|
||||||
* @bug 8073184
|
* @bug 8073184
|
||||||
* @summary CastII that guards counted loops confuses range check elimination with LoopLimitCheck off
|
* @summary CastII that guards counted loops confuses range check elimination with LoopLimitCheck off
|
||||||
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:-LoopLimitCheck -XX:CompileOnly=TestCastIINoLoopLimitCheck.m -Xcomp TestCastIINoLoopLimitCheck
|
* @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:CompileOnly=TestCastIINoLoopLimitCheck.m -Xcomp TestCastIINoLoopLimitCheck
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The test was originally run with
|
||||||
|
*
|
||||||
|
* -XX:+UnlockDiagnosticVMOptions -XX:-LoopLimitCheck
|
||||||
|
*
|
||||||
|
* to trigger a problem with code guarded with !LoopLimitCheck.
|
||||||
|
* JDK-8072422 has removed that code but kept the test because the
|
||||||
|
* test generates an interesting graph shape.
|
||||||
|
*/
|
||||||
public class TestCastIINoLoopLimitCheck {
|
public class TestCastIINoLoopLimitCheck {
|
||||||
|
|
||||||
static void m(int i, int index, char[] buf) {
|
static void m(int i, int index, char[] buf) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user