Skip to content

Commit 61ce3a3

Browse files
committed
Handle mark_dependence in ForEachLoopUnroll
1 parent 3e27dc8 commit 61ce3a3

File tree

4 files changed

+69
-56
lines changed

4 files changed

+69
-56
lines changed

lib/SILOptimizer/LoopTransforms/ForEachLoopUnroll.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,11 @@ void ArrayInfo::classifyUsesOfArray(SILValue arrayValue) {
302302
// above as the array would be passed indirectly.
303303
if (isFixLifetimeUseOfArray(user, arrayValue))
304304
continue;
305+
if (auto *MDI = dyn_cast<MarkDependenceInst>(user)) {
306+
if (MDI->getBase() == arrayValue) {
307+
continue;
308+
}
309+
}
305310
// Check if this is a forEach call on the array.
306311
if (TryApplyInst *forEachCall = isForEachUseOfArray(user, arrayValue)) {
307312
forEachCalls.insert(forEachCall);

test/SILOptimizer/constant_evaluator_test.sil

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,6 +1241,7 @@ bb0:
12411241
%1 = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
12421242
%2 = apply %1<String>(%0) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
12431243
(%3, %4) = destructure_tuple %2 : $(Array<String>, Builtin.RawPointer)
1244+
%5 = mark_dependence %4 : $Builtin.RawPointer on %3 : $Array<String>
12441245
return %3 : $Array<String>
12451246
} // CHECK: Returns Array<String>
12461247
// CHECK: size: 0 contents []

test/SILOptimizer/for_each_loop_unroll_test.sil

Lines changed: 60 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,42 @@ sil [_semantics "sequence.forEach"] @forEach : $@convention(method) <τ_0_0 wher
1212

1313
sil @forEachBody : $@convention(thin) (@in_guaranteed Builtin.Int64) -> @error any Error
1414

15+
// CHECK-LABEL: forEachLoopUnrollTest
16+
// CHECK: [[LIT1:%[0-9]+]] = integer_literal $Builtin.Int64, 15
17+
// CHECK: [[LIT2:%[0-9]+]] = integer_literal $Builtin.Int64, 27
18+
// CHECK: [[BODYCLOSURE:%[0-9]+]] = thin_to_thick_function
19+
// CHECK-NOT: forEach
20+
// CHECK: [[STACK:%[0-9]+]] = alloc_stack $Builtin.Int64
21+
// CHECK: store [[LIT1]] to [trivial] [[STACK]]
22+
// CHECK: try_apply [[BODYCLOSURE]]([[STACK]]) : $@noescape @callee_guaranteed (@in_guaranteed Builtin.Int64) -> @error any Error, normal [[NORMAL:bb[0-9]+]], error [[ERROR:bb[0-9]+]]
23+
24+
// CHECK: [[ERROR]]([[ERRPARAM:%[0-9]+]] : @owned $any Error):
25+
// CHECK: br [[ERROR3:bb[0-9]+]]([[ERRPARAM]] : $any Error)
26+
27+
// CHECK: [[NORMAL]](%{{.*}} : $()):
28+
// CHECK: store [[LIT2]] to [trivial] [[STACK]] : $*Builtin.Int64
29+
// CHECK: try_apply [[BODYCLOSURE]]([[STACK]]) : $@noescape @callee_guaranteed (@in_guaranteed Builtin.Int64) -> @error any Error, normal [[NORMAL2:bb[0-9]+]], error [[ERROR2:bb[0-9]+]]
30+
31+
// CHECK: [[ERROR2]]([[ERRPARAM2:%[0-9]+]] : @owned $any Error):
32+
// CHECK: br [[ERROR3:bb[0-9]+]]([[ERRPARAM2]] : $any Error)
33+
34+
// CHECK: [[NORMAL2]](%{{.*}} : $()):
35+
// CHECK: dealloc_stack [[STACK]]
36+
// Note that the temporary alloc_stack of the array created for the forEach call
37+
// will be cleaned up when the forEach call is removed.
38+
// CHECK: destroy_value
39+
40+
// CHECK: [[ERROR3]]([[ERRPARAM3:%[0-9]+]] : @owned $any Error):
41+
// CHECK: dealloc_stack [[STACK]]
42+
// CHECK: unreachable
43+
1544
sil hidden [ossa] @forEachLoopUnrollTest : $@convention(thin) () -> () {
1645
bb0:
1746
%0 = integer_literal $Builtin.Word, 2
1847
%1 = function_ref @_allocateUninitializedArray : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
1948
%2 = apply %1<Builtin.Int64>(%0) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
20-
(%3, %4) = destructure_tuple %2 : $(Array<Builtin.Int64>, Builtin.RawPointer)
49+
(%3, %4a) = destructure_tuple %2 : $(Array<Builtin.Int64>, Builtin.RawPointer)
50+
%4 = mark_dependence %4a : $Builtin.RawPointer on %3 : $Array<Builtin.Int64>
2151
%5 = pointer_to_address %4 : $Builtin.RawPointer to [strict] $*Builtin.Int64
2252
%6 = integer_literal $Builtin.Int64, 15
2353
store %6 to [trivial] %5 : $*Builtin.Int64
@@ -46,26 +76,35 @@ bb1(%32 : $()):
4676
bb2(%39 : @owned $Error):
4777
unreachable
4878
}
49-
// CHECK-LABEL: forEachLoopUnrollTest
50-
// CHECK: [[LIT1:%[0-9]+]] = integer_literal $Builtin.Int64, 15
51-
// CHECK: [[LIT2:%[0-9]+]] = integer_literal $Builtin.Int64, 27
79+
80+
sil @forEachBody2 : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <A> () -> @out A for <Int>) -> @error any Error
81+
82+
// CHECK-LABEL: nonTrivialForEachLoopUnrollTest
83+
// CHECK: [[ELEM1:%[0-9]+]] = copy_value %0
84+
// CHECK-NEXT: store %0 to [init] %{{.*}} : $*@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <Int>
85+
// CHECK: [[ELEM2:%[0-9]+]] = copy_value %1
86+
// CHECK-NEXT: store %1 to [init] %{{.*}} : $*@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <Int>
5287
// CHECK: [[BODYCLOSURE:%[0-9]+]] = thin_to_thick_function
5388
// CHECK-NOT: forEach
54-
// CHECK: [[STACK:%[0-9]+]] = alloc_stack $Builtin.Int64
55-
// CHECK: store [[LIT1]] to [trivial] [[STACK]]
56-
// CHECK: try_apply [[BODYCLOSURE]]([[STACK]]) : $@noescape @callee_guaranteed (@in_guaranteed Builtin.Int64) -> @error any Error, normal [[NORMAL:bb[0-9]+]], error [[ERROR:bb[0-9]+]]
89+
// CHECK: [[STACK:%[0-9]+]] = alloc_stack $@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <Int>
90+
// CHECK: [[ELEM1BORROW:%[0-9]+]] = begin_borrow [[ELEM1]]
91+
// CHECK: [[SB1:%.*]] = store_borrow [[ELEM1BORROW]] to [[STACK]]
92+
// CHECK: try_apply [[BODYCLOSURE]]([[SB1]]) : $@noescape @callee_guaranteed (@in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <Int>) -> @error any Error, normal [[NORMAL:bb[0-9]+]], error [[ERROR:bb[0-9]+]]
5793

