Skip to content

SwiftAsync: use runtime-provided flag for extended frame if back-deploying #3191

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 2 commits into from
Sep 3, 2021
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
22 changes: 17 additions & 5 deletions llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1110,11 +1110,23 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
// ORR is sufficient, it is assumed a Swift kernel would initialize the TBI
// bits so that is still true.
if (HasFP && AFI->hasSwiftAsyncContext()) {
// ORR x29, x29, #0x1000_0000_0000_0000
BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXri), AArch64::FP)
.addUse(AArch64::FP)
.addImm(0x1100)
.setMIFlag(MachineInstr::FrameSetup);
if (Subtarget.swiftAsyncContextIsDynamicallySet()) {
// The special symbol below is absolute and has a *value* that can be
// combined with the frame pointer to signal an extended frame.
BuildMI(MBB, MBBI, DL, TII->get(AArch64::LOADgot), AArch64::X16)
.addExternalSymbol("swift_async_extendedFramePointerFlags",
AArch64II::MO_GOT);
BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::FP)
.addUse(AArch64::FP)
.addUse(AArch64::X16)
.addImm(Subtarget.isTargetILP32() ? 32 : 0);
} else {
// ORR x29, x29, #0x1000_0000_0000_0000
BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXri), AArch64::FP)
.addUse(AArch64::FP)
.addImm(0x1100)
.setMIFlag(MachineInstr::FrameSetup);
}
}

// All calls are tail calls in GHC calling conv, and functions have no
Expand Down
25 changes: 25 additions & 0 deletions llvm/lib/Target/AArch64/AArch64Subtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,31 @@ class AArch64Subtarget final : public AArch64GenSubtargetInfo {
}
}

/// Return whether FrameLowering should always set the "extended frame
/// present" bit in FP, or set it based on a symbol in the runtime.
bool swiftAsyncContextIsDynamicallySet() const {
// Older OS versions (particularly system unwinders) are confused by the
// Swift extended frame, so when building code that might be run on them we
// must dynamically query the concurrency library to determine whether
// extended frames should be flagged as present.
const Triple &TT = getTargetTriple();

unsigned Major, Minor, Micro;
TT.getOSVersion(Major, Minor, Micro);
switch(TT.getOS()) {
default:
return false;
case Triple::IOS:
case Triple::TvOS:
return Major < 15;
case Triple::WatchOS:
return Major < 8;
case Triple::MacOSX:
case Triple::Darwin:
return Major < 12;
}
}

void mirFileLoaded(MachineFunction &MF) const override;

// Return the known range for the bit length of SVE data registers. A value
Expand Down
22 changes: 17 additions & 5 deletions llvm/lib/Target/X86/X86FrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1342,11 +1342,23 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
unsigned StackProbeSize = STI.getTargetLowering()->getStackProbeSize(MF);

if (HasFP && X86FI->hasSwiftAsyncContext()) {
BuildMI(MBB, MBBI, DL, TII.get(X86::BTS64ri8),
MachineFramePtr)
.addUse(MachineFramePtr)
.addImm(60)
.setMIFlag(MachineInstr::FrameSetup);
if (STI.swiftAsyncContextIsDynamicallySet()) {
// The special symbol below is absolute and has a *value* suitable to be
// combined with the frame pointer directly.
BuildMI(MBB, MBBI, DL, TII.get(X86::OR64rm), MachineFramePtr)
.addUse(MachineFramePtr)
.addUse(X86::RIP)
.addImm(1)
.addUse(X86::NoRegister)
.addExternalSymbol("swift_async_extendedFramePointerFlags",
X86II::MO_GOTPCREL)
.addUse(X86::NoRegister);
} else {
BuildMI(MBB, MBBI, DL, TII.get(X86::BTS64ri8), MachineFramePtr)
.addUse(MachineFramePtr)
.addImm(60)
.setMIFlag(MachineInstr::FrameSetup);
}
}

