< prev index next >
src/share/vm/opto/loopTransform.cpp
Print this page
rev 13090 : Make a copy of strip mined loops with small number of iterations from profiling
rev 13092 : aggressive predicates
@@ -2754,10 +2754,46 @@
phase->_igvn.replace_node(cl->phi(), cl->init_trip());
phase->C->set_major_progress();
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 ) {
// Compute loop trip count if possible.
compute_trip_count(phase);
@@ -2811,10 +2847,13 @@
// 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 true;
}
+ if (copy_strip_mined_short(phase, old_new)) {
+ return true;
+ }
}
// Skip next optimizations if running low on nodes. Note that
// policy_unswitching and policy_maximally_unroll have this check.
int nodes_left = phase->C->max_node_limit() - phase->C->live_nodes();
< prev index next >