5894
// CHECK: [[ERROR]]([[ERRPARAM:%[0-9]+]] : @owned $any Error):
5995
// CHECK: br [[ERROR3:bb[0-9]+]]([[ERRPARAM]] : $any Error)
6096

6197
// CHECK: [[NORMAL]](%{{.*}} : $()):
62-
// CHECK: store [[LIT2]] to [trivial] [[STACK]] : $*Builtin.Int64
63-
// CHECK: try_apply [[BODYCLOSURE]]([[STACK]]) : $@noescape @callee_guaranteed (@in_guaranteed Builtin.Int64) -> @error any Error, normal [[NORMAL2:bb[0-9]+]], error [[ERROR2:bb[0-9]+]]
98+
// CHECK: end_borrow [[ELEM1BORROW]]
99+
// CHECK: [[ELEM2BORROW:%[0-9]+]] = begin_borrow [[ELEM2]]
100+
// CHECK: [[SB2:%.*]] = store_borrow [[ELEM2BORROW]] to [[STACK]]
101+
// CHECK: try_apply [[BODYCLOSURE]]([[SB2]]) : $@noescape @callee_guaranteed (@in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <Int>) -> @error any Error, normal [[NORMAL2:bb[0-9]+]], error [[ERROR2:bb[0-9]+]]
64102

