--- old/src/share/vm/opto/loopTransform.cpp 2017-03-03 15:48:32.098435761 +0100 +++ new/src/share/vm/opto/loopTransform.cpp 2017-03-03 15:48:32.019435711 +0100 @@ -2756,6 +2756,42 @@ return true; } +bool IdealLoopTree::copy_strip_mined_short(PhaseIdealLoop *phase, Node_List &old_new) { + CountedLoopNode *cl = _head->as_CountedLoop(); + if (LoopStripMiningCopyShort && + cl->is_strip_mined() && + !cl->is_strip_mined_short_cloned() && + !cl->has_exact_trip_count() && + cl->profile_trip_cnt() < LoopStripMiningIter / 10) { + int nodes_left = phase->C->max_node_limit() - phase->C->live_nodes(); + if ((int)(2 * _body.size()) <= nodes_left) { + int stride = cl->stride_con(); + jlong scaled_iters_long = ((jlong)LoopStripMiningIter/10) * ABS(stride); + int scaled_iters = (int)scaled_iters_long; + if ((jlong)scaled_iters == scaled_iters_long) { + cl->mark_strip_mined_short_cloned(); + ProjNode* proj_true = phase->create_slow_version_of_loop(this, old_new, Op_If, PhaseIdealLoop::ControlAroundStripMined); + IfNode* iff = proj_true->in(0)->as_If(); + Node* proj_false = iff->proj_out(1-proj_true->_con); + Node* sub = NULL; + if (stride > 0) { + sub = phase->_igvn.transform(new SubINode(cl->limit(), cl->init_trip())); + } else { + sub = phase->_igvn.transform(new SubINode(cl->init_trip(), cl->limit())); + } + Node* cmp = phase->_igvn.transform(new CmpINode(sub, phase->_igvn.intcon(scaled_iters))); + Node* bol = phase->_igvn.transform(new BoolNode(cmp, BoolTest::ge)); + iff = phase->_igvn.transform(new IfNode(iff->in(0), bol, PROB_MIN, COUNT_UNKNOWN))->as_If(); + proj_true->set_req(0, iff); + proj_false->set_req(0, iff); + phase->C->set_major_progress(); + return true; + } + } + } + return false; +} + //============================================================================= //------------------------------iteration_split_impl--------------------------- bool IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_new ) { @@ -2813,6 +2849,9 @@ phase->do_maximally_unroll(this,old_new); return true; } + if (copy_strip_mined_short(phase, old_new)) { + return true; + } } // Skip next optimizations if running low on nodes. Note that