Skip to content

IRGen: Emit a weak reference to swift_async_extendedFramePointerFlags when neccessary #39415

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions lib/IRGen/IRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1644,6 +1644,7 @@ bool IRGenModule::finalize() {
if (!ClangCodeGen->GetModule())
return false;

emitSwiftAsyncExtendedFrameInfoWeakRef();
emitAutolinkInfo();
emitGlobalLists();
if (DebugInfo)
Expand Down Expand Up @@ -1776,3 +1777,30 @@ TypeExpansionContext IRGenModule::getMaximalTypeExpansionContext() const {
const TypeLayoutEntry &IRGenModule::getTypeLayoutEntry(SILType T) {
return Types.getTypeLayoutEntry(T);
}


void IRGenModule::emitSwiftAsyncExtendedFrameInfoWeakRef() {
if (!hasSwiftAsyncFunctionDef || extendedFramePointerFlagsWeakRef)
return;
if (IRGen.Opts.SwiftAsyncFramePointer !=
SwiftAsyncFramePointerKind::Auto)
return;
if (isConcurrencyAvailable())
return;

// Emit a weak reference to the `swift_async_extendedFramePointerFlags` symbol
// needed by Swift async functions.
auto symbolName = "swift_async_extendedFramePointerFlags";
if ((extendedFramePointerFlagsWeakRef = Module.getGlobalVariable(symbolName)))
return;
extendedFramePointerFlagsWeakRef = new llvm::GlobalVariable(Module, Int8PtrTy, false,
llvm::GlobalValue::ExternalWeakLinkage, nullptr,
symbolName);
}

bool IRGenModule::isConcurrencyAvailable() {
auto &ctx = getSwiftModule()->getASTContext();
auto deploymentAvailability =
AvailabilityContext::forDeploymentTarget(ctx);
return deploymentAvailability.isContainedIn(ctx.getConcurrencyAvailability());
}
10 changes: 10 additions & 0 deletions lib/IRGen/IRGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -1691,7 +1691,17 @@ private: \
void addLazyConformances(const IterableDeclContext *idc);

//--- Global context emission --------------------------------------------------
bool hasSwiftAsyncFunctionDef = false;
llvm::Value *extendedFramePointerFlagsWeakRef = nullptr;

/// Emit a weak reference to the `swift_async_extendedFramePointerFlags`
/// symbol needed by Swift async functions.
void emitSwiftAsyncExtendedFrameInfoWeakRef();
public:
bool isConcurrencyAvailable();
void noteSwiftAsyncFunctionDef() {
hasSwiftAsyncFunctionDef = true;
}
void emitRuntimeRegistration();
void emitVTableStubs();
void emitTypeVerifier();
Expand Down
6 changes: 5 additions & 1 deletion lib/IRGen/IRGenSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2181,12 +2181,16 @@ void IRGenSILFunction::emitSILFunction() {
IGM.IRGen.addDynamicReplacement(CurSILFn);

auto funcTy = CurSILFn->getLoweredFunctionType();
if (funcTy->isAsync() && funcTy->getLanguage() == SILFunctionLanguage::Swift) {
bool isAsyncFn = funcTy->isAsync();
if (isAsyncFn && funcTy->getLanguage() == SILFunctionLanguage::Swift) {
emitAsyncFunctionPointer(IGM,
CurFn,
LinkEntity::forSILFunction(CurSILFn),
getAsyncContextLayout(*this).getSize());
}
if (isAsyncFn) {
IGM.noteSwiftAsyncFunctionDef();
}

// Configure the dominance resolver.
// TODO: consider re-using a dom analysis from the PassManager
Expand Down
9 changes: 1 addition & 8 deletions lib/IRGen/MetadataRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1230,13 +1230,6 @@ static MetadataResponse emitTupleTypeMetadataRef(IRGenFunction &IGF,
}
}

/// Determine whether concurrency support is available in the runtime.
static bool isConcurrencyAvailable(ASTContext &ctx) {
auto deploymentAvailability =
AvailabilityContext::forDeploymentTarget(ctx);
return deploymentAvailability.isContainedIn(ctx.getConcurrencyAvailability());
}

namespace {
/// A visitor class for emitting a reference to a metatype object.
/// This implements a "raw" access, useful for implementing cache
Expand Down Expand Up @@ -1598,7 +1591,7 @@ namespace {
}

auto *getMetadataFn = type->getGlobalActor()
? (isConcurrencyAvailable(IGF.getSwiftModule()->getASTContext())
? (IGF.IGM.isConcurrencyAvailable()
? IGF.IGM.getGetFunctionMetadataGlobalActorFn()
: IGF.IGM.getGetFunctionMetadataGlobalActorBackDeployFn())
: type->isDifferentiable()
Expand Down
4 changes: 4 additions & 0 deletions test/IRGen/swift_async_extended_frame_info.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ public func someAsyncFunction() async {
// NEVER: s31swift_async_extended_frame_info17someAsyncFunctionyyYaF:
// NEVER-NOT: _swift_async_extendedFramePointerFlags
// NEVER-NOT: btsq $60

// AUTO: .weak_reference _swift_async_extendedFramePointerFlags
// NEVER-NOT: .weak_reference _swift_async_extendedFramePointerFlags
// ALWAYS-NOT: .weak_reference _swift_async_extendedFramePointerFlags