Skip to content

Commit 24638e1

Browse files
aschwaighoferDougGregor
authored andcommitted
IRGen: Emit a weak reference to swift_async_extendedFramePointerFlags when neccessary
When we deploy to a minimum target that is not known to support extended frame information the function prolog of Swift async functions will contain a reference to swift_async_extendedFramePointerFlags. This reference needs to be weak like any async symbols. rdar://83412550 (cherry picked from commit 16a5d69)
1 parent 214e517 commit 24638e1

File tree

4 files changed

+61
-1
lines changed

4 files changed

+61
-1
lines changed

lib/IRGen/IRGenModule.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1610,6 +1610,7 @@ bool IRGenModule::finalize() {
16101610
if (!ClangCodeGen->GetModule())
16111611
return false;
16121612

1613+
emitSwiftAsyncExtendedFrameInfoWeakRef();
16131614
emitAutolinkInfo();
16141615
emitGlobalLists();
16151616
if (DebugInfo)
@@ -1742,3 +1743,45 @@ TypeExpansionContext IRGenModule::getMaximalTypeExpansionContext() const {
17421743
const TypeLayoutEntry &IRGenModule::getTypeLayoutEntry(SILType T) {
17431744
return Types.getTypeLayoutEntry(T);
17441745
}
1746+
1747+
/// Return whether FrameLowering should always set the "extended frame
1748+
/// present" bit in FP, or set it based on a symbol in the runtime.
1749+
static bool isSwiftAsyncContextIsDynamicallySet(llvm::Triple TT) {
1750+
// Older OS versions (particularly system unwinders) are confused by the
1751+
// Swift extended frame, so when building code that might be run on them we
1752+
// must dynamically query the concurrency library to determine whether
1753+
// extended frames should be flagged as present.
1754+
unsigned Major, Minor, Micro;
1755+
TT.getOSVersion(Major, Minor, Micro);
1756+
switch(TT.getOS()) {
1757+
default:
1758+
return false;
1759+
case llvm::Triple::IOS:
1760+
case llvm::Triple::TvOS:
1761+
return Major < 15;
1762+
case llvm::Triple::WatchOS:
1763+
return Major < 8;
1764+
case llvm::Triple::MacOSX:
1765+
case llvm::Triple::Darwin:
1766+
return Major < 12;
1767+
}
1768+
}
1769+
1770+
void IRGenModule::emitSwiftAsyncExtendedFrameInfoWeakRef() {
1771+
if (!hasSwiftAsyncFunctionDef || extendedFramePointerFlagsWeakRef)
1772+
return;
1773+
if (IRGen.Opts.SwiftAsyncFramePointer !=
1774+
SwiftAsyncFramePointerKind::Auto)
1775+
return;
1776+
if (!isSwiftAsyncContextIsDynamicallySet(Triple))
1777+
return;
1778+
1779+
// Emit a weak reference to the `swift_async_extendedFramePointerFlags` symbol
1780+
// needed by Swift async functions.
1781+
auto symbolName = "swift_async_extendedFramePointerFlags";
1782+
if ((extendedFramePointerFlagsWeakRef = Module.getGlobalVariable(symbolName)))
1783+
return;
1784+
extendedFramePointerFlagsWeakRef = new llvm::GlobalVariable(Module, Int8PtrTy, false,
1785+
llvm::GlobalValue::ExternalWeakLinkage, nullptr,
1786+
symbolName);
1787+
}

lib/IRGen/IRGenModule.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,7 +1691,16 @@ private: \
16911691
void addLazyConformances(const IterableDeclContext *idc);
16921692

16931693
//--- Global context emission --------------------------------------------------
1694+
bool hasSwiftAsyncFunctionDef = false;
1695+
llvm::Value *extendedFramePointerFlagsWeakRef = nullptr;
1696+
1697+
/// Emit a weak reference to the `swift_async_extendedFramePointerFlags`
1698+
/// symbol needed by Swift async functions.
1699+
void emitSwiftAsyncExtendedFrameInfoWeakRef();
16941700
public:
1701+
void noteSwiftAsyncFunctionDef() {
1702+
hasSwiftAsyncFunctionDef = true;
1703+
}
16951704
void emitRuntimeRegistration();
16961705
void emitVTableStubs();
16971706
void emitTypeVerifier();

lib/IRGen/IRGenSIL.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2183,12 +2183,16 @@ void IRGenSILFunction::emitSILFunction() {
21832183
IGM.IRGen.addDynamicReplacement(CurSILFn);
21842184

21852185
auto funcTy = CurSILFn->getLoweredFunctionType();
2186-
if (funcTy->isAsync() && funcTy->getLanguage() == SILFunctionLanguage::Swift) {
2186+
bool isAsyncFn = funcTy->isAsync();
2187+
if (isAsyncFn && funcTy->getLanguage() == SILFunctionLanguage::Swift) {
21872188
emitAsyncFunctionPointer(IGM,
21882189
CurFn,
21892190
LinkEntity::forSILFunction(CurSILFn),
21902191
getAsyncContextLayout(*this).getSize());
21912192
}
2193+
if (isAsyncFn) {
2194+
IGM.noteSwiftAsyncFunctionDef();
2195+
}
21922196

21932197
// Configure the dominance resolver.
21942198
// TODO: consider re-using a dom analysis from the PassManager

test/IRGen/swift_async_extended_frame_info.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,7 @@ public func someAsyncFunction() async {
2121
// NEVER: s31swift_async_extended_frame_info17someAsyncFunctionyyYaF:
2222
// NEVER-NOT: _swift_async_extendedFramePointerFlags
2323
// NEVER-NOT: btsq $60
24+
25+
// AUTO: .weak_reference _swift_async_extendedFramePointerFlags
26+
// NEVER-NOT: .weak_reference _swift_async_extendedFramePointerFlags
27+
// ALWAYS-NOT: .weak_reference _swift_async_extendedFramePointerFlags

0 commit comments

Comments
 (0)