Skip to content

Commit e7df9db

Browse files
Merge pull request swiftlang#35134 from nate-chandler/concurrency/irgen/rdar72397303
[Async CC] Pass witness metadata to callees.
2 parents fcb1864 + 98e732d commit e7df9db

File tree

5 files changed

+86
-4
lines changed

5 files changed

+86
-4
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2449,6 +2449,18 @@ class AsyncCallEmission final : public CallEmission {
24492449
auto fieldLayout = layout.getLocalContextLayout();
24502450
saveValue(fieldLayout, localExplosion, isOutlined);
24512451
}
2452+
if (auto selfMetadata = witnessMetadata->SelfMetadata) {
2453+
Explosion selfMetadataExplosion;
2454+
selfMetadataExplosion.add(selfMetadata);
2455+
auto fieldLayout = layout.getSelfMetadataLayout();
2456+
saveValue(fieldLayout, selfMetadataExplosion, isOutlined);
2457+
}
2458+
if (auto selfWitnessTable = witnessMetadata->SelfWitnessTable) {
2459+
Explosion selfWitnessTableExplosion;
2460+
selfWitnessTableExplosion.add(selfWitnessTable);
2461+
auto fieldLayout = layout.getSelfWitnessTableLayout();
2462+
saveValue(fieldLayout, selfWitnessTableExplosion, isOutlined);
2463+
}
24522464
}
24532465
void emitCallToUnmappedExplosion(llvm::CallInst *call, Explosion &out) override {
24542466
auto layout = getAsyncContextLayout();

lib/IRGen/GenProto.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2712,12 +2712,14 @@ static void save(const NecessaryBindings &bindings, IRGenFunction &IGF,
27122712
[&](GenericRequirement requirement) -> llvm::Value * {
27132713
CanType type = requirement.TypeParameter;
27142714
if (auto protocol = requirement.Protocol) {
2715-
if (auto archetype = dyn_cast<ArchetypeType>(type)) {
2715+
CanArchetypeType archetype;
2716+
ProtocolConformanceRef conformance =
2717+
bindings.getConformance(requirement);
2718+
if ((archetype = dyn_cast<ArchetypeType>(type)) && !conformance) {
27162719
auto wtable =
27172720
emitArchetypeWitnessTableRef(IGF, archetype, protocol);
27182721
return transform(requirement, wtable);
27192722
} else {
2720-
auto conformance = bindings.getConformance(requirement);
27212723
auto wtable = emitWitnessTableRef(IGF, type, conformance);
27222724
return transform(requirement, wtable);
27232725
}

lib/IRGen/NecessaryBindings.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ class NecessaryBindings {
131131
}
132132
}
133133

134-
bool forPartialApply() { return kind == Kind::PartialApply; }
135-
bool forAsyncFunction() { return kind == Kind::AsyncFunction; }
134+
bool forPartialApply() const { return kind == Kind::PartialApply; }
135+
bool forAsyncFunction() const { return kind == Kind::AsyncFunction; }
136136

137137
private:
138138
static NecessaryBindings computeBindings(IRGenModule &IGM,
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift -Xfrontend -enable-experimental-concurrency %s -emit-ir | %FileCheck %s --check-prefix=CHECK-LL
3+
// RUN: %target-build-swift -Xfrontend -enable-experimental-concurrency %s -module-name main -o %t/main
4+
// RUN: %target-codesign %t/main
5+
// RUN: %target-run %t/main | %FileCheck %s
6+
7+
// REQUIRES: executable_test
8+
// REQUIRES: swift_test_mode_optimize_none
9+
// REQUIRES: concurrency
10+
// UNSUPPORTED: use_os_stdlib
11+
12+
import _Concurrency
13+
14+
func printGeneric<T>(_ t: T) {
15+
print(t)
16+
}
17+
18+
protocol P {
19+
func f() async
20+
}
21+
22+
// CHECK: entering call_f
23+
// CHECK: entering f
24+
// CHECK: X
25+
// CHECK: main.X
26+
// CHECK: exiting f
27+
// CHECK: exiting call_f
28+
29+
// CHECK-LL: @"$s4main1PPAAE1fyyYFTu" = hidden global %swift.async_func_pointer
30+
// CHECK-LL: @"$s4main6call_fyyxYAA1PRzlFTu" = hidden global %swift.async_func_pointer
31+
// CHECK-LL: @"$s4main1XCAA1PA2aDP1fyyYFTWTu" = internal global %swift.async_func_pointer
32+
33+
extension P {
34+
// CHECK-LL: define hidden swiftcc void @"$s4main1PPAAE1fyyYF"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} {
35+
func f() async {
36+
print("entering f")
37+
printGeneric(Self.self)
38+
printGeneric(self)
39+
print("exiting f")
40+
}
41+
}
42+
43+
// CHECK-LL: define internal swiftcc void @"$s4main1XCAA1PA2aDP1fyyYFTW"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} {
44+
extension X : P {}
45+
46+
// CHECK-LL: define hidden swiftcc void @"$s4main6call_fyyxYAA1PRzlF"(%swift.task* {{%[0-9]+}}, %swift.executor* {{%[0-9]+}}, %swift.context* {{%[0-9]+}}) {{#[0-9]*}} {
47+
func call_f<T : P>(_ t: T) async {
48+
print("entering call_f")
49+
await t.f()
50+
print("exiting call_f")
51+
}
52+
53+
class X {}
54+
55+
runAsyncAndBlock {
56+
let x = X()
57+
await call_f(x)
58+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %target-swift-frontend %s -emit-ir -enable-experimental-concurrency
2+
3+
protocol P {
4+
func f<T>() async throws -> T?
5+
}
6+
extension P {
7+
func f<T>() async throws -> T? { nil }
8+
}
9+
class X: P {}
10+

0 commit comments

Comments
 (0)