65103
// CHECK: [[ERROR2]]([[ERRPARAM2:%[0-9]+]] : @owned $any Error):
66104
// CHECK: br [[ERROR3:bb[0-9]+]]([[ERRPARAM2]] : $any Error)
67105

68106
// CHECK: [[NORMAL2]](%{{.*}} : $()):
107+
// CHECK: end_borrow [[ELEM2BORROW]]
69108
// CHECK: dealloc_stack [[STACK]]
70109
// Note that the temporary alloc_stack of the array created for the forEach call
71110
// will be cleaned up when the forEach call is removed.
@@ -74,15 +113,13 @@ bb2(%39 : @owned $Error):
74113
// CHECK: [[ERROR3]]([[ERRPARAM3:%[0-9]+]] : @owned $any Error):
75114
// CHECK: dealloc_stack [[STACK]]
76115
// CHECK: unreachable
77-
78-
sil @forEachBody2 : $@convention(thin) (@in_guaranteed @callee_guaranteed @substituted <A> () -> @out A for <Int>) -> @error any Error
79-
80116
sil hidden [ossa] @nonTrivialForEachLoopUnrollTest : $@convention(thin) (@owned @callee_guaranteed @substituted <A> () -> @out A for <Int>, @owned @callee_guaranteed @substituted <A> () -> @out A for <Int>) -> () {
81117
bb0(%0: @owned $@callee_guaranteed @substituted <A> () -> @out A for <Int>, %1: @owned $@callee_guaranteed @substituted <A> () -> @out A for <Int>):
82118
%2 = integer_literal $Builtin.Word, 2
83119
%3 = function_ref @_allocateUninitializedArray : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
84120
%4 = apply %3<() -> Int>(%2) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
85-
(%5, %6) = destructure_tuple %4 : $(Array<()->Int>, Builtin.RawPointer)
121+
(%5, %6a) = destructure_tuple %4 : $(Array<()->Int>, Builtin.RawPointer)
122+
%6 = mark_dependence %6a : $Builtin.RawPointer on %5 : $Array<() -> Int>
86123
%7 = pointer_to_address %6 : $Builtin.RawPointer to [strict] $*@callee_guaranteed @substituted <A> () -> @out A for <Int>
87124
store %0 to [init] %7 : $*@callee_guaranteed @substituted <A> () -> @out A for <Int>
88125
%12 = integer_literal $Builtin.Word, 1
@@ -109,47 +146,17 @@ bb1(%32 : $()):
109146
bb2(%39 : @owned $Error):
110147
unreachable
111148
}
112-
// CHECK-LABEL: nonTrivialForEachLoopUnrollTest
113-
// CHECK: [[ELEM1:%[0-9]+]] = copy_value %0
114-
// CHECK-NEXT: store %0 to [init] %{{.*}} : $*@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <Int>
115-
// CHECK: [[ELEM2:%[0-9]+]] = copy_value %1
116-
// CHECK-NEXT: store %1 to [init] %{{.*}} : $*@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <Int>
117-
// CHECK: [[BODYCLOSURE:%[0-9]+]] = thin_to_thick_function
118-
// CHECK-NOT: forEach
119-
// CHECK: [[STACK:%[0-9]+]] = alloc_stack $@callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <Int>
120-
// CHECK: [[ELEM1BORROW:%[0-9]+]] = begin_borrow [[ELEM1]]
121-
// CHECK: [[SB1:%.*]] = store_borrow [[ELEM1BORROW]] to [[STACK]]
122-
// CHECK: try_apply [[BODYCLOSURE]]([[SB1]]) : $@noescape @callee_guaranteed (@in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <Int>) -> @error any Error, normal [[NORMAL:bb[0-9]+]], error [[ERROR:bb[0-9]+]]
123-
124-
// CHECK: [[ERROR]]([[ERRPARAM:%[0-9]+]] : @owned $any Error):
125-
// CHECK: br [[ERROR3:bb[0-9]+]]([[ERRPARAM]] : $any Error)
126-
127-
// CHECK: [[NORMAL]](%{{.*}} : $()):
128-
// CHECK: end_borrow [[ELEM1BORROW]]
129-
// CHECK: [[ELEM2BORROW:%[0-9]+]] = begin_borrow [[ELEM2]]
130-
// CHECK: [[SB2:%.*]] = store_borrow [[ELEM2BORROW]] to [[STACK]]
131-
// CHECK: try_apply [[BODYCLOSURE]]([[SB2]]) : $@noescape @callee_guaranteed (@in_guaranteed @callee_guaranteed @substituted <τ_0_0> () -> @out τ_0_0 for <Int>) -> @error any Error, normal [[NORMAL2:bb[0-9]+]], error [[ERROR2:bb[0-9]+]]
132-
133-
// CHECK: [[ERROR2]]([[ERRPARAM2:%[0-9]+]] : @owned $any Error):
134-
// CHECK: br [[ERROR3:bb[0-9]+]]([[ERRPARAM2]] : $any Error)
135-
136-
// CHECK: [[NORMAL2]](%{{.*}} : $()):
137-
// CHECK: end_borrow [[ELEM2BORROW]]
138-
// CHECK: dealloc_stack [[STACK]]
139-
// Note that the temporary alloc_stack of the array created for the forEach call
140-
// will be cleaned up when the forEach call is removed.
141-
// CHECK: destroy_value
142-
143-
// CHECK: [[ERROR3]]([[ERRPARAM3:%[0-9]+]] : @owned $any Error):
144-
// CHECK: dealloc_stack [[STACK]]
145-
// CHECK: unreachable
146149

