diff --git a/include/swift/AST/IRGenOptions.h b/include/swift/AST/IRGenOptions.h index 427bc6e28fecf..9f51d44d38d20 100644 --- a/include/swift/AST/IRGenOptions.h +++ b/include/swift/AST/IRGenOptions.h @@ -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 { @@ -282,6 +288,8 @@ class IRGenOptions { IRGenLLVMLTOKind LLVMLTOKind : 2; + SwiftAsyncFramePointerKind SwiftAsyncFramePointer : 2; + /// Add names to LLVM values. unsigned HasValueNamesSetting : 1; unsigned ValueNames : 1; @@ -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), diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td index 5a3ff6410fd72..3b36485cb2f1d 100644 --- a/include/swift/Option/FrontendOptions.td +++ b/include/swift/Option/FrontendOptions.td @@ -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<"">, HelpText<"Path to a Json file indicating module name to installname map for @_originallyDefinedIn">; diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 10a74a9461651..40f3a44a0af90 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -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; } diff --git a/lib/IRGen/IRGen.cpp b/lib/IRGen/IRGen.cpp index 31ed912b0a3a3..905c5063a9e4f 100644 --- a/lib/IRGen/IRGen.cpp +++ b/lib/IRGen/IRGen.cpp @@ -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); } diff --git a/stdlib/public/BackDeployConcurrency/CMakeLists.txt b/stdlib/public/BackDeployConcurrency/CMakeLists.txt index beabf8a25bd42..514120348a080 100644 --- a/stdlib/public/BackDeployConcurrency/CMakeLists.txt +++ b/stdlib/public/BackDeployConcurrency/CMakeLists.txt @@ -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) diff --git a/stdlib/public/Concurrency/CMakeLists.txt b/stdlib/public/Concurrency/CMakeLists.txt index 7376eac880275..c35cac8d85936 100644 --- a/stdlib/public/Concurrency/CMakeLists.txt +++ b/stdlib/public/Concurrency/CMakeLists.txt @@ -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 @@ -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} diff --git a/test/IRGen/swift_async_extended_frame_info.swift b/test/IRGen/swift_async_extended_frame_info.swift new file mode 100644 index 0000000000000..70349cddd2c03 --- /dev/null +++ b/test/IRGen/swift_async_extended_frame_info.swift @@ -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