Skip to content

Commit a773db7

Browse files
DougGregoraschwaighofer
authored andcommitted
Add a command-line flag to control the Swift extended async frame info.
Introduce a new command-line flag `-swift-async-fp={auto|always|never}` that controls how code generation sets the Swift extended async frame info bit. There are three possibilities: * `auto`: which determines how to set the bit based on deployment target, either statically or dynamically via `swift_async_extendedFramePointerFlags`. * `always`: the default, always set the bit statically, regardless of deployment target. * `never`: never set the bit, regardless of deployment target. Patch by Doug Gregor <[email protected]> Reviewed By: doug.gregor Differential Revision: https://reviews.llvm.org/D109392
1 parent baa18ee commit a773db7

File tree

7 files changed

+99
-29
lines changed

7 files changed

+99
-29
lines changed

llvm/include/llvm/CodeGen/CommandFlags.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ llvm::FloatABI::ABIType getFloatABIForCalls();
7474

7575
llvm::FPOpFusion::FPOpFusionMode getFuseFPOps();
7676

77+
SwiftAsyncFramePointerMode getSwiftAsyncFramePointer();
78+
7779
bool getDontPlaceZerosInBSS();
7880

7981
bool getEnableGuaranteedTailCallOpt();

llvm/include/llvm/Target/TargetOptions.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,17 @@ namespace llvm {
110110
DisableWithDiag // Disable the abort but emit a diagnostic on failure.
111111
};
112112

113+
/// Indicates when and how the Swift async frame pointer bit should be set.
114+
enum class SwiftAsyncFramePointerMode {
115+
/// Determine whether to set the bit statically or dynamically based
116+
/// on the deployment target.
117+
DeploymentBased,
118+
/// Always set the bit.
119+
Always,
120+
/// Never set the bit.
121+
Never,
122+
};
123+
113124
class TargetOptions {
114125
public:
115126
TargetOptions()
@@ -219,6 +230,11 @@ namespace llvm {
219230
/// selection fails to lower/select an instruction.
220231
GlobalISelAbortMode GlobalISelAbort = GlobalISelAbortMode::Enable;
221232

233+
/// Control when and how the Swift async frame pointer bit should
234+
/// be set.
235+
SwiftAsyncFramePointerMode SwiftAsyncFramePointer =
236+
SwiftAsyncFramePointerMode::Always;
237+
222238
/// UseInitArray - Use .init_array instead of .ctors for static
223239
/// constructors.
224240
unsigned UseInitArray : 1;

llvm/lib/CodeGen/CommandFlags.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ CGOPT(DenormalMode::DenormalModeKind, DenormalFP32Math)
6565
CGOPT(bool, EnableHonorSignDependentRoundingFPMath)
6666
CGOPT(FloatABI::ABIType, FloatABIForCalls)
6767
CGOPT(FPOpFusion::FPOpFusionMode, FuseFPOps)
68+
CGOPT(SwiftAsyncFramePointerMode, SwiftAsyncFramePointer)
6869
CGOPT(bool, DontPlaceZerosInBSS)
6970
CGOPT(bool, EnableGuaranteedTailCallOpt)
7071
CGOPT(bool, DisableTailCalls)
@@ -278,6 +279,18 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
278279
"Only fuse FP ops when the result won't be affected.")));
279280
CGBINDOPT(FuseFPOps);
280281

