Wed, 13 May 2020 15:59:17 +0200
8241114: Better range handling
Reviewed-by: kvn, vlivanov, rhalade, ahgross, mbalao, andrew
1.1 --- a/src/share/vm/opto/addnode.cpp Wed Sep 23 16:26:20 2020 +0300 1.2 +++ b/src/share/vm/opto/addnode.cpp Wed May 13 15:59:17 2020 +0200 1.3 @@ -844,6 +844,14 @@ 1.4 return TypeInt::make( MAX2(r0->_lo,r1->_lo), MAX2(r0->_hi,r1->_hi), MAX2(r0->_widen,r1->_widen) ); 1.5 } 1.6 1.7 +// Check if addition of an integer with type 't' and a constant 'c' can overflow 1.8 +static bool can_overflow(const TypeInt* t, jint c) { 1.9 + jint t_lo = t->_lo; 1.10 + jint t_hi = t->_hi; 1.11 + return ((c < 0 && (java_add(t_lo, c) > t_lo)) || 1.12 + (c > 0 && (java_add(t_hi, c) < t_hi))); 1.13 +} 1.14 + 1.15 //============================================================================= 1.16 //------------------------------Idealize--------------------------------------- 1.17 // MINs show up in range-check loop limit calculations. Look for 1.18 @@ -866,7 +874,7 @@ 1.19 1.20 // Get left input & constant 1.21 Node *x = l; 1.22 - int x_off = 0; 1.23 + jint x_off = 0; 1.24 if( x->Opcode() == Op_AddI && // Check for "x+c0" and collect constant 1.25 x->in(2)->is_Con() ) { 1.26 const Type *t = x->in(2)->bottom_type(); 1.27 @@ -877,7 +885,7 @@ 1.28 1.29 // Scan a right-spline-tree for MINs 1.30 Node *y = r; 1.31 - int y_off = 0; 1.32 + jint y_off = 0; 1.33 // Check final part of MIN tree 1.34 if( y->Opcode() == Op_AddI && // Check for "y+c1" and collect constant 1.35 y->in(2)->is_Con() ) { 1.36 @@ -891,6 +899,7 @@ 1.37 return this; 1.38 } 1.39 1.40 + const TypeInt* tx = phase->type(x)->isa_int(); 1.41 1.42 if( r->Opcode() == Op_MinI ) { 1.43 assert( r != r->in(2), "dead loop in MinINode::Ideal" ); 1.44 @@ -907,18 +916,23 @@ 1.45 if( x->_idx > y->_idx ) 1.46 return new (phase->C) MinINode(r->in(1),phase->transform(new (phase->C) MinINode(l,r->in(2)))); 1.47 1.48 - // See if covers: MIN2(x+c0,MIN2(y+c1,z)) 1.49 - if( !phase->eqv(x,y) ) return NULL; 1.50 - // If (y == x) transform MIN2(x+c0, MIN2(x+c1,z)) into 1.51 - // MIN2(x+c0 or x+c1 which less, z). 1.52 - return new (phase->C) MinINode(phase->transform(new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off)))),r->in(2)); 1.53 + // Transform MIN2(x + c0, MIN2(x + c1, z)) into MIN2(x + MIN2(c0, c1), z) 1.54 + // if x == y and the additions can't overflow. 1.55 + if (phase->eqv(x,y) && 1.56 + !can_overflow(tx, x_off) && 1.57 + !can_overflow(tx, y_off)) { 1.58 + return new (phase->C) MinINode(phase->transform(new (phase->C) AddINode(x, phase->intcon(MIN2(x_off, y_off)))), r->in(2)); 1.59 + } 1.60 } else { 1.61 - // See if covers: MIN2(x+c0,y+c1) 1.62 - if( !phase->eqv(x,y) ) return NULL; 1.63 - // If (y == x) transform MIN2(x+c0,x+c1) into x+c0 or x+c1 which less. 1.64 - return new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off))); 1.65 + // Transform MIN2(x + c0, y + c1) into x + MIN2(c0, c1) 1.66 + // if x == y and the additions can't overflow. 1.67 + if (phase->eqv(x,y) && 1.68 + !can_overflow(tx, x_off) && 1.69 + !can_overflow(tx, y_off)) { 1.70 + return new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off))); 1.71 + } 1.72 } 1.73 - 1.74 + return NULL; 1.75 } 1.76 1.77 //------------------------------add_ring---------------------------------------
2.1 --- a/src/share/vm/opto/loopTransform.cpp Wed Sep 23 16:26:20 2020 +0300 2.2 +++ b/src/share/vm/opto/loopTransform.cpp Wed May 13 15:59:17 2020 +0200 2.3 @@ -1530,65 +1530,78 @@ 2.4 } 2.5 2.6 //------------------------------adjust_limit----------------------------------- 2.7 -// Helper function for add_constraint(). 2.8 -Node* PhaseIdealLoop::adjust_limit(int stride_con, Node * scale, Node *offset, Node *rc_limit, Node *loop_limit, Node *pre_ctrl, bool round_up) { 2.9 - // Compute "I :: (limit-offset)/scale" 2.10 - Node *con = new (C) SubINode(rc_limit, offset); 2.11 - register_new_node(con, pre_ctrl); 2.12 - Node *X = new (C) DivINode(0, con, scale); 2.13 - register_new_node(X, pre_ctrl); 2.14 +// Helper function that computes new loop limit as (rc_limit-offset)/scale 2.15 +Node* PhaseIdealLoop::adjust_limit(bool is_positive_stride, Node* scale, Node* offset, Node* rc_limit, Node* old_limit, Node* pre_ctrl, bool round) { 2.16 + Node* sub = new (C) SubLNode(rc_limit, offset); 2.17 + register_new_node(sub, pre_ctrl); 2.18 + Node* limit = new (C) DivLNode(NULL, sub, scale); 2.19 + register_new_node(limit, pre_ctrl); 2.20 2.21 - // When the absolute value of scale is greater than one, the integer 2.22 - // division may round limit down so add one to the limit. 2.23 - if (round_up) { 2.24 - X = new (C) AddINode(X, _igvn.intcon(1)); 2.25 - register_new_node(X, pre_ctrl); 2.26 + // When the absolute value of scale is greater than one, the division 2.27 + // may round limit down/up, so add/sub one to/from the limit. 2.28 + if (round) { 2.29 + limit = new (C) AddLNode(limit, _igvn.longcon(is_positive_stride ? -1 : 1)); 2.30 + register_new_node(limit, pre_ctrl); 2.31 } 2.32 2.33 - // Adjust loop limit 2.34 - loop_limit = (stride_con > 0) 2.35 - ? (Node*)(new (C) MinINode(loop_limit, X)) 2.36 - : (Node*)(new (C) MaxINode(loop_limit, X)); 2.37 - register_new_node(loop_limit, pre_ctrl); 2.38 - return loop_limit; 2.39 + // Clamp the limit to handle integer under-/overflows. 2.40 + // When reducing the limit, clamp to [min_jint, old_limit]: 2.41 + // MIN(old_limit, MAX(limit, min_jint)) 2.42 + // When increasing the limit, clamp to [old_limit, max_jint]: 2.43 + // MAX(old_limit, MIN(limit, max_jint)) 2.44 + Node* cmp = new (C) CmpLNode(limit, _igvn.longcon(is_positive_stride ? min_jint : max_jint)); 2.45 + register_new_node(cmp, pre_ctrl); 2.46 + Node* bol = new (C) BoolNode(cmp, is_positive_stride ? BoolTest::lt : BoolTest::gt); 2.47 + register_new_node(bol, pre_ctrl); 2.48 + limit = new (C) ConvL2INode(limit); 2.49 + register_new_node(limit, pre_ctrl); 2.50 + limit = new (C) CMoveINode(bol, limit, _igvn.intcon(is_positive_stride ? min_jint : max_jint), TypeInt::INT); 2.51 + register_new_node(limit, pre_ctrl); 2.52 + 2.53 + limit = is_positive_stride ? (Node*)(new (C) MinINode(old_limit, limit)) 2.54 + : (Node*)(new (C) MaxINode(old_limit, limit)); 2.55 + register_new_node(limit, pre_ctrl); 2.56 + return limit; 2.57 } 2.58 2.59 //------------------------------add_constraint--------------------------------- 2.60 // Constrain the main loop iterations so the conditions: 2.61 -// low_limit <= scale_con * I + offset < upper_limit 2.62 -// always holds true. That is, either increase the number of iterations in 2.63 -// the pre-loop or the post-loop until the condition holds true in the main 2.64 -// loop. Stride, scale, offset and limit are all loop invariant. Further, 2.65 -// stride and scale are constants (offset and limit often are). 2.66 -void PhaseIdealLoop::add_constraint( int stride_con, int scale_con, Node *offset, Node *low_limit, Node *upper_limit, Node *pre_ctrl, Node **pre_limit, Node **main_limit ) { 2.67 - // For positive stride, the pre-loop limit always uses a MAX function 2.68 - // and the main loop a MIN function. For negative stride these are 2.69 - // reversed. 2.70 +// low_limit <= scale_con*I + offset < upper_limit 2.71 +// always hold true. That is, either increase the number of iterations in the 2.72 +// pre-loop or reduce the number of iterations in the main-loop until the condition 2.73 +// holds true in the main-loop. Stride, scale, offset and limit are all loop 2.74 +// invariant. Further, stride and scale are constants (offset and limit often are). 2.75 +void PhaseIdealLoop::add_constraint(jlong stride_con, jlong scale_con, Node* offset, Node* low_limit, Node* upper_limit, Node* pre_ctrl, Node** pre_limit, Node** main_limit) { 2.76 + assert(_igvn.type(offset)->isa_long() != NULL && _igvn.type(low_limit)->isa_long() != NULL && 2.77 + _igvn.type(upper_limit)->isa_long() != NULL, "arguments should be long values"); 2.78 2.79 - // Also for positive stride*scale the affine function is increasing, so the 2.80 - // pre-loop must check for underflow and the post-loop for overflow. 2.81 - // Negative stride*scale reverses this; pre-loop checks for overflow and 2.82 - // post-loop for underflow. 2.83 + // For a positive stride, we need to reduce the main-loop limit and 2.84 + // increase the pre-loop limit. This is reversed for a negative stride. 2.85 + bool is_positive_stride = (stride_con > 0); 2.86 2.87 - Node *scale = _igvn.intcon(scale_con); 2.88 + // If the absolute scale value is greater one, division in 'adjust_limit' may require 2.89 + // rounding. Make sure the ABS method correctly handles min_jint. 2.90 + // Only do this for the pre-loop, one less iteration of the main loop doesn't hurt. 2.91 + bool round = ABS(scale_con) > 1; 2.92 + 2.93 + Node* scale = _igvn.longcon(scale_con); 2.94 set_ctrl(scale, C->root()); 2.95 2.96 if ((stride_con^scale_con) >= 0) { // Use XOR to avoid overflow 2.97 + // Positive stride*scale: the affine function is increasing, 2.98 + // the pre-loop checks for underflow and the post-loop for overflow. 2.99 + 2.100 // The overflow limit: scale*I+offset < upper_limit 2.101 - // For main-loop compute 2.102 + // For the main-loop limit compute: 2.103 // ( if (scale > 0) /* and stride > 0 */ 2.104 // I < (upper_limit-offset)/scale 2.105 // else /* scale < 0 and stride < 0 */ 2.106 // I > (upper_limit-offset)/scale 2.107 // ) 2.108 - // 2.109 - // (upper_limit-offset) may overflow or underflow. 2.110 - // But it is fine since main loop will either have 2.111 - // less iterations or will be skipped in such case. 2.112 - *main_limit = adjust_limit(stride_con, scale, offset, upper_limit, *main_limit, pre_ctrl, false); 2.113 + *main_limit = adjust_limit(is_positive_stride, scale, offset, upper_limit, *main_limit, pre_ctrl, false); 2.114 2.115 - // The underflow limit: low_limit <= scale*I+offset. 2.116 - // For pre-loop compute 2.117 + // The underflow limit: low_limit <= scale*I+offset 2.118 + // For the pre-loop limit compute: 2.119 // NOT(scale*I+offset >= low_limit) 2.120 // scale*I+offset < low_limit 2.121 // ( if (scale > 0) /* and stride > 0 */ 2.122 @@ -1596,40 +1609,13 @@ 2.123 // else /* scale < 0 and stride < 0 */ 2.124 // I > (low_limit-offset)/scale 2.125 // ) 2.126 + *pre_limit = adjust_limit(!is_positive_stride, scale, offset, low_limit, *pre_limit, pre_ctrl, round); 2.127 + } else { 2.128 + // Negative stride*scale: the affine function is decreasing, 2.129 + // the pre-loop checks for overflow and the post-loop for underflow. 2.130 2.131 - if (low_limit->get_int() == -max_jint) { 2.132 - if (!RangeLimitCheck) return; 2.133 - // We need this guard when scale*pre_limit+offset >= limit 2.134 - // due to underflow. So we need execute pre-loop until 2.135 - // scale*I+offset >= min_int. But (min_int-offset) will 2.136 - // underflow when offset > 0 and X will be > original_limit 2.137 - // when stride > 0. To avoid it we replace positive offset with 0. 2.138 - // 2.139 - // Also (min_int+1 == -max_int) is used instead of min_int here 2.140 - // to avoid problem with scale == -1 (min_int/(-1) == min_int). 2.141 - Node* shift = _igvn.intcon(31); 2.142 - set_ctrl(shift, C->root()); 2.143 - Node* sign = new (C) RShiftINode(offset, shift); 2.144 - register_new_node(sign, pre_ctrl); 2.145 - offset = new (C) AndINode(offset, sign); 2.146 - register_new_node(offset, pre_ctrl); 2.147 - } else { 2.148 - assert(low_limit->get_int() == 0, "wrong low limit for range check"); 2.149 - // The only problem we have here when offset == min_int 2.150 - // since (0-min_int) == min_int. It may be fine for stride > 0 2.151 - // but for stride < 0 X will be < original_limit. To avoid it 2.152 - // max(pre_limit, original_limit) is used in do_range_check(). 2.153 - } 2.154 - // Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond); 2.155 - *pre_limit = adjust_limit((-stride_con), scale, offset, low_limit, *pre_limit, pre_ctrl, 2.156 - scale_con > 1 && stride_con > 0); 2.157 - 2.158 - } else { // stride_con*scale_con < 0 2.159 - // For negative stride*scale pre-loop checks for overflow and 2.160 - // post-loop for underflow. 2.161 - // 2.162 // The overflow limit: scale*I+offset < upper_limit 2.163 - // For pre-loop compute 2.164 + // For the pre-loop limit compute: 2.165 // NOT(scale*I+offset < upper_limit) 2.166 // scale*I+offset >= upper_limit 2.167 // scale*I+offset+1 > upper_limit 2.168 @@ -1638,58 +1624,24 @@ 2.169 // else /* scale > 0 and stride < 0 */ 2.170 // I > (upper_limit-(offset+1))/scale 2.171 // ) 2.172 - // 2.173 - // (upper_limit-offset-1) may underflow or overflow. 2.174 - // To avoid it min(pre_limit, original_limit) is used 2.175 - // in do_range_check() for stride > 0 and max() for < 0. 2.176 - Node *one = _igvn.intcon(1); 2.177 + Node* one = _igvn.longcon(1); 2.178 set_ctrl(one, C->root()); 2.179 + Node* plus_one = new (C) AddLNode(offset, one); 2.180 + register_new_node( plus_one, pre_ctrl ); 2.181 + *pre_limit = adjust_limit(!is_positive_stride, scale, plus_one, upper_limit, *pre_limit, pre_ctrl, round); 2.182 2.183 - Node *plus_one = new (C) AddINode(offset, one); 2.184 - register_new_node( plus_one, pre_ctrl ); 2.185 - // Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond); 2.186 - *pre_limit = adjust_limit((-stride_con), scale, plus_one, upper_limit, *pre_limit, pre_ctrl, 2.187 - scale_con < -1 && stride_con > 0); 2.188 - 2.189 - if (low_limit->get_int() == -max_jint) { 2.190 - if (!RangeLimitCheck) return; 2.191 - // We need this guard when scale*main_limit+offset >= limit 2.192 - // due to underflow. So we need execute main-loop while 2.193 - // scale*I+offset+1 > min_int. But (min_int-offset-1) will 2.194 - // underflow when (offset+1) > 0 and X will be < main_limit 2.195 - // when scale < 0 (and stride > 0). To avoid it we replace 2.196 - // positive (offset+1) with 0. 2.197 - // 2.198 - // Also (min_int+1 == -max_int) is used instead of min_int here 2.199 - // to avoid problem with scale == -1 (min_int/(-1) == min_int). 2.200 - Node* shift = _igvn.intcon(31); 2.201 - set_ctrl(shift, C->root()); 2.202 - Node* sign = new (C) RShiftINode(plus_one, shift); 2.203 - register_new_node(sign, pre_ctrl); 2.204 - plus_one = new (C) AndINode(plus_one, sign); 2.205 - register_new_node(plus_one, pre_ctrl); 2.206 - } else { 2.207 - assert(low_limit->get_int() == 0, "wrong low limit for range check"); 2.208 - // The only problem we have here when offset == max_int 2.209 - // since (max_int+1) == min_int and (0-min_int) == min_int. 2.210 - // But it is fine since main loop will either have 2.211 - // less iterations or will be skipped in such case. 2.212 - } 2.213 - // The underflow limit: low_limit <= scale*I+offset. 2.214 - // For main-loop compute 2.215 + // The underflow limit: low_limit <= scale*I+offset 2.216 + // For the main-loop limit compute: 2.217 // scale*I+offset+1 > low_limit 2.218 // ( if (scale < 0) /* and stride > 0 */ 2.219 // I < (low_limit-(offset+1))/scale 2.220 // else /* scale > 0 and stride < 0 */ 2.221 // I > (low_limit-(offset+1))/scale 2.222 // ) 2.223 - 2.224 - *main_limit = adjust_limit(stride_con, scale, plus_one, low_limit, *main_limit, pre_ctrl, 2.225 - false); 2.226 + *main_limit = adjust_limit(is_positive_stride, scale, plus_one, low_limit, *main_limit, pre_ctrl, false); 2.227 } 2.228 } 2.229 2.230 - 2.231 //------------------------------is_scaled_iv--------------------------------- 2.232 // Return true if exp is a constant times an induction var 2.233 bool PhaseIdealLoop::is_scaled_iv(Node* exp, Node* iv, int* p_scale) { 2.234 @@ -1854,22 +1806,14 @@ 2.235 // Must know if its a count-up or count-down loop 2.236 2.237 int stride_con = cl->stride_con(); 2.238 - Node *zero = _igvn.intcon(0); 2.239 - Node *one = _igvn.intcon(1); 2.240 + Node* zero = _igvn.longcon(0); 2.241 + Node* one = _igvn.longcon(1); 2.242 // Use symmetrical int range [-max_jint,max_jint] 2.243 - Node *mini = _igvn.intcon(-max_jint); 2.244 + Node* mini = _igvn.longcon(-max_jint); 2.245 set_ctrl(zero, C->root()); 2.246 set_ctrl(one, C->root()); 2.247 set_ctrl(mini, C->root()); 2.248 2.249 - // Range checks that do not dominate the loop backedge (ie. 2.250 - // conditionally executed) can lengthen the pre loop limit beyond 2.251 - // the original loop limit. To prevent this, the pre limit is 2.252 - // (for stride > 0) MINed with the original loop limit (MAXed 2.253 - // stride < 0) when some range_check (rc) is conditionally 2.254 - // executed. 2.255 - bool conditional_rc = false; 2.256 - 2.257 // Check loop body for tests of trip-counter plus loop-invariant vs 2.258 // loop-invariant. 2.259 for( uint i = 0; i < loop->_body.size(); i++ ) { 2.260 @@ -1948,15 +1892,20 @@ 2.261 // stride_con and scale_con can be negative which will flip about the 2.262 // sense of the test. 2.263 2.264 + // Perform the limit computations in jlong to avoid overflow 2.265 + jlong lscale_con = scale_con; 2.266 + Node* int_offset = offset; 2.267 + offset = new (C) ConvI2LNode(offset); 2.268 + register_new_node(offset, pre_ctrl); 2.269 + Node* int_limit = limit; 2.270 + limit = new (C) ConvI2LNode(limit); 2.271 + register_new_node(limit, pre_ctrl); 2.272 + 2.273 // Adjust pre and main loop limits to guard the correct iteration set 2.274 if( cmp->Opcode() == Op_CmpU ) {// Unsigned compare is really 2 tests 2.275 if( b_test._test == BoolTest::lt ) { // Range checks always use lt 2.276 // The underflow and overflow limits: 0 <= scale*I+offset < limit 2.277 - add_constraint( stride_con, scale_con, offset, zero, limit, pre_ctrl, &pre_limit, &main_limit ); 2.278 - if (!conditional_rc) { 2.279 - // (0-offset)/scale could be outside of loop iterations range. 2.280 - conditional_rc = !loop->dominates_backedge(iff) || RangeLimitCheck; 2.281 - } 2.282 + add_constraint(stride_con, lscale_con, offset, zero, limit, pre_ctrl, &pre_limit, &main_limit); 2.283 } else { 2.284 #ifndef PRODUCT 2.285 if( PrintOpto ) 2.286 @@ -1970,16 +1919,16 @@ 2.287 // Fall into GE case 2.288 case BoolTest::ge: 2.289 // Convert (I*scale+offset) >= Limit to (I*(-scale)+(-offset)) <= -Limit 2.290 - scale_con = -scale_con; 2.291 - offset = new (C) SubINode( zero, offset ); 2.292 + lscale_con = -lscale_con; 2.293 + offset = new (C) SubLNode(zero, offset); 2.294 register_new_node( offset, pre_ctrl ); 2.295 - limit = new (C) SubINode( zero, limit ); 2.296 + limit = new (C) SubLNode(zero, limit); 2.297 register_new_node( limit, pre_ctrl ); 2.298 // Fall into LE case 2.299 case BoolTest::le: 2.300 if (b_test._test != BoolTest::gt) { 2.301 // Convert X <= Y to X < Y+1 2.302 - limit = new (C) AddINode( limit, one ); 2.303 + limit = new (C) AddLNode(limit, one); 2.304 register_new_node( limit, pre_ctrl ); 2.305 } 2.306 // Fall into LT case 2.307 @@ -1987,13 +1936,7 @@ 2.308 // The underflow and overflow limits: MIN_INT <= scale*I+offset < limit 2.309 // Note: (MIN_INT+1 == -MAX_INT) is used instead of MIN_INT here 2.310 // to avoid problem with scale == -1: MIN_INT/(-1) == MIN_INT. 2.311 - add_constraint( stride_con, scale_con, offset, mini, limit, pre_ctrl, &pre_limit, &main_limit ); 2.312 - if (!conditional_rc) { 2.313 - // ((MIN_INT+1)-offset)/scale could be outside of loop iterations range. 2.314 - // Note: negative offset is replaced with 0 but (MIN_INT+1)/scale could 2.315 - // still be outside of loop range. 2.316 - conditional_rc = !loop->dominates_backedge(iff) || RangeLimitCheck; 2.317 - } 2.318 + add_constraint(stride_con, lscale_con, offset, mini, limit, pre_ctrl, &pre_limit, &main_limit); 2.319 break; 2.320 default: 2.321 #ifndef PRODUCT 2.322 @@ -2029,7 +1972,8 @@ 2.323 } 2.324 2.325 // Update loop limits 2.326 - if (conditional_rc) { 2.327 + if (pre_limit != orig_limit) { 2.328 + // Computed pre-loop limit can be outside of loop iterations range. 2.329 pre_limit = (stride_con > 0) ? (Node*)new (C) MinINode(pre_limit, orig_limit) 2.330 : (Node*)new (C) MaxINode(pre_limit, orig_limit); 2.331 register_new_node(pre_limit, pre_ctrl);
3.1 --- a/src/share/vm/opto/loopnode.hpp Wed Sep 23 16:26:20 2020 +0300 3.2 +++ b/src/share/vm/opto/loopnode.hpp Wed May 13 15:59:17 2020 +0200 3.3 @@ -961,9 +961,9 @@ 3.4 // always holds true. That is, either increase the number of iterations in 3.5 // the pre-loop or the post-loop until the condition holds true in the main 3.6 // loop. Scale_con, offset and limit are all loop invariant. 3.7 - void add_constraint( int stride_con, int scale_con, Node *offset, Node *low_limit, Node *upper_limit, Node *pre_ctrl, Node **pre_limit, Node **main_limit ); 3.8 + void add_constraint(jlong stride_con, jlong scale_con, Node* offset, Node* low_limit, Node* upper_limit, Node* pre_ctrl, Node** pre_limit, Node** main_limit); 3.9 // Helper function for add_constraint(). 3.10 - Node* adjust_limit(int stride_con, Node * scale, Node *offset, Node *rc_limit, Node *loop_limit, Node *pre_ctrl, bool round_up); 3.11 + Node* adjust_limit(bool reduce, Node* scale, Node* offset, Node* rc_limit, Node* old_limit, Node* pre_ctrl, bool round); 3.12 3.13 // Partially peel loop up through last_peel node. 3.14 bool partial_peel( IdealLoopTree *loop, Node_List &old_new );