Skip to content

Commit 6e027b5

Browse files
committed
Enable loop rotate when the header is exiting
This was recently disabled but turns out to be an important case for loops with preconditions.
1 parent d8aa678 commit 6e027b5

File tree

3 files changed

+21
-30
lines changed

3 files changed

+21
-30
lines changed

lib/SILOptimizer/LoopTransforms/LoopRotate.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -369,12 +369,6 @@ static bool rotateLoop(SILLoop *loop, DominanceInfo *domInfo,
369369
assert(loop->contains(newHeader) && !loop->contains(exit)
370370
&& "Could not find loop header and exit block");
371371

372-
// It does not make sense to rotate the loop if the new header is loop
373-
// exiting as well.
374-
if (loop->isLoopExiting(newHeader)) {
375-
return false;
376-
}
377-
378372
// Incomplete liveranges in the dead-end exit block can cause a missing adjacent
379373
// phi-argument for a re-borrow if there is a borrow-scope is in the loop.
380374
// But even when we have complete lifetimes, it's probably not worth rotating

test/SILOptimizer/looprotate_ossa.sil

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,13 @@ bb3:
8585
return %23 : $Int32
8686
}
8787

88-
// CHECK-LABEL: sil [ossa] @dont_rotate_multi_exit_loop :
89-
// CHECK: bb1({{.*}}):
90-
// CHECK: cond_br %{{.*}}, bb4, bb2
91-
// CHECK: bb2:
92-
// CHECK: cond_br undef, bb3, bb5
93-
// CHECK: bb6:
94-
// CHECK: return
95-
// CHECK-NOT: bb7
96-
// CHECK: } // end sil function 'dont_rotate_multi_exit_loop'
97-
sil [ossa] @dont_rotate_multi_exit_loop : $@convention(thin) (Int32, @owned Bar) -> Int32 {
88+
// CHECK-LABEL: sil [ossa] @rotate_multi_exit_loop :
89+
// CHECK: [[METH1:%.*]] = class_method {{.*}} : $Bar, #Bar.foo : (Bar) -> () -> (), $@convention(method) (@guaranteed Bar) -> ()
90+
// CHECK: apply [[METH1]]({{.*}}) : $@convention(method) (@guaranteed Bar) -> ()
91+
// CHECK: [[METH2:%.*]] = class_method {{.*}} : $Bar, #Bar.foo : (Bar) -> () -> (), $@convention(method) (@guaranteed Bar) -> ()
92+
// CHECK: apply [[METH2]]({{.*}}) : $@convention(method) (@guaranteed Bar) -> ()
93+
// CHECK: } // end sil function 'rotate_multi_exit_loop'
94+
sil [ossa] @rotate_multi_exit_loop : $@convention(thin) (Int32, @owned Bar) -> Int32 {
9895
bb0(%0 : $Int32, %25: @owned $Bar):
9996
%1 = struct_extract %0 : $Int32, #Int32._value
10097
%2 = integer_literal $Builtin.Int32, 0

test/SILOptimizer/mutable_span_bounds_check_tests.swift

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111
import SpanExtras
1212

1313
// Bounds check should be eliminated
14-
// SIL does not optimize this
14+
// SIL removes lower bounds check from the loop
1515
// LLVM leaves behind a lower bound check outside the loop, does not vectorize the loop
1616

1717
// CHECK-SIL-LABEL: sil @$s31mutable_span_bounds_check_tests0B10_zero_inityy10SpanExtras07MutableH0VySiGzF :
18-
// CHECK: bb2:
19-
// CHECK: cond_fail {{.*}}, "Index out of bounds"
18+
// CHECK: bb3:
2019
// CHECK: cond_fail {{.*}}, "Index out of bounds"
20+
// CHECK-NOT: cond_fail {{.*}}, "Index out of bounds"
2121
// CHECK: cond_br
2222
// CHECK-SIL-LABEL: } // end sil function '$s31mutable_span_bounds_check_tests0B10_zero_inityy10SpanExtras07MutableH0VySiGzF'
2323
public func span_zero_init(_ output: inout MutableSpan<Int>) {
@@ -27,13 +27,13 @@ public func span_zero_init(_ output: inout MutableSpan<Int>) {
2727
}
2828

2929
// Bounds check should be eliminated
30-
// SIL does not optimize this
30+
// SIL removes lower bounds check from the loop
3131
// LLVM leaves behind a lower bound check outside the loop, does not vectorize the loop or reduce to a memcopy
3232

3333
// CHECK-SIL-LABEL: sil @$s31mutable_span_bounds_check_tests0B14_copy_elemwiseyy10SpanExtras07MutableH0VySiGz_s0H0VySiGtF :
34-
// CHECK: bb2:
35-
// CHECK: cond_fail {{.*}}, "Index out of bounds"
34+
// CHECK: bb3:
3635
// CHECK: cond_fail {{.*}}, "Index out of bounds"
36+
// CHECK-NOT: cond_fail {{.*}}, "Index out of bounds"
3737
// CHECK: cond_br
3838
// CHECK-SIL-LABEL: } // end sil function '$s31mutable_span_bounds_check_tests0B14_copy_elemwiseyy10SpanExtras07MutableH0VySiGz_s0H0VySiGtF'
3939
public func span_copy_elemwise(_ output: inout MutableSpan<Int>, _ input: Span<Int>) {
@@ -44,12 +44,12 @@ public func span_copy_elemwise(_ output: inout MutableSpan<Int>, _ input: Span<I
4444
}
4545

4646
// Bounds check should be eliminated
47-
// SIL does not optimize this
47+
// SIL removes lower bounds check from the loop
4848

4949
// CHECK-SIL-LABEL: sil @$s31mutable_span_bounds_check_tests0B16_append_elemwiseyy10SpanExtras06OutputH0VySiGz_s0H0VySiGtF :
50-
// CHECK: bb2:
51-
// CHECK: cond_fail {{.*}}, "Index out of bounds"
50+
// CHECK: bb3:
5251
// CHECK: cond_fail {{.*}}, "Index out of bounds"
52+
// CHECK-NOT: cond_fail {{.*}}, "Index out of bounds"
5353
// CHECK: cond_br
5454
// CHECK-SIL-LABEL: } // end sil function '$s31mutable_span_bounds_check_tests0B16_append_elemwiseyy10SpanExtras06OutputH0VySiGz_s0H0VySiGtF'
5555
public func span_append_elemwise(_ output: inout OutputSpan<Int>, _ input: Span<Int>) {
@@ -59,12 +59,12 @@ public func span_append_elemwise(_ output: inout OutputSpan<Int>, _ input: Span<
5959
}
6060

6161
// Bounds check should be eliminated
62-
// SIL does not optimize this
62+
// SIL removes lower bounds check from the loop
6363

6464
// CHECK-SIL-LABEL: sil @$s31mutable_span_bounds_check_tests0B12_sum_wo_trapyy10SpanExtras07MutableI0VySiGz_s0I0VySiGAItF :
65-
// CHECK: bb2:
66-
// CHECK: cond_fail {{.*}}, "Index out of bounds"
65+
// CHECK: bb3:
6766
// CHECK: cond_fail {{.*}}, "Index out of bounds"
67+
// CHECK-NOT: cond_fail {{.*}}, "Index out of bounds"
6868
// CHECK: cond_br
6969
// CHECK-SIL-LABEL: } // end sil function '$s31mutable_span_bounds_check_tests0B12_sum_wo_trapyy10SpanExtras07MutableI0VySiGz_s0I0VySiGAItF'
7070
public func span_sum_wo_trap(_ output: inout MutableSpan<Int>, _ input1: Span<Int>, _ input2: Span<Int>) {
@@ -76,9 +76,9 @@ public func span_sum_wo_trap(_ output: inout MutableSpan<Int>, _ input1: Span<In
7676
}
7777

7878
// CHECK-SIL-LABEL: sil @$s31mutable_span_bounds_check_tests0B14_sum_with_trapyy10SpanExtras07MutableI0VySiGz_s0I0VySiGAItF :
79-
// CHECK: bb2:
80-
// CHECK: cond_fail {{.*}}, "Index out of bounds"
79+
// CHECK: bb3:
8180
// CHECK: cond_fail {{.*}}, "Index out of bounds"
81+
// CHECK-NOT: cond_fail {{.*}}, "Index out of bounds"
8282
// CHECK: cond_br
8383
// CHECK-SIL-LABEL: } // end sil function '$s31mutable_span_bounds_check_tests0B14_sum_with_trapyy10SpanExtras07MutableI0VySiGz_s0I0VySiGAItF'
8484
public func span_sum_with_trap(_ output: inout MutableSpan<Int>, _ input1: Span<Int>, _ input2: Span<Int>) {

0 commit comments

Comments
 (0)