Skip to content

Commit 456ab75

Browse files
committed
[loadable-address] Move rewriting of yields into the loop that handles struct_extracts, switch_enum, and applies.
yields are like applies in the sense that processing them can produce struct_extract that need to be rewritten. rdar://80646212
1 parent 77f4dfa commit 456ab75

File tree

2 files changed

+80
-5
lines changed

2 files changed

+80
-5
lines changed

lib/IRGen/LoadableByAddress.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2064,17 +2064,17 @@ static void rewriteFunction(StructLoweringState &pass,
20642064
applySite.getArgumentOperands());
20652065
}
20662066

2067+
while (!pass.modYieldInsts.empty()) {
2068+
YieldInst *inst = pass.modYieldInsts.pop_back_val();
2069+
allocateAndSetAll(pass, allocator, inst, inst->getAllOperands());
2070+
}
2071+
20672072
repeat = !pass.switchEnumInstsToMod.empty() ||
20682073
!pass.structExtractInstsToMod.empty();
20692074
assert(pass.applies.empty());
20702075
pass.applies.append(currentModApplies.begin(), currentModApplies.end());
20712076
} while (repeat);
20722077

2073-
while (!pass.modYieldInsts.empty()) {
2074-
YieldInst *inst = pass.modYieldInsts.pop_back_val();
2075-
allocateAndSetAll(pass, allocator, inst, inst->getAllOperands());
2076-
}
2077-
20782078
for (SILInstruction *instr : pass.instsToMod) {
20792079
for (Operand &operand : instr->getAllOperands()) {
20802080
auto currOperand = operand.get();

test/IRGen/yield_once_big.sil

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,12 @@ struct Big<T: SomeClass> {
2626
var h: T
2727
}
2828

29+
struct BigWrapper<T : SomeClass> {
30+
var big: Big<T>
31+
}
32+
2933
sil @make_big : $<T: SomeClass> () -> (@owned Big<T>)
34+
sil @use_some_class : $<T : SomeClass> (@guaranteed T) -> ()
3035

3136
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc { i8*, %T14yield_once_big3BigV* } @test_simple
3237
// CHECK-32-SAME: (i8* noalias dereferenceable([[BUFFER_SIZE:16]]) %0, %swift.type* %C)
@@ -171,3 +176,73 @@ cont:
171176
%ret = tuple ()
172177
return %ret : $()
173178
}
179+
180+
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc { i8*, %T14yield_once_big3BigV* } @test_simple_guaranteed
181+
// CHECK-32-SAME: (i8* noalias dereferenceable([[BUFFER_SIZE:16]]) %0, %T14yield_once_big10BigWrapperV* noalias nocapture dereferenceable(32) %1, %swift.type* %C)
182+
// CHECK-64-SAME: (i8* noalias dereferenceable([[BUFFER_SIZE:32]]) %0, %T14yield_once_big10BigWrapperV* noalias nocapture dereferenceable(64) %1, %swift.type* %C)
183+
sil [ossa] @test_simple_guaranteed : $@yield_once <C: SomeClass> (@in_guaranteed BigWrapper<C>) -> (@yields @guaranteed Big<C>) {
184+
entry(%arg : $*BigWrapper<C>):
185+
// Allocate space for the return value of make_big.
186+
// CHECK: [[TEMP:%.*]] = alloca [[BIG:%T14yield_once_big3BigV]]
187+
// CHECK-32-SAME: , align 4
188+
// CHECK-64-SAME: , align 8
189+
190+
// Coroutine setup.
191+
// CHECK-32-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s14yield_once_big10BigWrapperVyxGAA0D0VyxGAA9SomeClassCRbzlIetAnYn_TC" to i8*), i8* bitcast (i8* (i32)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*))
192+
// CHECK-64-NEXT: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast (void (i8*, i1)* @"$s14yield_once_big10BigWrapperVyxGAA0D0VyxGAA9SomeClassCRbzlIetAnYn_TC" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*))
193+
// CHECK-NEXT: [[BEGIN:%.*]] = call i8* @llvm.coro.begin(token [[ID]], i8* null)
194+
// CHECK-NEXT: store %swift.type*
195+
196+
// Create the return temporary. We could give this a tighter bound.
197+
// CHECK-NEXT: [[T0:%.*]] = bitcast [[BIG]]* [[TEMP]] to i8*
198+
// CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 {{.*}}, i8* [[T0]])
199+
200+
// CHECK-NEXT: call swiftcc void @marker(i32 1000)
201+
%marker = function_ref @marker : $@convention(thin) (Builtin.Int32) -> ()
202+
%1000 = integer_literal $Builtin.Int32, 1000
203+
apply %marker(%1000) : $@convention(thin) (Builtin.Int32) -> ()
204+
205+
%value = load_borrow %arg : $*BigWrapper<C>
206+
%field = struct_extract %value : $BigWrapper<C>, #BigWrapper.big
207+
208+
// Make sure that we properly convert these struct_extract to
209+
// struct_element_addr while rewriting.
210+
//
211+
// CHECK: call swiftcc void @use_some_class(
212+
%field2 = struct_extract %value : $BigWrapper<C>, #BigWrapper.big
213+
%field3 = struct_extract %field2 : $Big<C>, #Big.a
214+
%f = function_ref @use_some_class : $@convention(thin) <T : SomeClass> (@guaranteed T) -> ()
215+
apply %f<C>(%field3) : $@convention(thin) <T : SomeClass>(@guaranteed T) -> ()
216+
217+
// Suspend.
218+
// CHECK-NEXT: [[IS_UNWIND:%.*]] = call i1 (...) @llvm.coro.suspend.retcon.i1([[BIG]]* [[TEMP]])
219+
220+
// CHECK-NEXT: br i1 [[IS_UNWIND]]
221+
yield %field : $Big<C>, resume resume, unwind unwind
222+
223+
resume:
224+
end_borrow %value : $BigWrapper<C>
225+
226+
// CHECK: call swiftcc void @marker(i32 2000)
227+
%2000 = integer_literal $Builtin.Int32, 2000
228+
apply %marker(%2000) : $@convention(thin) (Builtin.Int32) -> ()
229+
// CHECK-NEXT: [[T0:%.*]] = bitcast [[BIG]]* [[TEMP]] to i8*
230+
// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 {{.*}}, i8* [[T0]])
231+
// CHECK-NEXT: br label %coro.end
232+
%ret = tuple ()
233+
return %ret : $()
234+
235+
unwind:
236+
end_borrow %value : $BigWrapper<C>
237+
// CHECK: call swiftcc void @marker(i32 3000)
238+
%3000 = integer_literal $Builtin.Int32, 3000
239+
apply %marker(%3000) : $@convention(thin) (Builtin.Int32) -> ()
240+
// CHECK-NEXT: [[T0:%.*]] = bitcast [[BIG]]* [[TEMP]] to i8*
241+
// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 {{.*}}, i8* [[T0]])
242+
// CHECK-NEXT: br label %coro.end
243+
unwind
244+
245+
// CHECK: coro.end:
246+
// CHECK: call i1 @llvm.coro.end(i8* [[BEGIN]], i1 false)
247+
// CHECK-NEXT: unreachable
248+
}

0 commit comments

Comments
 (0)