< prev index next >

src/share/vm/opto/loopTransform.cpp

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.

@@ -68,13 +68,13 @@
     _phase->_igvn._worklist.push(n);
   }
 }
 
 //------------------------------compute_exact_trip_count-----------------------
-// Compute loop exact trip count if possible. Do not recalculate trip count for
+// Compute loop trip count if possible. Do not recalculate trip count for
 // split loops (pre-main-post) which have their limits and inits behind Opaque node.
-void IdealLoopTree::compute_exact_trip_count( PhaseIdealLoop *phase ) {
+void IdealLoopTree::compute_trip_count(PhaseIdealLoop* phase) {
   if (!_head->as_Loop()->is_valid_counted_loop()) {
     return;
   }
   CountedLoopNode* cl = _head->as_CountedLoop();
   // Trip count may become nonexact for iteration split loops since

@@ -92,21 +92,25 @@
          bt == BoolTest::ne, "canonical test is expected");
 #endif
 
   Node* init_n = cl->init_trip();
   Node* limit_n = cl->limit();
-  if (init_n  != NULL &&  init_n->is_Con() &&
-      limit_n != NULL && limit_n->is_Con()) {
+  if (init_n != NULL && limit_n != NULL) {
     // Use longs to avoid integer overflow.
     int stride_con  = cl->stride_con();
-    jlong init_con   = cl->init_trip()->get_int();
-    jlong limit_con  = cl->limit()->get_int();
+    jlong init_con = phase->_igvn.type(init_n)->is_int()->_lo;
+    jlong limit_con = phase->_igvn.type(limit_n)->is_int()->_hi;
     int stride_m    = stride_con - (stride_con > 0 ? 1 : -1);
     jlong trip_count = (limit_con - init_con + stride_m)/stride_con;
     if (trip_count > 0 && (julong)trip_count < (julong)max_juint) {
+      if (init_n->is_Con() && limit_n->is_Con()) {
       // Set exact trip count.
       cl->set_exact_trip_count((uint)trip_count);
+      } else if (cl->is_normal_loop() && cl->unrolled_count() == 1) {
+        // Set maximum trip count before unrolling.
+        cl->set_trip_count((uint)trip_count);
+      }
     }
   }
 }
 
 //------------------------------compute_profile_trip_cnt----------------------------

@@ -1303,11 +1307,11 @@
   // Step A: Create a new post-Loop.
   Node* main_exit = main_end->proj_out(false);
   assert(main_exit->Opcode() == Op_IfFalse, "");
   int dd_main_exit = dom_depth(main_exit);
 
-  // Step A1: Clone the loop body of main.  The clone becomes the vector post-loop.
+  // Step A1: Clone the loop body of main. The clone becomes the post-loop.
   // The main loop pre-header illegally has 2 control users (old & new loops).
   clone_loop(loop, old_new, dd_main_exit);
   assert(old_new[main_end->_idx]->Opcode() == Op_CountedLoopEnd, "");
   post_head = old_new[main_head->_idx]->as_CountedLoop();
   post_head->set_normal_loop();

@@ -2093,12 +2097,11 @@
 
   // Count number of range checks and reduce by load range limits, if zero,
   // the loop is in canonical form to multiversion.
   closed_range_checks = 0;
 
-  // Check loop body for tests of trip-counter plus loop-invariant vs
-  // loop-invariant.
+  // Check loop body for tests of trip-counter plus loop-invariant vs loop-variant.
   for( uint i = 0; i < loop->_body.size(); i++ ) {
     Node *iff = loop->_body[i];
     if (iff->Opcode() == Op_If ||
         iff->Opcode() == Op_RangeCheck) { // Test?
       // Test is an IfNode, has 2 projections.  If BOTH are in the loop

@@ -2296,11 +2299,11 @@
   CountedLoopNode *cl = loop->_head->as_CountedLoop();
 
   // skip this loop if it is already checked
   if (cl->has_been_range_checked()) return;
 
-  // Now check for existance of range checks
+  // Now check for existence of range checks
   for (uint i = 0; i < loop->_body.size(); i++) {
     Node *iff = loop->_body[i];
     int iff_opc = iff->Opcode();
     if (iff_opc == Op_If || iff_opc == Op_RangeCheck) {
       cl->mark_has_range_checks();

@@ -2317,11 +2320,11 @@
   bool multi_version_succeeded = false;
   assert(RangeCheckElimination, "");
   CountedLoopNode *legacy_cl = legacy_loop->_head->as_CountedLoop();
   assert(legacy_cl->is_post_loop(), "");
 
-  // Check for existance of range checks using the unique instance to make a guard with
+  // Check for existence of range checks using the unique instance to make a guard with
   Unique_Node_List worklist;
   for (uint i = 0; i < legacy_loop->_body.size(); i++) {
     Node *iff = legacy_loop->_body[i];
     int iff_opc = iff->Opcode();
     if (iff_opc == Op_If || iff_opc == Op_RangeCheck) {

@@ -2420,11 +2423,11 @@
 
   return multi_version_succeeded;
 }
 
 //-------------------------poison_rce_post_loop--------------------------------
-// Causes the rce'd post loop to be optimized away if multiverioning fails
+// Causes the rce'd post loop to be optimized away if multiversioning fails
 void PhaseIdealLoop::poison_rce_post_loop(IdealLoopTree *rce_loop) {
   CountedLoopNode *rce_cl = rce_loop->_head->as_CountedLoop();
   Node* ctrl = rce_cl->in(LoopNode::EntryControl);
   if (ctrl->is_IfTrue() || ctrl->is_IfFalse()) {
     Node* iffm = ctrl->in(0);

@@ -2708,12 +2711,12 @@
 }
 
 //=============================================================================
 //------------------------------iteration_split_impl---------------------------
 bool IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_new ) {
-  // Compute exact loop trip count if possible.
-  compute_exact_trip_count(phase);
+  // Compute loop trip count if possible.
+  compute_trip_count(phase);
 
   // Convert one iteration loop into normal code.
   if (policy_do_one_iteration_loop(phase))
     return true;
 
< prev index next >