150+
// CHECK-LABEL: @checkIndirectFixLifetimeUsesAreIgnored
151+
// CHECK-NOT: function_ref @forEach : $@convention(method) <τ_0_0 where τ_0_0 : Sequence> (@noescape @callee_guaranteed (@in_guaranteed τ_0_0.Element) -> @error any Error, @in_guaranteed τ_0_0) -> @error any Error
152+
// CHECK: end sil function 'checkIndirectFixLifetimeUsesAreIgnored'
147153
sil hidden [ossa] @checkIndirectFixLifetimeUsesAreIgnored : $@convention(thin) () -> () {
148154
bb0:
149155
%0 = integer_literal $Builtin.Word, 2
150156
%1 = function_ref @_allocateUninitializedArray : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
151157
%2 = apply %1<Builtin.Int64>(%0) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
152-
(%3, %4) = destructure_tuple %2 : $(Array<Builtin.Int64>, Builtin.RawPointer)
158+
(%3, %4a) = destructure_tuple %2 : $(Array<Builtin.Int64>, Builtin.RawPointer)
159+
%4 = mark_dependence %4a : $Builtin.RawPointer on %3 : $Array<Builtin.Int64>
153160
%5 = pointer_to_address %4 : $Builtin.RawPointer to [strict] $*Builtin.Int64
154161
%6 = integer_literal $Builtin.Int64, 15
155162
store %6 to [trivial] %5 : $*Builtin.Int64
@@ -184,10 +191,10 @@ bb1(%32 : $()):
184191
bb2(%39 : @owned $Error):
185192
unreachable
186193
}
187-
// CHECK-LABEL: @checkIndirectFixLifetimeUsesAreIgnored
188-
// CHECK-NOT: function_ref @forEach : $@convention(method) <τ_0_0 where τ_0_0 : Sequence> (@noescape @callee_guaranteed (@in_guaranteed τ_0_0.Element) -> @error any Error, @in_guaranteed τ_0_0) -> @error any Error
189-
// CHECK: end sil function 'checkIndirectFixLifetimeUsesAreIgnored'
190194