282+
static cl::opt<SwiftAsyncFramePointerMode> SwiftAsyncFramePointer(
283+
"swift-async-fp",
284+
cl::desc("Determine when the Swift async frame pointer should be set"),
285+
cl::init(SwiftAsyncFramePointerMode::Always),
286+
cl::values(clEnumValN(SwiftAsyncFramePointerMode::DeploymentBased, "auto",
287+
"Determine based on deployment target"),
288+
clEnumValN(SwiftAsyncFramePointerMode::Always, "always",
289+
"Always set the bit"),
290+
clEnumValN(SwiftAsyncFramePointerMode::Never, "never",
291+
"Never set the bit")));
292+
CGBINDOPT(SwiftAsyncFramePointer);
293+
281294
static cl::opt<bool> DontPlaceZerosInBSS(
282295
"nozero-initialized-in-bss",
283296
cl::desc("Don't place zero-initialized symbols into bss section"),
@@ -539,7 +552,7 @@ codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
539552
Options.ThreadModel = getThreadModel();
540553
Options.EABIVersion = getEABIVersion();
541554
Options.DebuggerTuning = getDebuggerTuningOpt();
542-
555+
Options.SwiftAsyncFramePointer = getSwiftAsyncFramePointer();
543556
return Options;
544557
}
545558

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,22 +1158,32 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
11581158
// ORR is sufficient, it is assumed a Swift kernel would initialize the TBI
11591159
// bits so that is still true.
11601160
if (HasFP && AFI->hasSwiftAsyncContext()) {
1161-
if (Subtarget.swiftAsyncContextIsDynamicallySet()) {
1162-
// The special symbol below is absolute and has a *value* that can be
1163-
// combined with the frame pointer to signal an extended frame.
1164-
BuildMI(MBB, MBBI, DL, TII->get(AArch64::LOADgot), AArch64::X16)
1165-
.addExternalSymbol("swift_async_extendedFramePointerFlags",
1166-
AArch64II::MO_GOT);
1167-
BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::FP)
1168-
.addUse(AArch64::FP)
1169-
.addUse(AArch64::X16)
1170-
.addImm(Subtarget.isTargetILP32() ? 32 : 0);
1171-
} else {
1161+
switch (MF.getTarget().Options.SwiftAsyncFramePointer) {
1162+
case SwiftAsyncFramePointerMode::DeploymentBased:
1163+
if (Subtarget.swiftAsyncContextIsDynamicallySet()) {
1164+
// The special symbol below is absolute and has a *value* that can be
1165+
// combined with the frame pointer to signal an extended frame.
1166+
BuildMI(MBB, MBBI, DL, TII->get(AArch64::LOADgot), AArch64::X16)
1167+
.addExternalSymbol("swift_async_extendedFramePointerFlags",
1168+
AArch64II::MO_GOT);
1169+
BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::FP)
1170+
.addUse(AArch64::FP)
1171+
.addUse(AArch64::X16)
1172+
.addImm(Subtarget.isTargetILP32() ? 32 : 0);
1173+
break;
1174+
}
1175+
LLVM_FALLTHROUGH;
1176+
1177+
case SwiftAsyncFramePointerMode::Always:
11721178
// ORR x29, x29, #0x1000_0000_0000_0000
11731179
BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXri), AArch64::FP)
11741180
.addUse(AArch64::FP)
11751181
.addImm(0x1100)
11761182
.setMIFlag(MachineInstr::FrameSetup);
1183+
break;
1184+
1185+
case SwiftAsyncFramePointerMode::Never:
1186+
break;
11771187
}
11781188
}
11791189

llvm/lib/Target/X86/X86FrameLowering.cpp

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,22 +1364,32 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
13641364
unsigned StackProbeSize = STI.getTargetLowering()->getStackProbeSize(MF);
13651365

