mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[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.
This commit is contained in:
@@ -82,6 +82,7 @@ FEATURE(ValueGenericType, (6, 2))
|
||||
FEATURE(InitRawStructMetadata2, (6, 2))
|
||||
FEATURE(CustomGlobalExecutors, (6, 2))
|
||||
FEATURE(TaskExecutor, (6, 2))
|
||||
FEATURE(TypedCoroAlloc, (6, 2))
|
||||
|
||||
FEATURE(Differentiation, FUTURE)
|
||||
FEATURE(ClearSensitive, FUTURE)
|
||||
|
||||
@@ -2059,7 +2059,8 @@ FUNCTION(Free, c, free, C_CC, AlwaysAvailable,
|
||||
NO_ATTRS,
|
||||
EFFECT(RuntimeEffect::Deallocating),
|
||||
UNKNOWN_MEMEFFECTS)
|
||||
FUNCTION(CoroFrameAlloc, Swift, swift_coroFrameAlloc, C_CC, AlwaysAvailable,
|
||||
FUNCTION(CoroFrameAlloc, Swift, swift_coroFrameAlloc, C_CC,
|
||||
TypedCoroAllocAvailability,
|
||||
RETURNS(Int8PtrTy),
|
||||
ARGS(SizeTy, Int64Ty),
|
||||
NO_ATTRS,
|
||||
|
||||
@@ -366,6 +366,8 @@ toolchains::Darwin::addArgsToLinkStdlib(ArgStringList &Arguments,
|
||||
runtimeCompatibilityVersion = llvm::VersionTuple(5, 8);
|
||||
} else if (value == "6.0") {
|
||||
runtimeCompatibilityVersion = llvm::VersionTuple(6, 0);
|
||||
} else if (value == "6.2") {
|
||||
runtimeCompatibilityVersion = llvm::VersionTuple(6, 2);
|
||||
} else if (value == "none") {
|
||||
runtimeCompatibilityVersion = std::nullopt;
|
||||
} else {
|
||||
|
||||
@@ -3699,6 +3699,8 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
|
||||
runtimeCompatibilityVersion = llvm::VersionTuple(5, 8);
|
||||
} else if (version == "6.0") {
|
||||
runtimeCompatibilityVersion = llvm::VersionTuple(6, 0);
|
||||
} else if (version == "6.2") {
|
||||
runtimeCompatibilityVersion = llvm::VersionTuple(6, 2);
|
||||
} else {
|
||||
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
|
||||
versionArg->getAsString(Args), version);
|
||||
|
||||
@@ -863,15 +863,20 @@ CanType irgen::getArgumentLoweringType(CanType type, SILParameterInfo paramInfo,
|
||||
}
|
||||
|
||||
llvm::Constant *irgen::getCoroFrameAllocStubFn(IRGenModule &IGM) {
|
||||
// If the coroutine allocation function is always available, call it directly.
|
||||
auto coroAllocPtr = IGM.getCoroFrameAllocFn();
|
||||
auto coroAllocFn = dyn_cast<llvm::Function>(coroAllocPtr);
|
||||
if (coroAllocFn->getLinkage() != llvm::GlobalValue::ExternalWeakLinkage)
|
||||
return coroAllocFn;
|
||||
|
||||
// Otherwise, create a stub function to call it when available, or malloc
|
||||
// when it isn't.
|
||||
return IGM.getOrCreateHelperFunction(
|
||||
"__swift_coroFrameAllocStub", IGM.Int8PtrTy,
|
||||
{IGM.SizeTy, IGM.Int64Ty},
|
||||
[&](IRGenFunction &IGF) {
|
||||
auto parameters = IGF.collectParameters();
|
||||
auto *size = parameters.claimNext();
|
||||
auto coroAllocPtr = IGF.IGM.getCoroFrameAllocFn();
|
||||
auto coroAllocFn = dyn_cast<llvm::Function>(coroAllocPtr);
|
||||
coroAllocFn->setLinkage(llvm::GlobalValue::ExternalWeakLinkage);
|
||||
auto *coroFrameAllocFn = IGF.IGM.getOpaquePtr(coroAllocPtr);
|
||||
auto *nullSwiftCoroFrameAlloc = IGF.Builder.CreateCmp(
|
||||
llvm::CmpInst::Predicate::ICMP_NE, coroFrameAllocFn,
|
||||
|
||||
@@ -902,6 +902,14 @@ namespace RuntimeConstants {
|
||||
return RuntimeAvailability::AlwaysAvailable;
|
||||
}
|
||||
|
||||
RuntimeAvailability TypedCoroAllocAvailability(ASTContext &context) {
|
||||
auto featureAvailability = context.getTypedCoroAllocAvailability();
|
||||
if (!isDeploymentAvailabilityContainedIn(context, featureAvailability)) {
|
||||
return RuntimeAvailability::ConditionallyAvailable;
|
||||
}
|
||||
return RuntimeAvailability::AlwaysAvailable;
|
||||
}
|
||||
|
||||
RuntimeAvailability ConcurrencyDiscardingTaskGroupAvailability(ASTContext &context) {
|
||||
auto featureAvailability =
|
||||
context.getConcurrencyDiscardingTaskGroupAvailability();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// REQUIRES: OS=macosx || OS=iOS
|
||||
// RUN: %target-swift-frontend -emit-irgen %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-%target-ptrsize-%target-ptrauth
|
||||
// REQUIRES: OS=macosx
|
||||
// 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
|
||||
|
||||
import Builtin
|
||||
|
||||
@@ -44,6 +44,9 @@ unwind:
|
||||
// CHECK-NEXT: unreachable
|
||||
}
|
||||
|
||||
// CHECK-32: declare extern_weak ptr @swift_coroFrameAlloc(i32, i64)
|
||||
// CHECK-64: declare extern_weak ptr @swift_coroFrameAlloc(i64, i64)
|
||||
|
||||
// CHECK-32: define linkonce_odr hidden ptr @__swift_coroFrameAllocStub(i32 %0, i64 %1) #1{{( comdat)?}} {
|
||||
// CHECK-64: define linkonce_odr hidden ptr @__swift_coroFrameAllocStub(i64 %0, i64 %1) #1{{( comdat)?}} {
|
||||
// CHECK: [[T0:%.*]] = icmp ne ptr @swift_coroFrameAlloc, null
|
||||
@@ -59,9 +62,6 @@ unwind:
|
||||
// CHECK-64: [[T2:%.*]] = call ptr @malloc(i64 %0)
|
||||
// CHECK: ret ptr [[T2]]
|
||||
|
||||
// CHECK-32: declare extern_weak ptr @swift_coroFrameAlloc(i32, i64)
|
||||
// CHECK-64: declare extern_weak ptr @swift_coroFrameAlloc(i64, i64)
|
||||
|
||||
// CHECK-LABEL: declare{{( dllimport)?}}{{( protected)?}} swiftcc void @"$sIetA_TC"
|
||||
// CHECK-SAME: (ptr noalias dereferenceable([[BUFFER_SIZE]]), i1)
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
// REQUIRES: OS=iOS
|
||||
// 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
|
||||
@@ -0,0 +1,4 @@
|
||||
// REQUIRES: OS=macosx
|
||||
// RUN: %target-swift-frontend -target %target-cpu-apple-macosx26.0 -emit-irgen %S/yield_once_enable_emit_type_malloc_coro_frame.sil | %FileCheck %s
|
||||
|
||||
// CHECK-NOT: __swift_coroFrameAllocStub
|
||||
Reference in New Issue
Block a user