Skip to content

Commit fb4583f

Browse files
authored
Merge pull request swiftlang#35111 from nate-chandler/concurrency/irgen/for-now-async-is-not-simple
[Async CC] Never use simple partial apply for async functions.
2 parents d68d406 + d4664c8 commit fb4583f

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed

lib/IRGen/IRGenSIL.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2942,6 +2942,9 @@ static bool isSimplePartialApply(IRGenFunction &IGF, PartialApplyInst *i) {
29422942
// The callee type must use the `method` convention.
29432943
auto calleeTy = i->getCallee()->getType().castTo<SILFunctionType>();
29442944
auto resultTy = i->getFunctionType();
2945+
2946+
if (calleeTy->isAsync())
2947+
return false;
29452948

29462949
if (calleeTy->getRepresentation() != SILFunctionTypeRepresentation::Method)
29472950
return false;
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift-dylib(%t/%target-library-name(PrintShims)) %S/../../Inputs/print-shims.swift -module-name PrintShims -emit-module -emit-module-path %t/PrintShims.swiftmodule
3+
// RUN: %target-codesign %t/%target-library-name(PrintShims)
4+
// RUN: %target-build-swift -Xfrontend -enable-experimental-concurrency -parse-sil %s -emit-ir -I %t -L %t -lPrintShim | %FileCheck %s --check-prefix=CHECK-LL
5+
// RUN: %target-build-swift -Xfrontend -enable-experimental-concurrency -parse-sil %s -module-name main -o %t/main -I %t -L %t -lPrintShims %target-rpath(%t)
6+
// RUN: %target-codesign %t/main
7+
// RUN: %target-run %t/main %t/%target-library-name(PrintShims) | %FileCheck %s
8+
9+
// REQUIRES: executable_test
10+
// REQUIRES: swift_test_mode_optimize_none
11+
// REQUIRES: concurrency
12+
// UNSUPPORTED: use_os_stdlib
13+
14+
import Builtin
15+
import Swift
16+
import PrintShims
17+
import _Concurrency
18+
19+
sil public_external @printGeneric : $@convention(thin) <T> (@in_guaranteed T) -> ()
20+
21+
class S {
22+
deinit
23+
init()
24+
}
25+
26+
sil hidden [exact_self_class] @S_allocating_init : $@convention(method) (@thick S.Type) -> @owned S {
27+
bb0(%0 : $@thick S.Type):
28+
%1 = alloc_ref $S
29+
%2 = function_ref @$S_init : $@convention(method) (@owned S) -> @owned S
30+
%3 = apply %2(%1) : $@convention(method) (@owned S) -> @owned S
31+
return %3 : $S
32+
}
33+
34+
sil hidden @$S_init : $@convention(method) (@owned S) -> @owned S {
35+
bb0(%0 : $S):
36+
return %0 : $S
37+
}
38+
39+
sil hidden @$S_deinit : $@convention(method) (@guaranteed S) -> @owned Builtin.NativeObject {
40+
bb0(%0 : $S):
41+
%2 = unchecked_ref_cast %0 : $S to $Builtin.NativeObject
42+
return %2 : $Builtin.NativeObject
43+
}
44+
45+
sil hidden @S_deallocating_deinit : $@convention(method) (@owned S) -> () {
46+
bb0(%0 : $S):
47+
%2 = function_ref @$S_deinit : $@convention(method) (@guaranteed S) -> @owned Builtin.NativeObject
48+
%3 = apply %2(%0) : $@convention(method) (@guaranteed S) -> @owned Builtin.NativeObject
49+
%4 = unchecked_ref_cast %3 : $Builtin.NativeObject to $S
50+
dealloc_ref %4 : $S
51+
%6 = tuple ()
52+
return %6 : $()
53+
}
54+
55+
sil_vtable S {
56+
#S.init!allocator: (S.Type) -> () -> S : @S_allocating_init
57+
#S.deinit!deallocator: @S_deallocating_deinit
58+
}
59+
60+
// CHECK-LL: @classinstanceSToVoidAD =
61+
// CHECK-LL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @classinstanceSToVoid(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} {
62+
sil @classinstanceSToVoid : $@async @convention(method) (@owned S) -> () {
63+
entry(%c : $S):
64+
%class_addr = alloc_stack $S
65+
store %c to %class_addr : $*S
66+
%printGeneric = function_ref @printGeneric : $@convention(thin) <T> (@in_guaranteed T) -> ()
67+
%result = apply %printGeneric<S>(%class_addr) : $@convention(thin) <T> (@in_guaranteed T) -> () // CHECK: main.S
68+
dealloc_stack %class_addr : $*S
69+
return %result : $()
70+
}
71+
72+
// Defined in _Concurrency
73+
sil public_external @swift_task_runAndBlockThread : $@convention(thin) (@guaranteed @async @callee_guaranteed () -> ()) -> ()
74+
75+
sil @test_case : $@convention(thin) @async () -> () {
76+
%s_type = metatype $@thick S.Type
77+
%allocating_init = function_ref @S_allocating_init : $@convention(method) (@thick S.Type) -> @owned S
78+
%instance = apply %allocating_init(%s_type) : $@convention(method) (@thick S.Type) -> @owned S
79+
strong_retain %instance : $S
80+
81+
%classinstanceSToVoid = function_ref @classinstanceSToVoid : $@async @convention(method) (@owned S) -> ()
82+
%partiallyApplied = partial_apply %classinstanceSToVoid(%instance) : $@async @convention(method) (@owned S) -> ()
83+
%result = apply %partiallyApplied() : $@async @callee_owned () -> ()
84+
85+
strong_release %instance : $S
86+
87+
%void = tuple()
88+
return %void : $()
89+
}
90+
91+
sil @main : $@convention(c) (Int32, UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>) -> Int32 {
92+
bb0(%0 : $Int32, %1 : $UnsafeMutablePointer<Optional<UnsafeMutablePointer<Int8>>>):
93+
94+
%2 = function_ref @test_case : $@convention(thin) @async () -> ()
95+
%3 = thin_to_thick_function %2 : $@convention(thin) @async () -> () to $@async @callee_guaranteed () -> ()
96+
%4 = function_ref @swift_task_runAndBlockThread : $@convention(thin) (@guaranteed @async @callee_guaranteed () -> ()) -> ()
97+
%5 = apply %4(%3) : $@convention(thin) (@guaranteed @async @callee_guaranteed () -> ()) -> ()
98+
99+
%6 = integer_literal $Builtin.Int32, 0
100+
%7 = struct $Int32 (%6 : $Builtin.Int32)
101+
return %7 : $Int32
102+
}
103+

0 commit comments

Comments
 (0)