Skip to content

Commit f7264e3

Browse files
committed
[IRGen] Only use a stub for swift_coroFrameAlloc when we need it
swift_coroFrameAlloc was introduced in the Swift 6.2 runtime. Give it the appropriate availability in IRGen, so that it gets weak availability when needed (per the deployment target). Then, only create the stub function for calling into swift_coroFrameAlloc or malloc (when the former isn't available) when we're back-deploying to a runtime prior to Swift 6.2. This is a small code size/performance win when allocating coroutine frames on Swift 6.2-or-newer platforms. This has a side effect of fixing a bug in Embedded Swift, where the swift_coroFrameAlloc was getting unconditionally set to have weak external linkage despite behind defined in the same LLVM module (because it comes from the standard library). Fixes rdar://149695139 / issue #80947.
1 parent 865c643 commit f7264e3

9 files changed

+34
-9
lines changed

include/swift/AST/FeatureAvailability.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ FEATURE(ValueGenericType, (6, 2))
8282
FEATURE(InitRawStructMetadata2, (6, 2))
8383
FEATURE(CustomGlobalExecutors, (6, 2))
8484
FEATURE(TaskExecutor, (6, 2))
85+
FEATURE(TypedCoroAlloc, (6, 2))
8586

8687
FEATURE(Differentiation, FUTURE)
8788
FEATURE(ClearSensitive, FUTURE)

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2059,7 +2059,8 @@ FUNCTION(Free, c, free, C_CC, AlwaysAvailable,
20592059
NO_ATTRS,
20602060
EFFECT(RuntimeEffect::Deallocating),
20612061
UNKNOWN_MEMEFFECTS)
2062-
FUNCTION(CoroFrameAlloc, Swift, swift_coroFrameAlloc, C_CC, AlwaysAvailable,
2062+
FUNCTION(CoroFrameAlloc, Swift, swift_coroFrameAlloc, C_CC,
2063+
TypedCoroAllocAvailability,
20632064
RETURNS(Int8PtrTy),
20642065
ARGS(SizeTy, Int64Ty),
20652066
NO_ATTRS,

lib/Driver/DarwinToolChains.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,8 @@ toolchains::Darwin::addArgsToLinkStdlib(ArgStringList &Arguments,
366366
runtimeCompatibilityVersion = llvm::VersionTuple(5, 8);
367367
} else if (value == "6.0") {
368368
runtimeCompatibilityVersion = llvm::VersionTuple(6, 0);
369+
} else if (value == "6.2") {
370+
runtimeCompatibilityVersion = llvm::VersionTuple(6, 2);
369371
} else if (value == "none") {
370372
runtimeCompatibilityVersion = std::nullopt;
371373
} else {

lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3699,6 +3699,8 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
36993699
runtimeCompatibilityVersion = llvm::VersionTuple(5, 8);
37003700
} else if (version == "6.0") {
37013701
runtimeCompatibilityVersion = llvm::VersionTuple(6, 0);
3702+
} else if (version == "6.2") {
3703+
runtimeCompatibilityVersion = llvm::VersionTuple(6, 2);
37023704
} else {
37033705
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
37043706
versionArg->getAsString(Args), version);

lib/IRGen/GenFunc.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -863,15 +863,20 @@ CanType irgen::getArgumentLoweringType(CanType type, SILParameterInfo paramInfo,
863863
}
864864

865865
llvm::Constant *irgen::getCoroFrameAllocStubFn(IRGenModule &IGM) {
866+
// If the coroutine allocation function is always available, call it directly.
867+
auto coroAllocPtr = IGM.getCoroFrameAllocFn();
868+
auto coroAllocFn = dyn_cast<llvm::Function>(coroAllocPtr);
869+
if (coroAllocFn->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
870+
return coroAllocFn;
871+
872+
// Otherwise, create a stub function to call it when available, or malloc
873+
// when it isn't.
866874
return IGM.getOrCreateHelperFunction(
867875
"__swift_coroFrameAllocStub", IGM.Int8PtrTy,
868876
{IGM.SizeTy, IGM.Int64Ty},
869877
[&](IRGenFunction &IGF) {
870878
auto parameters = IGF.collectParameters();
871879
auto *size = parameters.claimNext();
872-
auto coroAllocPtr = IGF.IGM.getCoroFrameAllocFn();
873-
auto coroAllocFn = dyn_cast<llvm::Function>(coroAllocPtr);
874-
coroAllocFn->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
875880
auto *coroFrameAllocFn = IGF.IGM.getOpaquePtr(coroAllocPtr);
876881
auto *nullSwiftCoroFrameAlloc = IGF.Builder.CreateCmp(
877882
llvm::CmpInst::Predicate::ICMP_NE, coroFrameAllocFn,

lib/IRGen/IRGenModule.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,14 @@ namespace RuntimeConstants {
902902
return RuntimeAvailability::AlwaysAvailable;
903903
}
904904

905+
RuntimeAvailability TypedCoroAllocAvailability(ASTContext &context) {
906+
auto featureAvailability = context.getTypedCoroAllocAvailability();
907+
if (!isDeploymentAvailabilityContainedIn(context, featureAvailability)) {
908+
return RuntimeAvailability::ConditionallyAvailable;
909+
}
910+
return RuntimeAvailability::AlwaysAvailable;
911+
}
912+
905913
RuntimeAvailability ConcurrencyDiscardingTaskGroupAvailability(ASTContext &context) {
906914
auto featureAvailability =
907915
context.getConcurrencyDiscardingTaskGroupAvailability();

test/IRGen/yield_once_enable_emit_type_malloc_coro_frame.sil

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// REQUIRES: OS=macosx || OS=iOS
2-
// RUN: %target-swift-frontend -emit-irgen %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-%target-ptrsize-%target-ptrauth
1+
// REQUIRES: OS=macosx
2+
// RUN: %target-swift-frontend -target %target-cpu-apple-macosx15.0 -emit-irgen %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-%target-ptrsize-%target-ptrauth
33

44
import Builtin
55

@@ -44,6 +44,9 @@ unwind:
4444
// CHECK-NEXT: unreachable
4545
}
4646

47+
// CHECK-32: declare extern_weak ptr @swift_coroFrameAlloc(i32, i64)
48+
// CHECK-64: declare extern_weak ptr @swift_coroFrameAlloc(i64, i64)
49+
4750
// CHECK-32: define linkonce_odr hidden ptr @__swift_coroFrameAllocStub(i32 %0, i64 %1) #1{{( comdat)?}} {
4851
// CHECK-64: define linkonce_odr hidden ptr @__swift_coroFrameAllocStub(i64 %0, i64 %1) #1{{( comdat)?}} {
4952
// CHECK: [[T0:%.*]] = icmp ne ptr @swift_coroFrameAlloc, null
@@ -59,9 +62,6 @@ unwind:
5962
// CHECK-64: [[T2:%.*]] = call ptr @malloc(i64 %0)
6063
// CHECK: ret ptr [[T2]]
6164

62-
// CHECK-32: declare extern_weak ptr @swift_coroFrameAlloc(i32, i64)
63-
// CHECK-64: declare extern_weak ptr @swift_coroFrameAlloc(i64, i64)
64-
6565
// CHECK-LABEL: declare{{( dllimport)?}}{{( protected)?}} swiftcc void @"$sIetA_TC"
6666
// CHECK-SAME: (ptr noalias dereferenceable([[BUFFER_SIZE]]), i1)
6767

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// REQUIRES: OS=iOS
2+
// RUN: %target-swift-frontend -target %target-cpu-apple-iphoneos16.0 -emit-irgen %S/yield_once_enable_emit_type_malloc_coro_frame.sil | %FileCheck %S/yield_once_enable_emit_type_malloc_coro_frame.sil --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-%target-ptrsize-%target-ptrauth
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// REQUIRES: OS=macosx
2+
// RUN: %target-swift-frontend -target %target-cpu-apple-macosx26.0 -emit-irgen %S/yield_once_enable_emit_type_malloc_coro_frame.sil | %FileCheck %s
3+
4+
// CHECK-NOT: __swift_coroFrameAllocStub

0 commit comments

Comments
 (0)