13661366
if (HasFP && X86FI->hasSwiftAsyncContext()) {
1367-
if (STI.swiftAsyncContextIsDynamicallySet()) {
1368-
// The special symbol below is absolute and has a *value* suitable to be
1369-
// combined with the frame pointer directly.
1370-
BuildMI(MBB, MBBI, DL, TII.get(X86::OR64rm), MachineFramePtr)
1371-
.addUse(MachineFramePtr)
1372-
.addUse(X86::RIP)
1373-
.addImm(1)
1374-
.addUse(X86::NoRegister)
1375-
.addExternalSymbol("swift_async_extendedFramePointerFlags",
1376-
X86II::MO_GOTPCREL)
1377-
.addUse(X86::NoRegister);
1378-
} else {
1367+
switch (MF.getTarget().Options.SwiftAsyncFramePointer) {
1368+
case SwiftAsyncFramePointerMode::DeploymentBased:
1369+
if (STI.swiftAsyncContextIsDynamicallySet()) {
1370+
// The special symbol below is absolute and has a *value* suitable to be
1371+
// combined with the frame pointer directly.
1372+
BuildMI(MBB, MBBI, DL, TII.get(X86::OR64rm), MachineFramePtr)
1373+
.addUse(MachineFramePtr)
1374+
.addUse(X86::RIP)
1375+
.addImm(1)
1376+
.addUse(X86::NoRegister)
1377+
.addExternalSymbol("swift_async_extendedFramePointerFlags",
1378+
X86II::MO_GOTPCREL)
1379+
.addUse(X86::NoRegister);
1380+
break;
1381+
}
1382+
LLVM_FALLTHROUGH;
1383+
1384+
case SwiftAsyncFramePointerMode::Always:
13791385
BuildMI(MBB, MBBI, DL, TII.get(X86::BTS64ri8), MachineFramePtr)
13801386
.addUse(MachineFramePtr)
13811387
.addImm(60)
13821388
.setMIFlag(MachineInstr::FrameSetup);
1389+
break;
1390+
1391+
case SwiftAsyncFramePointerMode::Never:
1392+
break;
13831393
}
13841394
}
13851395

llvm/test/CodeGen/AArch64/swift-dynamic-async-frame.ll

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
11
; RUN: llc -mtriple arm64-apple-ios15.0.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
2-
; RUN: llc -mtriple arm64-apple-ios14.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC
2+
; RUN: llc -mtriple arm64-apple-ios15.0.0 -swift-async-fp=auto %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
3+
; RUN: llc -mtriple arm64-apple-ios15.0.0 -swift-async-fp=never %s -o - | FileCheck %s --check-prefix=CHECK-NEVER
4+
; RUN: llc -mtriple arm64-apple-ios14.9.0 -swift-async-fp=always %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
5+
; RUN: llc -mtriple arm64-apple-ios14.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
6+
; RUN: llc -mtriple arm64-apple-ios14.9.0 -swift-async-fp=auto %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC
37
; RUN: llc -mtriple arm64-apple-tvos15.0.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
4-
; RUN: llc -mtriple arm64-apple-tvos14.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC
8+
; RUN: llc -mtriple arm64-apple-tvos14.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
59
; RUN: llc -mtriple arm64-apple-macosx12.0.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
6-
; RUN: llc -mtriple arm64-apple-macosx11.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC
10+
; RUN: llc -mtriple arm64-apple-macosx11.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
711
; RUN: llc -mtriple arm64_32-apple-watchos8.0.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
8-
; RUN: llc -mtriple arm64_32-apple-watchos7.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC-32
12+
; RUN: llc -mtriple arm64_32-apple-watchos7.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
13+
; RUN: llc -mtriple arm64_32-apple-watchos7.9.0 -swift-async-fp=auto %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC-32
914

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

18+
; CHECK-NEVER-LABEL: foo:
19+
; CHECK-NEVER-NOT: orr x29, x29, #0x1000000000000000
20+
; CHECK-NEVER-NOT: _swift_async_extendedFramePointerFlags
21+
1322
; CHECK-DYNAMIC-LABEL: foo:
1423
; CHECK-DYNAMIC: adrp x16, _swift_async_extendedFramePointerFlags@GOTPAGE
1524
; CHECK-DYNAMIC: ldr x16, [x16, _swift_async_extendedFramePointerFlags@GOTPAGEOFF]
Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
; RUN: llc -mtriple x86_64-apple-macosx12.0.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
2-
; RUN: llc -mtriple x86_64-apple-macosx11.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC
2+
; RUN: llc -mtriple x86_64-apple-macosx12.0.0 -swift-async-fp=always %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
3+
; RUN: llc -mtriple x86_64-apple-macosx12.0.0 -swift-async-fp=auto %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
4+
; RUN: llc -mtriple x86_64-apple-macosx11.9.0 -swift-async-fp=always %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
5+
; RUN: llc -mtriple x86_64-apple-macosx11.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
6+
; RUN: llc -mtriple x86_64-apple-macosx11.9.0 -swift-async-fp=auto %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC
7+
; RUN: llc -mtriple x86_64-apple-macosx11.9.0 -swift-async-fp=always %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
8+
; RUN: llc -mtriple x86_64-apple-macosx11.9.0 -swift-async-fp=never %s -o - | FileCheck %s --check-prefix=CHECK-NEVER
39

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

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

16+
; CHECK-NEVER-LABEL: foo:
17+
; CHECK-NEVER-NOT: btsq $60, %rbp
18+
; CHECK-NEVER-NOT: _swift_async_extendedFramePointerFlags
19+
1020
define void @foo(i8* swiftasync) "frame-pointer"="all" {
1121
ret void
1222
}

0 commit comments

Comments
 (0)