src/share/vm/opto/loopTransform.cpp

changeset 9739
bf9503046dd4
parent 9610
f43f77de876a
child 9756
2be326848943
child 9772
eee5798e1b28
     1.1 --- a/src/share/vm/opto/loopTransform.cpp	Fri Sep 28 14:24:22 2018 +0200
     1.2 +++ b/src/share/vm/opto/loopTransform.cpp	Fri Dec 14 11:22:26 2018 +0100
     1.3 @@ -1537,13 +1537,20 @@
     1.4  
     1.5  //------------------------------adjust_limit-----------------------------------
     1.6  // Helper function for add_constraint().
     1.7 -Node* PhaseIdealLoop::adjust_limit(int stride_con, Node * scale, Node *offset, Node *rc_limit, Node *loop_limit, Node *pre_ctrl) {
     1.8 +Node* PhaseIdealLoop::adjust_limit(int stride_con, Node * scale, Node *offset, Node *rc_limit, Node *loop_limit, Node *pre_ctrl, bool round_up) {
     1.9    // Compute "I :: (limit-offset)/scale"
    1.10    Node *con = new (C) SubINode(rc_limit, offset);
    1.11    register_new_node(con, pre_ctrl);
    1.12    Node *X = new (C) DivINode(0, con, scale);
    1.13    register_new_node(X, pre_ctrl);
    1.14  
    1.15 +  // When the absolute value of scale is greater than one, the integer
    1.16 +  // division may round limit down so add one to the limit.
    1.17 +  if (round_up) {
    1.18 +    X = new (C) AddINode(X, _igvn.intcon(1));
    1.19 +    register_new_node(X, pre_ctrl);
    1.20 +  }
    1.21 +
    1.22    // Adjust loop limit
    1.23    loop_limit = (stride_con > 0)
    1.24                 ? (Node*)(new (C) MinINode(loop_limit, X))
    1.25 @@ -1584,7 +1591,7 @@
    1.26      // (upper_limit-offset) may overflow or underflow.
    1.27      // But it is fine since main loop will either have
    1.28      // less iterations or will be skipped in such case.
    1.29 -    *main_limit = adjust_limit(stride_con, scale, offset, upper_limit, *main_limit, pre_ctrl);
    1.30 +    *main_limit = adjust_limit(stride_con, scale, offset, upper_limit, *main_limit, pre_ctrl, false);
    1.31  
    1.32      // The underflow limit: low_limit <= scale*I+offset.
    1.33      // For pre-loop compute
    1.34 @@ -1620,7 +1627,8 @@
    1.35        // max(pre_limit, original_limit) is used in do_range_check().
    1.36      }
    1.37      // Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond);
    1.38 -    *pre_limit = adjust_limit((-stride_con), scale, offset, low_limit, *pre_limit, pre_ctrl);
    1.39 +    *pre_limit = adjust_limit((-stride_con), scale, offset, low_limit, *pre_limit, pre_ctrl,
    1.40 +                              scale_con > 1 && stride_con > 0);
    1.41  
    1.42    } else { // stride_con*scale_con < 0
    1.43      // For negative stride*scale pre-loop checks for overflow and
    1.44 @@ -1646,7 +1654,8 @@
    1.45      Node *plus_one = new (C) AddINode(offset, one);
    1.46      register_new_node( plus_one, pre_ctrl );
    1.47      // Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond);
    1.48 -    *pre_limit = adjust_limit((-stride_con), scale, plus_one, upper_limit, *pre_limit, pre_ctrl);
    1.49 +    *pre_limit = adjust_limit((-stride_con), scale, plus_one, upper_limit, *pre_limit, pre_ctrl,
    1.50 +                              scale_con < -1 && stride_con > 0);
    1.51  
    1.52      if (low_limit->get_int() == -max_jint) {
    1.53        if (!RangeLimitCheck) return;
    1.54 @@ -1681,7 +1690,8 @@
    1.55      //       I > (low_limit-(offset+1))/scale
    1.56      //   )
    1.57  
    1.58 -    *main_limit = adjust_limit(stride_con, scale, plus_one, low_limit, *main_limit, pre_ctrl);
    1.59 +    *main_limit = adjust_limit(stride_con, scale, plus_one, low_limit, *main_limit, pre_ctrl,
    1.60 +                               false);
    1.61    }
    1.62  }
    1.63  

mercurial