< 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 >