195+
// CHECK-LABEL: @testUnrollOfArrayWithPhiArguments
196+
// CHECK-NOT: function_ref @forEach : $@convention(method) <τ_0_0 where τ_0_0 : Sequence> (@noescape @callee_guaranteed (@in_guaranteed τ_0_0.Element) -> @error any Error, @in_guaranteed τ_0_0) -> @error any Error
197+
// CHECK: end sil function 'testUnrollOfArrayWithPhiArguments'
191198
sil hidden [ossa] @testUnrollOfArrayWithPhiArguments : $@convention(thin) () -> () {
192199
bb0:
193200
%0 = integer_literal $Builtin.Int64, 57
@@ -197,7 +204,8 @@ bb1(%arg : $Builtin.Int64):
197204
%10 = integer_literal $Builtin.Word, 1
198205
%11 = function_ref @_allocateUninitializedArray : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
199206
%12 = apply %11<Builtin.Int64>(%10) : $@convention(thin) <τ_0_0> (Builtin.Word) -> (@owned Array<τ_0_0>, Builtin.RawPointer)
200-
(%13, %14) = destructure_tuple %12 : $(Array<Builtin.Int64>, Builtin.RawPointer)
207+
(%13, %14a) = destructure_tuple %12 : $(Array<Builtin.Int64>, Builtin.RawPointer)
208+
%14 = mark_dependence %14a : $Builtin.RawPointer on %13 : $Array<Builtin.Int64>
201209
%15 = pointer_to_address %14 : $Builtin.RawPointer to [strict] $*Builtin.Int64
202210
store %arg to [trivial] %15 : $*Builtin.Int64
203211
br bb2(%arg : $Builtin.Int64)
@@ -224,7 +232,4 @@ bb3(%32 : $()):
224232
bb4(%39 : @owned $Error):
225233
unreachable
226234
}
227-
// CHECK-LABEL: @testUnrollOfArrayWithPhiArguments
228-
// CHECK-NOT: function_ref @forEach : $@convention(method) <τ_0_0 where τ_0_0 : Sequence> (@noescape @callee_guaranteed (@in_guaranteed τ_0_0.Element) -> @error any Error, @in_guaranteed τ_0_0) -> @error any Error
229-
// CHECK: end sil function 'testUnrollOfArrayWithPhiArguments'
230235

test/SILOptimizer/for_each_loop_unroll_test.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,10 @@ func unrollLetArrayLiteralWithClosures(i: Int32, j: Int32) {
6464
a.forEach { print($0()) }
6565
// CHECK: [[ALLOCATE:%[0-9]+]] = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF
6666
// CHECK: [[ARRAYTUP:%[0-9]+]] = apply [[ALLOCATE]]<() -> Int32>
67+
// CHECK: [[ARRAYVAL:%[0-9]+]] = tuple_extract [[ARRAYTUP]] : $(Array<() -> Int32>, Builtin.RawPointer), 0
6768
// CHECK: [[STORAGEPTR:%[0-9]+]] = tuple_extract [[ARRAYTUP]] : $(Array<() -> Int32>, Builtin.RawPointer), 1
68-
// CHECK: [[STORAGEADDR:%[0-9]+]] = pointer_to_address [[STORAGEPTR]]
69+
// CHECK: [[MDI:%[0-9]+]] = mark_dependence [[STORAGEPTR]] : $Builtin.RawPointer on [[ARRAYVAL]] : $Array<() -> Int32>
70+
// CHECK: [[STORAGEADDR:%[0-9]+]] = pointer_to_address [[MDI]]
6971
// CHECK: store [[CLOSURE1:%[0-9]+]] to [[STORAGEADDR]]
7072
// CHECK: [[INDEX1:%[0-9]+]] = index_addr [[STORAGEADDR]]
7173
// CHECK: store [[CLOSURE2:%[0-9]+]] to [[INDEX1]]

0 commit comments

Comments
 (0)