// Re-align the stack on 64-bit if the x86-interrupt calling convention is
Expand Down
25 changes: 25 additions & 0 deletions llvm/lib/Target/X86/X86Subtarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,31 @@ class X86Subtarget final : public X86GenSubtargetInfo {
/// Return true if the subtarget allows calls to immediate address.
bool isLegalToCallImmediateAddr() const;

/// Return whether FrameLowering should always set the "extended frame
/// present" bit in FP, or set it based on a symbol in the runtime.
bool swiftAsyncContextIsDynamicallySet() const {
// Older OS versions (particularly system unwinders) are confused by the
// Swift extended frame, so when building code that might be run on them we
// must dynamically query the concurrency library to determine whether
// extended frames should be flagged as present.
const Triple &TT = getTargetTriple();

unsigned Major, Minor, Micro;
TT.getOSVersion(Major, Minor, Micro);
switch(TT.getOS()) {
default:
return false;
case Triple::IOS:
case Triple::TvOS:
return Major < 15;
case Triple::WatchOS:
return Major < 8;
case Triple::MacOSX:
case Triple::Darwin:
return Major < 12;
}
}

/// If we are using indirect thunks, we need to expand indirectbr to avoid it
/// lowering to an actual indirect jump.
bool enableIndirectBrExpand() const override {
Expand Down
6 changes: 3 additions & 3 deletions llvm/test/CodeGen/AArch64/swift-async.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; RUN: llc -mtriple=arm64-apple-ios %s -o - | FileCheck %s --check-prefixes=CHECK-NOAUTH,CHECK
; RUN: llc -mtriple=arm64-apple-ios -mcpu=apple-a13 %s -o - | FileCheck %s --check-prefixes=CHECK-NOAUTH,CHECK
; RUN: llc -mtriple=arm64e-apple-ios %s -o - | FileCheck %s --check-prefixes=CHECK-AUTH,CHECK
; RUN: llc -mtriple=arm64-apple-ios15 %s -o - | FileCheck %s --check-prefixes=CHECK-NOAUTH,CHECK
; RUN: llc -mtriple=arm64-apple-ios15 -mcpu=apple-a13 %s -o - | FileCheck %s --check-prefixes=CHECK-NOAUTH,CHECK
; RUN: llc -mtriple=arm64e-apple-ios15 %s -o - | FileCheck %s --check-prefixes=CHECK-AUTH,CHECK

; Important details in prologue:
; * x22 is stored just below x29
Expand Down
25 changes: 25 additions & 0 deletions llvm/test/CodeGen/AArch64/swift-dynamic-async-frame.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
; RUN: llc -mtriple arm64-apple-ios15.0.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
; RUN: llc -mtriple arm64-apple-ios14.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC
; RUN: llc -mtriple arm64-apple-tvos15.0.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
; RUN: llc -mtriple arm64-apple-tvos14.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC
; RUN: llc -mtriple arm64-apple-macosx12.0.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
; RUN: llc -mtriple arm64-apple-macosx11.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC
; RUN: llc -mtriple arm64_32-apple-watchos8.0.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
; RUN: llc -mtriple arm64_32-apple-watchos7.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC-32

; CHECK-STATIC-LABEL: foo:
; CHECK-STATIC: orr x29, x29, #0x1000000000000000

; CHECK-DYNAMIC-LABEL: foo:
; CHECK-DYNAMIC: adrp x16, _swift_async_extendedFramePointerFlags@GOTPAGE
; CHECK-DYNAMIC: ldr x16, [x16, _swift_async_extendedFramePointerFlags@GOTPAGEOFF]
; CHECK-DYNAMIC: orr x29, x29, x16

; CHECK-DYNAMIC-32-LABEL: foo:
; CHECK-DYNAMIC-32: adrp x16, _swift_async_extendedFramePointerFlags@GOTPAGE
; CHECK-DYNAMIC-32: ldr w16, [x16, _swift_async_extendedFramePointerFlags@GOTPAGEOFF]
; CHECK-DYNAMIC-32: orr x29, x29, x16, lsl #32

define void @foo(i8* swiftasync) "frame-pointer"="all" {
ret void
}
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/X86/swift-async.ll
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
; RUN: llc -mtriple=x86_64-apple-darwin %s -o - | FileCheck %s
; RUN: llc -mtriple=x86_64-apple-macosx12.0 %s -o - | FileCheck %s
; RUN: llc -mtriple=i686-apple-darwin %s -o - | FileCheck %s --check-prefix=CHECK-32


Expand Down
12 changes: 12 additions & 0 deletions llvm/test/CodeGen/X86/swift-dynamic-async-frame.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
; RUN: llc -mtriple x86_64-apple-macosx12.0.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
; RUN: llc -mtriple x86_64-apple-macosx11.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC

; CHECK-STATIC-LABEL: foo:
; CHECK-STATIC: btsq $60, %rbp

; CHECK-DYNAMIC-LABEL: foo:
; CHECK-DYNAMIC: orq _swift_async_extendedFramePointerFlags@GOTPCREL(%rip), %rbp

define void @foo(i8* swiftasync) "frame-pointer"="all" {
ret void
}
2 changes: 2 additions & 0 deletions llvm/test/lit.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ def get_asan_rtlib():
asan_rtlib = get_asan_rtlib()
if asan_rtlib:
ld64_cmd = 'DYLD_INSERT_LIBRARIES={} {}'.format(asan_rtlib, ld64_cmd)
if config.osx_sysroot:
ld64_cmd = '{} -syslibroot {}'.format(ld64_cmd, config.osx_sysroot)

ocamlc_command = '%s ocamlc -cclib -L%s %s' % (
config.ocamlfind_executable, config.llvm_lib_dir, config.ocaml_flags)
Expand Down
1 change: 1 addition & 0 deletions llvm/test/lit.site.cfg.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ config.lit_tools_dir = path(r"@LLVM_LIT_TOOLS_DIR@")
config.python_executable = "@Python3_EXECUTABLE@"
config.gold_executable = "@GOLD_EXECUTABLE@"
config.ld64_executable = "@LD64_EXECUTABLE@"
config.osx_sysroot = "@CMAKE_OSX_SYSROOT@"
config.ocamlfind_executable = "@OCAMLFIND@"
config.have_ocamlopt = @HAVE_OCAMLOPT@
config.have_ocaml_ounit = @HAVE_OCAML_OUNIT@
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/tools/lto/hide-linkonce-odr.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
; RUN: llvm-as %s -o %t.o
; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -dylib -arch x86_64 -macosx_version_min 10.10.0 -o %t.dylib %t.o -save-temps -undefined dynamic_lookup -exported_symbol _c -exported_symbol _b -exported_symbol _GlobLinkonce
; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -dylib -arch x86_64 -macosx_version_min 10.10.0 -o %t.dylib %t.o -save-temps -undefined dynamic_lookup -exported_symbol _c -exported_symbol _b -exported_symbol _GlobLinkonce -lSystem

; RUN: llvm-dis %t.dylib.lto.opt.bc -o - | FileCheck --check-prefix=IR %s
; check that @a is no longer a linkonce_odr definition
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/tools/lto/no-bitcode.s
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
; libLTO.dylib shouldn't assert on invalid inputs.
; RUN: llvm-mc -triple=arm64-apple-ios7.0.0 -filetype=obj -o %t.o
; RUN: llvm-ar r %t.a %t.o
; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -O0 -o %t.dylib %t.a
; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -O0 -o %t.dylib %t.a -lSystem
4 changes: 2 additions & 2 deletions llvm/test/tools/lto/opt-level.ll
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
; RUN: llvm-as %s -o %t.o
; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -O0 -o %t.dylib %t.o
; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -O0 -o %t.dylib %t.o -lSystem
; RUN: llvm-nm --no-llvm-bc %t.dylib | FileCheck --check-prefix=CHECK-O0 %s
; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -O2 -o %t.dylib %t.o
; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -O2 -o %t.dylib %t.o -lSystem
; RUN: llvm-nm --no-llvm-bc %t.dylib | FileCheck --check-prefix=CHECK-O2 %s

target triple = "x86_64-apple-macosx10.8.0"
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/tools/lto/print-stats.ll
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
; RUN: llvm-as %s -o %t.o
; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -stats -o %t.dylib %t.o 2>&1 | FileCheck --check-prefix=STATS %s
; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -o %t.dylib %t.o 2>&1 | FileCheck --check-prefix=NO_STATS %s
; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -mllvm -stats -o %t.dylib %t.o -lSystem 2>&1 | FileCheck --check-prefix=STATS %s
; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -arch x86_64 -dylib -o %t.dylib %t.o -lSystem 2>&1 | FileCheck --check-prefix=NO_STATS %s
; REQUIRES: asserts

target triple = "x86_64-apple-macosx10.8.0"
Expand Down