# HG changeset patch # User thartmann # Date 1459851067 0 # Node ID 8604d4659ceee1298bea1243a7708ba4ea375104 # Parent 9989add27bf4fcb8a761687997e12b888af161bb# Parent a31d47bbbdf635687a69b68215a742738a10abd0 Merge diff -r 9989add27bf4 -r 8604d4659cee hotspot/src/share/vm/opto/c2_globals.hpp --- a/hotspot/src/share/vm/opto/c2_globals.hpp Tue Apr 05 01:46:40 2016 -0700 +++ b/hotspot/src/share/vm/opto/c2_globals.hpp Tue Apr 05 10:11:07 2016 +0000 @@ -229,21 +229,12 @@ develop(bool, TraceLoopOpts, false, \ "Trace executed loop optimizations") \ \ - diagnostic(bool, LoopLimitCheck, true, \ - "Generate a loop limits check for overflow") \ - \ develop(bool, TraceLoopLimitCheck, false, \ "Trace generation of loop limits checks") \ \ - diagnostic(bool, RangeLimitCheck, true, \ - "Additional overflow checks during range check elimination") \ - \ develop(bool, TraceRangeLimitCheck, false, \ "Trace additional overflow checks in RCE") \ \ - diagnostic(bool, UnrollLimitCheck, true, \ - "Additional overflow checks during loop unroll") \ - \ /* OptimizeFill not yet supported on PowerPC. */ \ product(bool, OptimizeFill, true PPC64_ONLY(&& false), \ "convert fill/copy loops into intrinsic") \ diff -r 9989add27bf4 -r 8604d4659cee hotspot/src/share/vm/opto/graphKit.cpp --- a/hotspot/src/share/vm/opto/graphKit.cpp Tue Apr 05 01:46:40 2016 -0700 +++ b/hotspot/src/share/vm/opto/graphKit.cpp Tue Apr 05 10:11:07 2016 +0000 @@ -3773,9 +3773,7 @@ add_predicate_impl(Deoptimization::Reason_predicate, nargs); } // 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 ---------------------------- diff -r 9989add27bf4 -r 8604d4659cee hotspot/src/share/vm/opto/loopPredicate.cpp --- a/hotspot/src/share/vm/opto/loopPredicate.cpp Tue Apr 05 01:46:40 2016 -0700 +++ b/hotspot/src/share/vm/opto/loopPredicate.cpp Tue Apr 05 10:11:07 2016 +0000 @@ -313,11 +313,9 @@ // Search original predicates Node* entry = old_entry; ProjNode* limit_check_proj = NULL; - if (LoopLimitCheck) { - limit_check_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check); - if (limit_check_proj != NULL) { - entry = entry->in(0)->in(0); - } + limit_check_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check); + if (limit_check_proj != NULL) { + entry = entry->in(0)->in(0); } if (UseLoopPredicate) { ProjNode* predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate); @@ -353,11 +351,9 @@ // Skip related predicates. Node* PhaseIdealLoop::skip_loop_predicates(Node* entry) { Node* predicate = NULL; - if (LoopLimitCheck) { - predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check); - if (predicate != NULL) { - entry = entry->in(0)->in(0); - } + predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check); + if (predicate != NULL) { + entry = entry->in(0)->in(0); } if (UseLoopPredicate) { predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate); @@ -393,11 +389,9 @@ // Find a predicate Node* PhaseIdealLoop::find_predicate(Node* entry) { Node* predicate = NULL; - if (LoopLimitCheck) { - predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check); - if (predicate != NULL) { // right pattern that can be used by loop predication - return entry; - } + predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check); + if (predicate != NULL) { // right pattern that can be used by loop predication + return entry; } if (UseLoopPredicate) { predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate); @@ -646,19 +640,13 @@ Node* max_idx_expr = init; int stride_con = stride->get_int(); if ((stride_con > 0) == (scale > 0) == upper) { - if (LoopLimitCheck) { - // With LoopLimitCheck limit is not exact. - // Calculate exact limit here. - // Note, counted loop's test is '<' or '>'. - limit = exact_limit(loop); - max_idx_expr = new SubINode(limit, stride); - register_new_node(max_idx_expr, ctrl); - 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) "); - } + // Limit is not exact. + // Calculate exact limit here. + // Note, counted loop's test is '<' or '>'. + limit = exact_limit(loop); + max_idx_expr = new SubINode(limit, stride); + register_new_node(max_idx_expr, ctrl); + if (TraceLoopPredicate) predString->print("(limit - stride) "); } else { if (TraceLoopPredicate) predString->print("init "); } @@ -721,12 +709,9 @@ Node* entry = head->in(LoopNode::EntryControl); ProjNode *predicate_proj = NULL; // Loop limit check predicate should be near the loop. - if (LoopLimitCheck) { - predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check); - if (predicate_proj != NULL) - entry = predicate_proj->in(0)->in(0); - } - + predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check); + if (predicate_proj != NULL) + entry = predicate_proj->in(0)->in(0); predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate); if (!predicate_proj) { #ifndef PRODUCT diff -r 9989add27bf4 -r 8604d4659cee hotspot/src/share/vm/opto/loopTransform.cpp --- a/hotspot/src/share/vm/opto/loopTransform.cpp Tue Apr 05 01:46:40 2016 -0700 +++ b/hotspot/src/share/vm/opto/loopTransform.cpp Tue Apr 05 10:11:07 2016 +0000 @@ -1468,209 +1468,156 @@ C->set_major_progress(); Node* new_limit = NULL; - if (UnrollLimitCheck) { - int stride_con = stride->get_int(); - int stride_p = (stride_con > 0) ? stride_con : -stride_con; - uint old_trip_count = loop_head->trip_count(); - // Verify that unroll policy result is still valid. - assert(old_trip_count > 1 && - (!adjust_min_trip || stride_p <= (1<<3)*loop_head->unrolled_count()), "sanity"); + int stride_con = stride->get_int(); + int stride_p = (stride_con > 0) ? stride_con : -stride_con; + uint old_trip_count = loop_head->trip_count(); + // Verify that unroll policy result is still valid. + assert(old_trip_count > 1 && + (!adjust_min_trip || stride_p <= (1<<3)*loop_head->unrolled_count()), "sanity"); - // Adjust loop limit to keep valid iterations number after unroll. - // Use (limit - stride) instead of (((limit - init)/stride) & (-2))*stride - // which may overflow. - if (!adjust_min_trip) { - assert(old_trip_count > 1 && (old_trip_count & 1) == 0, - "odd trip count for maximally unroll"); - // Don't need to adjust limit for maximally unroll since trip count is even. - } else if (loop_head->has_exact_trip_count() && init->is_Con()) { - // Loop's limit is constant. Loop's init could be constant when pre-loop - // become peeled iteration. - jlong init_con = init->get_int(); - // We can keep old loop limit if iterations count stays the same: - // old_trip_count == new_trip_count * 2 - // Note: since old_trip_count >= 2 then new_trip_count >= 1 - // so we also don't need to adjust zero trip test. - jlong limit_con = limit->get_int(); - // (stride_con*2) not overflow since stride_con <= 8. - int new_stride_con = stride_con * 2; - int stride_m = new_stride_con - (stride_con > 0 ? 1 : -1); - jlong trip_count = (limit_con - init_con + stride_m)/new_stride_con; - // New trip count should satisfy next conditions. - assert(trip_count > 0 && (julong)trip_count < (julong)max_juint/2, "sanity"); - uint new_trip_count = (uint)trip_count; - adjust_min_trip = (old_trip_count != new_trip_count*2); - } + // Adjust loop limit to keep valid iterations number after unroll. + // Use (limit - stride) instead of (((limit - init)/stride) & (-2))*stride + // which may overflow. + if (!adjust_min_trip) { + assert(old_trip_count > 1 && (old_trip_count & 1) == 0, + "odd trip count for maximally unroll"); + // Don't need to adjust limit for maximally unroll since trip count is even. + } else if (loop_head->has_exact_trip_count() && init->is_Con()) { + // Loop's limit is constant. Loop's init could be constant when pre-loop + // become peeled iteration. + jlong init_con = init->get_int(); + // We can keep old loop limit if iterations count stays the same: + // old_trip_count == new_trip_count * 2 + // Note: since old_trip_count >= 2 then new_trip_count >= 1 + // so we also don't need to adjust zero trip test. + jlong limit_con = limit->get_int(); + // (stride_con*2) not overflow since stride_con <= 8. + int new_stride_con = stride_con * 2; + int stride_m = new_stride_con - (stride_con > 0 ? 1 : -1); + jlong trip_count = (limit_con - init_con + stride_m)/new_stride_con; + // New trip count should satisfy next conditions. + assert(trip_count > 0 && (julong)trip_count < (julong)max_juint/2, "sanity"); + uint new_trip_count = (uint)trip_count; + adjust_min_trip = (old_trip_count != new_trip_count*2); + } + + if (adjust_min_trip) { + // Step 2: Adjust the trip limit if it is called for. + // The adjustment amount is -stride. Need to make sure if the + // adjustment underflows or overflows, then the main loop is skipped. + Node* cmp = loop_end->cmp_node(); + assert(cmp->in(2) == limit, "sanity"); + assert(opaq != NULL && opaq->in(1) == limit, "sanity"); + + // Verify that policy_unroll result is still valid. + const TypeInt* limit_type = _igvn.type(limit)->is_int(); + assert(stride_con > 0 && ((limit_type->_hi - stride_con) < limit_type->_hi) || + stride_con < 0 && ((limit_type->_lo - stride_con) > limit_type->_lo), "sanity"); - if (adjust_min_trip) { - // Step 2: Adjust the trip limit if it is called for. - // The adjustment amount is -stride. Need to make sure if the - // adjustment underflows or overflows, then the main loop is skipped. - Node* cmp = loop_end->cmp_node(); - assert(cmp->in(2) == limit, "sanity"); - assert(opaq != NULL && opaq->in(1) == limit, "sanity"); - - // Verify that policy_unroll result is still valid. - const TypeInt* limit_type = _igvn.type(limit)->is_int(); - assert(stride_con > 0 && ((limit_type->_hi - stride_con) < limit_type->_hi) || - stride_con < 0 && ((limit_type->_lo - stride_con) > limit_type->_lo), "sanity"); - - if (limit->is_Con()) { - // The check in policy_unroll and the assert above guarantee - // no underflow if limit is constant. - new_limit = _igvn.intcon(limit->get_int() - stride_con); - set_ctrl(new_limit, C->root()); + if (limit->is_Con()) { + // The check in policy_unroll and the assert above guarantee + // no underflow if limit is constant. + new_limit = _igvn.intcon(limit->get_int() - stride_con); + set_ctrl(new_limit, C->root()); + } else { + // Limit is not constant. + if (loop_head->unrolled_count() == 1) { // only for first unroll + // Separate limit by Opaque node in case it is an incremented + // variable from previous loop to avoid using pre-incremented + // value which could increase register pressure. + // Otherwise reorg_offsets() optimization will create a separate + // Opaque node for each use of trip-counter and as result + // zero trip guard limit will be different from loop limit. + assert(has_ctrl(opaq), "should have it"); + Node* opaq_ctrl = get_ctrl(opaq); + limit = new Opaque2Node( C, limit ); + register_new_node( limit, opaq_ctrl ); + } + if (stride_con > 0 && (java_subtract(limit_type->_lo, stride_con) < limit_type->_lo) || + stride_con < 0 && (java_subtract(limit_type->_hi, stride_con) > limit_type->_hi)) { + // No underflow. + new_limit = new SubINode(limit, stride); } else { - // Limit is not constant. - if (loop_head->unrolled_count() == 1) { // only for first unroll - // Separate limit by Opaque node in case it is an incremented - // variable from previous loop to avoid using pre-incremented - // value which could increase register pressure. - // Otherwise reorg_offsets() optimization will create a separate - // Opaque node for each use of trip-counter and as result - // zero trip guard limit will be different from loop limit. - assert(has_ctrl(opaq), "should have it"); - Node* opaq_ctrl = get_ctrl(opaq); - limit = new Opaque2Node( C, limit ); - register_new_node( limit, opaq_ctrl ); - } - if (stride_con > 0 && (java_subtract(limit_type->_lo, stride_con) < limit_type->_lo) || - stride_con < 0 && (java_subtract(limit_type->_hi, stride_con) > limit_type->_hi)) { - // No underflow. - new_limit = new SubINode(limit, stride); + // (limit - stride) may underflow. + // Clamp the adjustment value with MININT or MAXINT: + // + // new_limit = limit-stride + // if (stride > 0) + // new_limit = (limit < new_limit) ? MININT : new_limit; + // else + // new_limit = (limit > new_limit) ? MAXINT : new_limit; + // + BoolTest::mask bt = loop_end->test_trip(); + assert(bt == BoolTest::lt || bt == BoolTest::gt, "canonical test is expected"); + Node* adj_max = _igvn.intcon((stride_con > 0) ? min_jint : max_jint); + set_ctrl(adj_max, C->root()); + Node* old_limit = NULL; + Node* adj_limit = NULL; + Node* bol = limit->is_CMove() ? limit->in(CMoveNode::Condition) : NULL; + if (loop_head->unrolled_count() > 1 && + limit->is_CMove() && limit->Opcode() == Op_CMoveI && + limit->in(CMoveNode::IfTrue) == adj_max && + bol->as_Bool()->_test._test == bt && + bol->in(1)->Opcode() == Op_CmpI && + bol->in(1)->in(2) == limit->in(CMoveNode::IfFalse)) { + // Loop was unrolled before. + // Optimize the limit to avoid nested CMove: + // use original limit as old limit. + old_limit = bol->in(1)->in(1); + // Adjust previous adjusted limit. + adj_limit = limit->in(CMoveNode::IfFalse); + adj_limit = new SubINode(adj_limit, stride); } else { - // (limit - stride) may underflow. - // Clamp the adjustment value with MININT or MAXINT: - // - // new_limit = limit-stride - // if (stride > 0) - // new_limit = (limit < new_limit) ? MININT : new_limit; - // else - // new_limit = (limit > new_limit) ? MAXINT : new_limit; - // - BoolTest::mask bt = loop_end->test_trip(); - assert(bt == BoolTest::lt || bt == BoolTest::gt, "canonical test is expected"); - Node* adj_max = _igvn.intcon((stride_con > 0) ? min_jint : max_jint); - set_ctrl(adj_max, C->root()); - Node* old_limit = NULL; - Node* adj_limit = NULL; - Node* bol = limit->is_CMove() ? limit->in(CMoveNode::Condition) : NULL; - if (loop_head->unrolled_count() > 1 && - limit->is_CMove() && limit->Opcode() == Op_CMoveI && - limit->in(CMoveNode::IfTrue) == adj_max && - bol->as_Bool()->_test._test == bt && - bol->in(1)->Opcode() == Op_CmpI && - bol->in(1)->in(2) == limit->in(CMoveNode::IfFalse)) { - // Loop was unrolled before. - // Optimize the limit to avoid nested CMove: - // use original limit as old limit. - old_limit = bol->in(1)->in(1); - // Adjust previous adjusted limit. - adj_limit = limit->in(CMoveNode::IfFalse); - adj_limit = new SubINode(adj_limit, stride); - } else { - old_limit = limit; - adj_limit = new SubINode(limit, stride); - } - assert(old_limit != NULL && adj_limit != NULL, ""); - register_new_node( adj_limit, ctrl ); // adjust amount - Node* adj_cmp = new CmpINode(old_limit, adj_limit); - register_new_node( adj_cmp, ctrl ); - Node* adj_bool = new BoolNode(adj_cmp, bt); - register_new_node( adj_bool, ctrl ); - new_limit = new CMoveINode(adj_bool, adj_limit, adj_max, TypeInt::INT); + old_limit = limit; + adj_limit = new SubINode(limit, stride); } - register_new_node(new_limit, ctrl); + assert(old_limit != NULL && adj_limit != NULL, ""); + register_new_node( adj_limit, ctrl ); // adjust amount + Node* adj_cmp = new CmpINode(old_limit, adj_limit); + register_new_node( adj_cmp, ctrl ); + Node* adj_bool = new BoolNode(adj_cmp, bt); + register_new_node( adj_bool, ctrl ); + new_limit = new CMoveINode(adj_bool, adj_limit, adj_max, TypeInt::INT); } - assert(new_limit != NULL, ""); - // Replace in loop test. - assert(loop_end->in(1)->in(1) == cmp, "sanity"); - if (cmp->outcnt() == 1 && loop_end->in(1)->outcnt() == 1) { - // Don't need to create new test since only one user. - _igvn.hash_delete(cmp); - cmp->set_req(2, new_limit); - } else { - // Create new test since it is shared. - Node* ctrl2 = loop_end->in(0); - Node* cmp2 = cmp->clone(); - cmp2->set_req(2, new_limit); - register_new_node(cmp2, ctrl2); - Node* bol2 = loop_end->in(1)->clone(); - bol2->set_req(1, cmp2); - register_new_node(bol2, ctrl2); - _igvn.replace_input_of(loop_end, 1, bol2); - } - // Step 3: Find the min-trip test guaranteed before a 'main' loop. - // Make it a 1-trip test (means at least 2 trips). - - // 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.replace_input_of(opaq, 1, new_limit); + register_new_node(new_limit, ctrl); } - - // 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(old_trip_count / 2); - - // Double the count of original iterations in the unrolled loop body. - 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); - + assert(new_limit != NULL, ""); + // Replace in loop test. + assert(loop_end->in(1)->in(1) == cmp, "sanity"); + if (cmp->outcnt() == 1 && loop_end->in(1)->outcnt() == 1) { + // Don't need to create new test since only one user. + _igvn.hash_delete(cmp); + cmp->set_req(2, new_limit); + } else { + // Create new test since it is shared. + Node* ctrl2 = loop_end->in(0); + Node* cmp2 = cmp->clone(); + cmp2->set_req(2, new_limit); + register_new_node(cmp2, ctrl2); + Node* bol2 = loop_end->in(1)->clone(); + bol2->set_req(1, cmp2); + register_new_node(bol2, ctrl2); + _igvn.replace_input_of(loop_end, 1, 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 + + // 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.replace_input_of(opaq, 1, new_limit); + } + + // 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(old_trip_count / 2); + + // Double the count of original iterations in the unrolled loop body. + loop_head->double_unrolled_count(); // --------- // Step 4: Clone the loop body. Move it inside the loop. This loop body @@ -1904,7 +1851,6 @@ // ) if (low_limit->get_int() == -max_jint) { - if (!RangeLimitCheck) return; // We need this guard when scale*pre_limit+offset >= limit // due to underflow. So we need execute pre-loop until // scale*I+offset >= min_int. But (min_int-offset) will @@ -1956,7 +1902,6 @@ *pre_limit = adjust_limit((-stride_con), scale, plus_one, upper_limit, *pre_limit, pre_ctrl); if (low_limit->get_int() == -max_jint) { - if (!RangeLimitCheck) return; // We need this guard when scale*main_limit+offset >= limit // due to underflow. So we need execute main-loop while // scale*I+offset+1 > min_int. But (min_int-offset-1) will @@ -2258,7 +2203,7 @@ add_constraint( stride_con, scale_con, offset, zero, limit, pre_ctrl, &pre_limit, &main_limit ); if (!conditional_rc) { // (0-offset)/scale could be outside of loop iterations range. - conditional_rc = !loop->dominates_backedge(iff) || RangeLimitCheck; + conditional_rc = !loop->dominates_backedge(iff); } } else { if (PrintOpto) { @@ -2294,7 +2239,7 @@ // ((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 // still be outside of loop range. - conditional_rc = !loop->dominates_backedge(iff) || RangeLimitCheck; + conditional_rc = !loop->dominates_backedge(iff); } break; default: @@ -2340,26 +2285,6 @@ // Note:: we are making the main loop limit no longer precise; // need to round up based on stride. 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_bol = main_cle->in(1); // Hacking loop bounds; need private copies of exit test diff -r 9989add27bf4 -r 8604d4659cee hotspot/src/share/vm/opto/loopUnswitch.cpp --- a/hotspot/src/share/vm/opto/loopUnswitch.cpp Tue Apr 05 01:46:40 2016 -0700 +++ b/hotspot/src/share/vm/opto/loopUnswitch.cpp Tue Apr 05 10:11:07 2016 +0000 @@ -138,7 +138,7 @@ Node* uniqc = proj_true->unique_ctrl_out(); Node* entry = head->in(LoopNode::EntryControl); Node* predicate = find_predicate(entry); - if (predicate != NULL && LoopLimitCheck && UseLoopPredicate) { + if (predicate != NULL && UseLoopPredicate) { // We may have two predicates, find first. entry = find_predicate(entry->in(0)->in(0)); if (entry != NULL) predicate = entry; diff -r 9989add27bf4 -r 8604d4659cee hotspot/src/share/vm/opto/loopnode.cpp --- a/hotspot/src/share/vm/opto/loopnode.cpp Tue Apr 05 01:46:40 2016 -0700 +++ b/hotspot/src/share/vm/opto/loopnode.cpp Tue Apr 05 10:11:07 2016 +0000 @@ -463,8 +463,6 @@ Node *hook = new Node(6); - if (LoopLimitCheck) { - // =================================================== // Generate loop limit check to avoid integer overflow // in cases like next (cyclic loops): @@ -593,103 +591,6 @@ } 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) { // Check for SafePoint on backedge and remove Node *sfpt = x->in(LoopNode::LoopBackControl); @@ -829,7 +730,7 @@ CountedLoopNode *cl = loop->_head->as_CountedLoop(); assert(cl->is_valid_counted_loop(), ""); - if (!LoopLimitCheck || ABS(cl->stride_con()) == 1 || + if (ABS(cl->stride_con()) == 1 || cl->limit()->Opcode() == Op_LoopLimit) { // 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. @@ -1897,12 +1798,10 @@ tty->print("Loop: N%d/N%d ",_head->_idx,_tail->_idx); if (_irreducible) tty->print(" IRREDUCIBLE"); Node* entry = _head->in(LoopNode::EntryControl); - if (LoopLimitCheck) { - Node* predicate = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check); - if (predicate != NULL ) { - tty->print(" limit_check"); - entry = entry->in(0)->in(0); - } + Node* predicate = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check); + if (predicate != NULL ) { + tty->print(" limit_check"); + entry = entry->in(0)->in(0); } if (UseLoopPredicate) { entry = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_predicate); @@ -2322,7 +2221,7 @@ // Some parser-inserted loop predicates could never be used by loop // predication or they were moved away from loop during some optimizations. // For example, peeling. Eliminate them before next loop optimizations. - if (UseLoopPredicate || LoopLimitCheck) { + if (UseLoopPredicate) { eliminate_useless_predicates(); } diff -r 9989add27bf4 -r 8604d4659cee hotspot/src/share/vm/opto/parse1.cpp --- a/hotspot/src/share/vm/opto/parse1.cpp Tue Apr 05 01:46:40 2016 -0700 +++ b/hotspot/src/share/vm/opto/parse1.cpp Tue Apr 05 10:11:07 2016 +0000 @@ -661,8 +661,7 @@ // (Note that dead locals do not get phis built, ever.) ensure_phis_everywhere(); - if (block->is_SEL_head() && - (UseLoopPredicate || LoopLimitCheck)) { + if (block->is_SEL_head() && UseLoopPredicate) { // Add predicate to single entry (not irreducible) loop head. assert(!block->has_merged_backedge(), "only entry paths should be merged for now"); // Need correct bci for predicate. diff -r 9989add27bf4 -r 8604d4659cee hotspot/src/share/vm/runtime/thread.cpp --- a/hotspot/src/share/vm/runtime/thread.cpp Tue Apr 05 01:46:40 2016 -0700 +++ b/hotspot/src/share/vm/runtime/thread.cpp Tue Apr 05 10:11:07 2016 +0000 @@ -791,10 +791,6 @@ handle_area()->oops_do(f); } -void Thread::nmethods_do(CodeBlobClosure* cf) { - // no nmethods in a generic thread... -} - void Thread::metadata_handles_do(void f(Metadata*)) { // Only walk the Handles in Thread. if (metadata_handles() != NULL) { @@ -2827,8 +2823,6 @@ } void JavaThread::nmethods_do(CodeBlobClosure* cf) { - Thread::nmethods_do(cf); // (super method is a no-op) - assert((!has_last_Java_frame() && java_call_counter() == 0) || (has_last_Java_frame() && java_call_counter() > 0), "wrong java_sp info!"); @@ -3301,6 +3295,7 @@ : JavaThread(&sweeper_thread_entry) { _scanned_nmethod = NULL; } + void CodeCacheSweeperThread::oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf) { JavaThread::oops_do(f, cld_f, cf); if (_scanned_nmethod != NULL && cf != NULL) { @@ -3311,6 +3306,16 @@ } } +void CodeCacheSweeperThread::nmethods_do(CodeBlobClosure* cf) { + JavaThread::nmethods_do(cf); + if (_scanned_nmethod != NULL && cf != NULL) { + // Safepoints can occur when the sweeper is scanning an nmethod so + // process it here to make sure it isn't unloaded in the middle of + // a scan. + cf->do_code_blob(_scanned_nmethod); + } +} + // ======= Threads ======== @@ -4348,9 +4353,13 @@ void Threads::nmethods_do(CodeBlobClosure* cf) { ALL_JAVA_THREADS(p) { - p->nmethods_do(cf); - } - VMThread::vm_thread()->nmethods_do(cf); + // This is used by the code cache sweeper to mark nmethods that are active + // on the stack of a Java thread. Ignore the sweeper thread itself to avoid + // marking CodeCacheSweeperThread::_scanned_nmethod as active. + if(!p->is_Code_cache_sweeper_thread()) { + p->nmethods_do(cf); + } + } } void Threads::metadata_do(void f(Metadata*)) { diff -r 9989add27bf4 -r 8604d4659cee hotspot/src/share/vm/runtime/thread.hpp --- a/hotspot/src/share/vm/runtime/thread.hpp Tue Apr 05 01:46:40 2016 -0700 +++ b/hotspot/src/share/vm/runtime/thread.hpp Tue Apr 05 10:11:07 2016 +0000 @@ -509,9 +509,6 @@ } } - // Sweeper support - void nmethods_do(CodeBlobClosure* cf); - // jvmtiRedefineClasses support void metadata_handles_do(void f(Metadata*)); @@ -1649,7 +1646,7 @@ void oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf); // Sweeper operations - void nmethods_do(CodeBlobClosure* cf); + virtual void nmethods_do(CodeBlobClosure* cf); // RedefineClasses Support void metadata_do(void f(Metadata*)); @@ -1997,10 +1994,10 @@ bool is_hidden_from_external_view() const { return true; } bool is_Code_cache_sweeper_thread() const { return true; } - // GC support - // Apply "f->do_oop" to all root oops in "this". - // Apply "cf->do_code_blob" (if !NULL) to all code blobs active in frames + + // Prevent GC from unloading _scanned_nmethod void oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf); + void nmethods_do(CodeBlobClosure* cf); }; // A thread used for Compilation. diff -r 9989add27bf4 -r 8604d4659cee hotspot/test/compiler/loopopts/TestCastIINoLoopLimitCheck.java --- a/hotspot/test/compiler/loopopts/TestCastIINoLoopLimitCheck.java Tue Apr 05 01:46:40 2016 -0700 +++ b/hotspot/test/compiler/loopopts/TestCastIINoLoopLimitCheck.java Tue Apr 05 10:11:07 2016 +0000 @@ -26,10 +26,19 @@ * @test * @bug 8073184 * @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 { static void m(int i, int index, char[] buf) {