@@ -1065,7 +1065,7 @@ void IdealLoopTree::policy_unroll_slp_analysis(CountedLoopNode *cl, PhaseIdealLo
1065
1065
// When TRUE, the estimated node budget is also requested.
1066
1066
//
1067
1067
// We will actually perform iteration-splitting, a more powerful form of RCE.
1068
- bool IdealLoopTree::policy_range_check (PhaseIdealLoop* phase, bool provisional) const {
1068
+ bool IdealLoopTree::policy_range_check (PhaseIdealLoop* phase, bool provisional, BasicType bt ) const {
1069
1069
if (!provisional && !RangeCheckElimination) return false ;
1070
1070
1071
1071
// If nodes are depleted, some transform has miscalculated its needs.
@@ -1087,7 +1087,7 @@ bool IdealLoopTree::policy_range_check(PhaseIdealLoop* phase, bool provisional)
1087
1087
1088
1088
BaseCountedLoopNode* cl = _head->as_BaseCountedLoop ();
1089
1089
Node *trip_counter = cl->phi ();
1090
- BasicType bt = cl-> bt ( );
1090
+ assert (!cl-> is_LongCountedLoop () || bt == T_LONG, " only long range checks in long counted loops " );
1091
1091
1092
1092
// Check loop body for tests of trip-counter plus loop-invariant vs
1093
1093
// loop-invariant.
@@ -1135,7 +1135,7 @@ bool IdealLoopTree::policy_range_check(PhaseIdealLoop* phase, bool provisional)
1135
1135
}
1136
1136
}
1137
1137
1138
- if (!phase->is_scaled_iv_plus_offset (rc_exp, trip_counter, NULL , NULL )) {
1138
+ if (!phase->is_scaled_iv_plus_offset (rc_exp, trip_counter, NULL , NULL , bt )) {
1139
1139
continue ;
1140
1140
}
1141
1141
}
@@ -1145,7 +1145,9 @@ bool IdealLoopTree::policy_range_check(PhaseIdealLoop* phase, bool provisional)
1145
1145
if (is_loop_exit (iff)) {
1146
1146
// Found valid reason to split iterations (if there is room).
1147
1147
// NOTE: Usually a gross overestimate.
1148
- return provisional || phase->may_require_nodes (est_loop_clone_sz (2 ));
1148
+ // Long range checks cause the loop to be transformed in a loop nest which only causes a fixed number of nodes
1149
+ // to be added
1150
+ return provisional || bt == T_LONG || phase->may_require_nodes (est_loop_clone_sz (2 ));
1149
1151
}
1150
1152
} // End of is IF
1151
1153
}
@@ -2508,34 +2510,52 @@ void PhaseIdealLoop::add_constraint(jlong stride_con, jlong scale_con, Node* off
2508
2510
}
2509
2511
}
2510
2512
2513
+ bool PhaseIdealLoop::is_iv (Node* exp, Node* iv, BasicType bt) {
2514
+ if (exp == iv) {
2515
+ return true ;
2516
+ }
2517
+
2518
+ if (bt == T_LONG && iv->bottom_type ()->isa_int () && exp->Opcode () == Op_ConvI2L && exp->in (1 ) == iv) {
2519
+ return true ;
2520
+ }
2521
+ return false ;
2522
+ }
2523
+
2511
2524
// ------------------------------is_scaled_iv---------------------------------
2512
2525
// Return true if exp is a constant times an induction var
2513
- bool PhaseIdealLoop::is_scaled_iv (Node* exp, Node* iv, jlong* p_scale, BasicType bt) {
2526
+ bool PhaseIdealLoop::is_scaled_iv (Node* exp, Node* iv, jlong* p_scale, BasicType bt, bool * converted ) {
2514
2527
exp = exp->uncast ();
2515
2528
assert (bt == T_INT || bt == T_LONG, " unexpected int type" );
2516
- if (exp == iv ) {
2529
+ if (is_iv ( exp, iv, bt) ) {
2517
2530
if (p_scale != NULL ) {
2518
2531
*p_scale = 1 ;
2519
2532
}
2520
2533
return true ;
2521
2534
}
2535
+ if (bt == T_LONG && iv->bottom_type ()->isa_int () && exp->Opcode () == Op_ConvI2L) {
2536
+ exp = exp->in (1 );
2537
+ bt = T_INT;
2538
+ if (converted != NULL ) {
2539
+ *converted = true ;
2540
+ }
2541
+ }
2522
2542
int opc = exp->Opcode ();
2523
2543
// Can't use is_Mul() here as it's true for AndI and AndL
2524
2544
if (opc == Op_Mul (bt)) {
2525
- if (exp->in (1 )->uncast () == iv && exp->in (2 )->is_Con ()) {
2545
+ if (is_iv ( exp->in (1 )->uncast (), iv, bt) && exp->in (2 )->is_Con ()) {
2526
2546
if (p_scale != NULL ) {
2527
2547
*p_scale = exp->in (2 )->get_integer_as_long (bt);
2528
2548
}
2529
2549
return true ;
2530
2550
}
2531
- if (exp->in (2 )->uncast () == iv && exp->in (1 )->is_Con ()) {
2551
+ if (is_iv ( exp->in (2 )->uncast (), iv, bt) && exp->in (1 )->is_Con ()) {
2532
2552
if (p_scale != NULL ) {
2533
2553
*p_scale = exp->in (1 )->get_integer_as_long (bt);
2534
2554
}
2535
2555
return true ;
2536
2556
}
2537
2557
} else if (opc == Op_LShift (bt)) {
2538
- if (exp->in (1 )->uncast () == iv && exp->in (2 )->is_Con ()) {
2558
+ if (is_iv ( exp->in (1 )->uncast (), iv, bt) && exp->in (2 )->is_Con ()) {
2539
2559
if (p_scale != NULL ) {
2540
2560
jint shift_amount = exp->in (2 )->get_int ();
2541
2561
if (bt == T_INT) {
@@ -2552,9 +2572,9 @@ bool PhaseIdealLoop::is_scaled_iv(Node* exp, Node* iv, jlong* p_scale, BasicType
2552
2572
2553
2573
// -----------------------------is_scaled_iv_plus_offset------------------------------
2554
2574
// Return true if exp is a simple induction variable expression: k1*iv + (invar + k2)
2555
- bool PhaseIdealLoop::is_scaled_iv_plus_offset (Node* exp, Node* iv, jlong* p_scale, Node** p_offset, BasicType bt, int depth) {
2575
+ bool PhaseIdealLoop::is_scaled_iv_plus_offset (Node* exp, Node* iv, jlong* p_scale, Node** p_offset, BasicType bt, bool * converted, int depth) {
2556
2576
assert (bt == T_INT || bt == T_LONG, " unexpected int type" );
2557
- if (is_scaled_iv (exp, iv, p_scale, bt)) {
2577
+ if (is_scaled_iv (exp, iv, p_scale, bt, converted )) {
2558
2578
if (p_offset != NULL ) {
2559
2579
Node *zero = _igvn.integercon (0 , bt);
2560
2580
set_ctrl (zero, C->root ());
@@ -2565,13 +2585,13 @@ bool PhaseIdealLoop::is_scaled_iv_plus_offset(Node* exp, Node* iv, jlong* p_scal
2565
2585
exp = exp->uncast ();
2566
2586
int opc = exp->Opcode ();
2567
2587
if (opc == Op_Add (bt)) {
2568
- if (is_scaled_iv (exp->in (1 ), iv, p_scale, bt)) {
2588
+ if (is_scaled_iv (exp->in (1 ), iv, p_scale, bt, converted )) {
2569
2589
if (p_offset != NULL ) {
2570
2590
*p_offset = exp->in (2 );
2571
2591
}
2572
2592
return true ;
2573
2593
}
2574
- if (is_scaled_iv (exp->in (2 ), iv, p_scale, bt)) {
2594
+ if (is_scaled_iv (exp->in (2 ), iv, p_scale, bt, converted )) {
2575
2595
if (p_offset != NULL ) {
2576
2596
*p_offset = exp->in (1 );
2577
2597
}
@@ -2581,7 +2601,7 @@ bool PhaseIdealLoop::is_scaled_iv_plus_offset(Node* exp, Node* iv, jlong* p_scal
2581
2601
Node* offset2 = NULL ;
2582
2602
if (depth < 2 &&
2583
2603
is_scaled_iv_plus_offset (exp->in (1 ), iv, p_scale,
2584
- p_offset != NULL ? &offset2 : NULL , bt, depth+1 )) {
2604
+ p_offset != NULL ? &offset2 : NULL , bt, converted, depth+1 )) {
2585
2605
if (p_offset != NULL ) {
2586
2606
Node *ctrl_off2 = get_ctrl (offset2);
2587
2607
Node* offset = AddNode::make (offset2, exp->in (2 ), bt);
@@ -2592,7 +2612,7 @@ bool PhaseIdealLoop::is_scaled_iv_plus_offset(Node* exp, Node* iv, jlong* p_scal
2592
2612
}
2593
2613
}
2594
2614
} else if (opc == Op_Sub (bt)) {
2595
- if (is_scaled_iv (exp->in (1 ), iv, p_scale, bt)) {
2615
+ if (is_scaled_iv (exp->in (1 ), iv, p_scale, bt, converted )) {
2596
2616
if (p_offset != NULL ) {
2597
2617
Node *zero = _igvn.integercon (0 , bt);
2598
2618
set_ctrl (zero, C->root ());
@@ -2603,7 +2623,7 @@ bool PhaseIdealLoop::is_scaled_iv_plus_offset(Node* exp, Node* iv, jlong* p_scal
2603
2623
}
2604
2624
return true ;
2605
2625
}
2606
- if (is_scaled_iv (exp->in (2 ), iv, p_scale, bt)) {
2626
+ if (is_scaled_iv (exp->in (2 ), iv, p_scale, bt, converted )) {
2607
2627
if (p_offset != NULL ) {
2608
2628
// We can't handle a scale of min_jint (or min_jlong) here as -1 * min_jint = min_jint
2609
2629
if (*p_scale == min_signed_integer (bt)) {
@@ -3432,6 +3452,8 @@ bool IdealLoopTree::iteration_split_impl(PhaseIdealLoop *phase, Node_List &old_n
3432
3452
} else if (policy_unswitching (phase)) {
3433
3453
phase->do_unswitching (this , old_new);
3434
3454
return false ; // need to recalculate idom data
3455
+ } else if (_head->is_LongCountedLoop ()) {
3456
+ phase->create_loop_nest (this , old_new);
3435
3457
}
3436
3458
return true ;
3437
3459
}
@@ -3475,7 +3497,8 @@ bool IdealLoopTree::iteration_split_impl(PhaseIdealLoop *phase, Node_List &old_n
3475
3497
// unrolling), plus any needed for RCE purposes.
3476
3498
3477
3499
bool should_unroll = policy_unroll (phase);
3478
- bool should_rce = policy_range_check (phase, false );
3500
+ bool should_rce = policy_range_check (phase, false , T_INT);
3501
+ bool should_rce_long = policy_range_check (phase, false , T_LONG);
3479
3502
3480
3503
// If not RCE'ing (iteration splitting), then we do not need a pre-loop.
3481
3504
// We may still need to peel an initial iteration but we will not
@@ -3490,6 +3513,9 @@ bool IdealLoopTree::iteration_split_impl(PhaseIdealLoop *phase, Node_List &old_n
3490
3513
// peeling.
3491
3514
if (should_rce || should_unroll) {
3492
3515
if (cl->is_normal_loop ()) { // Convert to 'pre/main/post' loops
3516
+ if (should_rce_long && phase->create_loop_nest (this , old_new)) {
3517
+ return true ;
3518
+ }
3493
3519
uint estimate = est_loop_clone_sz (3 );
3494
3520
if (!phase->may_require_nodes (estimate)) {
3495
3521
return false ;
@@ -3531,6 +3557,9 @@ bool IdealLoopTree::iteration_split_impl(PhaseIdealLoop *phase, Node_List &old_n
3531
3557
phase->do_peeling (this , old_new);
3532
3558
}
3533
3559
}
3560
+ if (should_rce_long) {
3561
+ phase->create_loop_nest (this , old_new);
3562
+ }
3534
3563
}
3535
3564
return true ;
3536
3565
}
0 commit comments