Skip to content

Commit 4f6937e

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`: the default, which determines how to set the bit based on deployment target, either statically or dynamically via `swift_async_extendedFramePointerFlags`. * `always`: always set the bit statically, regardless of deployment target. * `never`: never set the bit, regardless of deployment target. Patch by Doug Gregor <[email protected]> Differential Revision: https://reviews.llvm.org/D109392
1 parent 56b171f commit 4f6937e

File tree

7 files changed

+82
-24
lines changed

7 files changed

+82
-24
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::DeploymentBased;
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)
@@ -277,6 +278,18 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
277278
"Only fuse FP ops when the result won't be affected.")));
278279
CGBINDOPT(FuseFPOps);
279280

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

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,22 +1180,32 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
11801180
// ORR is sufficient, it is assumed a Swift kernel would initialize the TBI
11811181
// bits so that is still true.
11821182
if (HasFP && AFI->hasSwiftAsyncContext()) {
1183-
if (Subtarget.swiftAsyncContextIsDynamicallySet()) {
1184-
// The special symbol below is absolute and has a *value* that can be
1185-
// combined with the frame pointer to signal an extended frame.
1186-
BuildMI(MBB, MBBI, DL, TII->get(AArch64::LOADgot), AArch64::X16)
1187-
.addExternalSymbol("swift_async_extendedFramePointerFlags",
1188-
AArch64II::MO_GOT);
1189-
BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::FP)
1190-
.addUse(AArch64::FP)
1191-
.addUse(AArch64::X16)
1192-
.addImm(Subtarget.isTargetILP32() ? 32 : 0);
1193-
} else {
1183+
switch (MF.getTarget().Options.SwiftAsyncFramePointer) {
1184+
case SwiftAsyncFramePointerMode::DeploymentBased:
1185+
if (Subtarget.swiftAsyncContextIsDynamicallySet()) {
1186+
// The special symbol below is absolute and has a *value* that can be
1187+
// combined with the frame pointer to signal an extended frame.
1188+
BuildMI(MBB, MBBI, DL, TII->get(AArch64::LOADgot), AArch64::X16)
1189+
.addExternalSymbol("swift_async_extendedFramePointerFlags",
1190+
AArch64II::MO_GOT);
1191+
BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXrs), AArch64::FP)
1192+
.addUse(AArch64::FP)
1193+
.addUse(AArch64::X16)
1194+
.addImm(Subtarget.isTargetILP32() ? 32 : 0);
1195+
break;
1196+
}
1197+
LLVM_FALLTHROUGH;
1198+
1199+
case SwiftAsyncFramePointerMode::Always:
11941200
// ORR x29, x29, #0x1000_0000_0000_0000
11951201
BuildMI(MBB, MBBI, DL, TII->get(AArch64::ORRXri), AArch64::FP)
11961202
.addUse(AArch64::FP)
11971203
.addImm(0x1100)
11981204
.setMIFlag(MachineInstr::FrameSetup);
1205+
break;
1206+
1207+
case SwiftAsyncFramePointerMode::Never:
1208+
break;
11991209
}
12001210
}
12011211

llvm/lib/Target/X86/X86FrameLowering.cpp

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

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

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
; RUN: llc -mtriple arm64-apple-ios15.0.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
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-ios14.9.0 -swift-async-fp=always %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
24
; RUN: llc -mtriple arm64-apple-ios14.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC
5+
; RUN: llc -mtriple arm64-apple-ios14.9.0 -swift-async-fp=auto %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC
36
; RUN: llc -mtriple arm64-apple-tvos15.0.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC
47
; RUN: llc -mtriple arm64-apple-tvos14.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC
58
; RUN: llc -mtriple arm64-apple-macosx12.0.0 %s -o - | FileCheck %s --check-prefix=CHECK-STATIC

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
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-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
25
; RUN: llc -mtriple x86_64-apple-macosx11.9.0 %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC
6+
; RUN: llc -mtriple x86_64-apple-macosx11.9.0 -swift-async-fp=auto %s -o - | FileCheck %s --check-prefix=CHECK-DYNAMIC
37

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

0 commit comments

Comments
 (0)