Skip to content

Add flag -swift-async-framepointer=auto,never,always to control swift extended frame information emission #39245

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
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
12 changes: 11 additions & 1 deletion include/swift/AST/IRGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ enum class IRGenEmbedMode : unsigned {
EmbedBitcode
};

enum class SwiftAsyncFramePointerKind : unsigned {
Auto, // Choose Swift async extended frame info based on deployment target.
Always, // Unconditionally emit Swift async extended frame info.
Never, // Don't emit Swift async extended frame info.
};

using clang::PointerAuthSchema;

struct PointerAuthOptions : clang::PointerAuthOptions {
Expand Down Expand Up @@ -282,6 +288,8 @@ class IRGenOptions {

IRGenLLVMLTOKind LLVMLTOKind : 2;

SwiftAsyncFramePointerKind SwiftAsyncFramePointer : 2;

/// Add names to LLVM values.
unsigned HasValueNamesSetting : 1;
unsigned ValueNames : 1;
Expand Down Expand Up @@ -393,7 +401,9 @@ class IRGenOptions {
Playground(false),
EmitStackPromotionChecks(false), FunctionSections(false),
PrintInlineTree(false), EmbedMode(IRGenEmbedMode::None),
LLVMLTOKind(IRGenLLVMLTOKind::None), HasValueNamesSetting(false),
LLVMLTOKind(IRGenLLVMLTOKind::None),
SwiftAsyncFramePointer(SwiftAsyncFramePointerKind::Always),
HasValueNamesSetting(false),
ValueNames(false), EnableReflectionMetadata(true),
EnableReflectionNames(true), EnableAnonymousContextMangledNames(false),
ForcePublicLinkage(false), LazyInitializeClassMetadata(false),
Expand Down
4 changes: 4 additions & 0 deletions include/swift/Option/FrontendOptions.td
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,10 @@ def type_info_dump_filter_EQ : Joined<["-"], "type-info-dump-filter=">,
Flags<[FrontendOption]>,
HelpText<"One of 'all', 'resilient' or 'fragile'">;

def swift_async_frame_pointer_EQ : Joined<["-"], "swift-async-frame-pointer=">,
Flags<[FrontendOption]>,
HelpText<"One of 'auto', 'always' or 'never'">;

def previous_module_installname_map_file
: Separate<["-"], "previous-module-installname-map-file">, MetaVarName<"<path>">,
HelpText<"Path to a Json file indicating module name to installname map for @_originallyDefinedIn">;
Expand Down
20 changes: 20 additions & 0 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1908,6 +1908,26 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
Opts.VirtualFunctionElimination = true;
}

// Default to disabling swift async extended frame info on anything but
// darwin. Other platforms are unlikely to have support for extended frame
// pointer information.
if (!Triple.isOSDarwin()) {
Opts.SwiftAsyncFramePointer = SwiftAsyncFramePointerKind::Never;
}
if (const Arg *A = Args.getLastArg(OPT_swift_async_frame_pointer_EQ)) {
StringRef mode(A->getValue());
if (mode == "auto")
Opts.SwiftAsyncFramePointer = SwiftAsyncFramePointerKind::Auto;
else if (mode == "always")
Opts.SwiftAsyncFramePointer = SwiftAsyncFramePointerKind::Always;
else if (mode == "never")
Opts.SwiftAsyncFramePointer = SwiftAsyncFramePointerKind::Never;
else {
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
A->getAsString(Args), A->getValue());
}
}

return false;
}

Expand Down
12 changes: 12 additions & 0 deletions lib/IRGen/IRGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,18 @@ swift::getIRTargetOptions(const IRGenOptions &Opts, ASTContext &Ctx) {
TargetOpts.GlobalISelAbort = GlobalISelAbortMode::DisableWithDiag;
}

switch (Opts.SwiftAsyncFramePointer) {
case SwiftAsyncFramePointerKind::Never:
TargetOpts.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::Never;
break;
case SwiftAsyncFramePointerKind::Auto:
TargetOpts.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::DeploymentBased;
break;
case SwiftAsyncFramePointerKind::Always:
TargetOpts.SwiftAsyncFramePointer = SwiftAsyncFramePointerMode::Always;
break;
}

clang::TargetOptions &ClangOpts = Clang->getTargetInfo().getTargetOpts();
return std::make_tuple(TargetOpts, ClangOpts.CPU, ClangOpts.Features, ClangOpts.Triple);
}
Expand Down
1 change: 1 addition & 0 deletions stdlib/public/BackDeployConcurrency/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,6 @@ set(swift_concurrency_options
set(swift_concurrency_extra_sources
"../BackDeployConcurrency/Exclusivity.cpp"
"../BackDeployConcurrency/Metadata.cpp")
set(swift_concurrency_async_fp_mode "never")

add_subdirectory(../Concurrency stdlib/public/BackDeployConcurrency)
23 changes: 22 additions & 1 deletion stdlib/public/Concurrency/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,26 @@ if(SWIFT_CONCURRENCY_USES_DISPATCH)
endif()
endif()


set(SWIFT_RUNTIME_CONCURRENCY_C_FLAGS)
set(SWIFT_RUNTIME_CONCURRENCY_SWIFT_FLAGS)

if(NOT swift_concurrency_async_fp_mode)
set(swift_concurrency_async_fp_mode "always")
endif()

# Don't emit extended frame info on platforms other than darwin, system
# backtracer and system debugger are unlikely to support it.
if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
list(APPEND SWIFT_RUNTIME_CONCURRENCY_C_FLAGS
"-fswift-async-fp=${swift_concurrency_async_fp_mode}")
list(APPEND SWIFT_RUNTIME_CONCURRENCY_SWIFT_FLAGS
"-Xfrontend"
"-swift-async-frame-pointer=${swift_concurrency_async_fp_mode}")
else()
list(APPEND SWIFT_RUNTIME_CONCURRENCY_C_FLAGS "-fswift-async-fp=never")
endif()

add_swift_target_library(swift_Concurrency ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_STDLIB
../CompatibilityOverride/CompatibilityOverride.cpp
Actor.cpp
Expand Down Expand Up @@ -91,13 +111,14 @@ add_swift_target_library(swift_Concurrency ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} I
LINK_LIBRARIES ${swift_concurrency_link_libraries}

C_COMPILE_FLAGS
-Dswift_Concurrency_EXPORTS
-Dswift_Concurrency_EXPORTS ${SWIFT_RUNTIME_CONCURRENCY_C_FLAGS}
SWIFT_COMPILE_FLAGS
${SWIFT_STANDARD_LIBRARY_SWIFT_FLAGS}
-parse-stdlib
-Xfrontend -enable-experimental-concurrency
-Xfrontend -define-availability
-Xfrontend "SwiftStdlib 5.5:macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0"
${SWIFT_RUNTIME_CONCURRENCY_SWIFT_FLAGS}
LINK_FLAGS "${SWIFT_RUNTIME_CONCURRENCY_SWIFT_LINK_FLAGS}"
${swift_concurrency_options}
INSTALL_IN_COMPONENT ${swift_concurrency_install_component}
Expand Down
23 changes: 23 additions & 0 deletions test/IRGen/swift_async_extended_frame_info.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// RUN: %target-swift-frontend -disable-availability-checking -target x86_64-apple-macosx11 %s -S | %FileCheck -check-prefix=ALWAYS %s
// RUN: %target-swift-frontend -disable-availability-checking -target x86_64-apple-macosx12 %s -S | %FileCheck -check-prefix=ALWAYS %s
// RUN: %target-swift-frontend -disable-availability-checking -swift-async-frame-pointer=auto -target x86_64-apple-macosx11 %s -S | %FileCheck -check-prefix=AUTO %s
// RUN: %target-swift-frontend -disable-availability-checking -swift-async-frame-pointer=auto -target x86_64-apple-macosx12 %s -S | %FileCheck -check-prefix=ALWAYS %s
// RUN: %target-swift-frontend -disable-availability-checking -swift-async-frame-pointer=never -target x86_64-apple-macosx11 %s -S | %FileCheck -check-prefix=NEVER %s
// RUN: %target-swift-frontend -disable-availability-checking -swift-async-frame-pointer=never -target x86_64-apple-macosx12 %s -S | %FileCheck -check-prefix=NEVER %s
// RUN: %target-swift-frontend -disable-availability-checking -swift-async-frame-pointer=always -target x86_64-apple-macosx11 %s -S | %FileCheck -check-prefix=ALWAYS %s
// RUN: %target-swift-frontend -disable-availability-checking -swift-async-frame-pointer=always -target x86_64-apple-macosx12 %s -S | %FileCheck -check-prefix=ALWAYS %s

// REQUIRES: OS=macosx

public func someAsyncFunction() async {
}

// AUTO: s31swift_async_extended_frame_info17someAsyncFunctionyyYaF:
// AUTO: _swift_async_extendedFramePointerFlags

// ALWAYS: s31swift_async_extended_frame_info17someAsyncFunctionyyYaF:
// ALWAYS: btsq $60

// NEVER: s31swift_async_extended_frame_info17someAsyncFunctionyyYaF:
// NEVER-NOT: _swift_async_extendedFramePointerFlags
// NEVER-NOT: btsq $60