[llvm] 25e9292 - [AArch64] Async unwind - helper functions to decide on CFI emission
Momchil Velikov via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 24 10:18:31 PST 2022
Author: Momchil Velikov
Date: 2022-02-24T18:16:50Z
New Revision: 25e92920c9d136be9771f519ba773f4aa2232ba2
URL: https://github.com/llvm/llvm-project/commit/25e92920c9d136be9771f519ba773f4aa2232ba2
DIFF: https://github.com/llvm/llvm-project/commit/25e92920c9d136be9771f519ba773f4aa2232ba2.diff
LOG: [AArch64] Async unwind - helper functions to decide on CFI emission
Reviewed By: efriedma
Differential Revision: https://reviews.llvm.org/D112327
Added:
Modified:
llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-regsave.mir
llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-sp-mod.mir
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index a4d20735e2b15..93daf02731801 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -1109,8 +1109,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
const TargetInstrInfo *TII = Subtarget.getInstrInfo();
MachineModuleInfo &MMI = MF.getMMI();
AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
- bool needsFrameMoves =
- MF.needsFrameMoves() && !MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
+ bool EmitCFI = AFI->needsDwarfUnwindInfo();
bool HasFP = hasFP(MF);
bool NeedsWinCFI = needsWinCFI(MF);
bool HasWinCFI = false;
@@ -1145,12 +1144,13 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
.addReg(AArch64::LR)
.addReg(AArch64::SP, RegState::InternalRead);
MI.setMIFlag(MachineInstr::FrameSetup);
-
- unsigned CFIIndex =
- MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr));
- BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
- .addCFIIndex(CFIIndex)
- .setMIFlags(MachineInstr::FrameSetup);
+ if (EmitCFI) {
+ unsigned CFIIndex =
+ MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr));
+ BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex)
+ .setMIFlags(MachineInstr::FrameSetup);
+ }
}
// We signal the presence of a Swift extended frame to external tools by
@@ -1227,7 +1227,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
emitFrameOffset(MBB, MBBI, DL, AArch64::SP, AArch64::SP,
StackOffset::getFixed(-NumBytes), TII,
MachineInstr::FrameSetup, false, NeedsWinCFI, &HasWinCFI);
- if (needsFrameMoves) {
+ if (EmitCFI) {
// Label used to tie together the PROLOG_LABEL and the MachineMoves.
MCSymbol *FrameLabel = MMI.getContext().createTempSymbol();
// Encode the stack size of the leaf function.
@@ -1533,7 +1533,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
}
}
- if (needsFrameMoves) {
+ if (EmitCFI) {
// An example of the prologue:
//
// .globl __foo
@@ -2490,27 +2490,29 @@ bool AArch64FrameLowering::spillCalleeSavedRegisters(
.addImm(8)
.setMIFlag(MachineInstr::FrameSetup);
+ // This instruction also makes x18 live-in to the entry block.
+ MBB.addLiveIn(AArch64::X18);
+
if (NeedsWinCFI)
BuildMI(MBB, MI, DL, TII.get(AArch64::SEH_Nop))
.setMIFlag(MachineInstr::FrameSetup);
- // Emit a CFI instruction that causes 8 to be subtracted from the value of
- // x18 when unwinding past this frame.
- static const char CFIInst[] = {
- dwarf::DW_CFA_val_expression,
- 18, // register
- 2, // length
- static_cast<char>(unsigned(dwarf::DW_OP_breg18)),
- static_cast<char>(-8) & 0x7f, // addend (sleb128)
- };
- unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createEscape(
- nullptr, StringRef(CFIInst, sizeof(CFIInst))));
- BuildMI(MBB, MI, DL, TII.get(AArch64::CFI_INSTRUCTION))
- .addCFIIndex(CFIIndex)
- .setMIFlag(MachineInstr::FrameSetup);
-
- // This instruction also makes x18 live-in to the entry block.
- MBB.addLiveIn(AArch64::X18);
+ if (MF.getInfo<AArch64FunctionInfo>()->needsDwarfUnwindInfo()) {
+ // Emit a CFI instruction that causes 8 to be subtracted from the value of
+ // x18 when unwinding past this frame.
+ static const char CFIInst[] = {
+ dwarf::DW_CFA_val_expression,
+ 18, // register
+ 2, // length
+ static_cast<char>(unsigned(dwarf::DW_OP_breg18)),
+ static_cast<char>(-8) & 0x7f, // addend (sleb128)
+ };
+ unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createEscape(
+ nullptr, StringRef(CFIInst, sizeof(CFIInst))));
+ BuildMI(MBB, MI, DL, TII.get(AArch64::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex)
+ .setMIFlag(MachineInstr::FrameSetup);
+ }
}
if (homogeneousPrologEpilog(MF)) {
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
index e17515b974cee..041c1698efa5d 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp
@@ -7427,11 +7427,13 @@ static void signOutlinedFunction(MachineFunction &MF, MachineBasicBlock &MBB,
.addReg(AArch64::SP, RegState::InternalRead);
MI.setMIFlag(MachineInstr::FrameSetup);
- unsigned CFIIndex =
- MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr));
- BuildMI(MBB, MBBPAC, DebugLoc(), TII->get(AArch64::CFI_INSTRUCTION))
- .addCFIIndex(CFIIndex)
- .setMIFlags(MachineInstr::FrameSetup);
+ if (MF.getInfo<AArch64FunctionInfo>()->needsDwarfUnwindInfo()) {
+ unsigned CFIIndex =
+ MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr));
+ BuildMI(MBB, MBBPAC, DebugLoc(), TII->get(AArch64::CFI_INSTRUCTION))
+ .addCFIIndex(CFIIndex)
+ .setMIFlags(MachineInstr::FrameSetup);
+ }
// If v8.3a features are available we can replace a RET instruction by
// RETAA or RETAB and omit the AUT instructions
@@ -7518,24 +7520,26 @@ void AArch64InstrInfo::buildOutlinedFrame(
.addImm(-16);
It = MBB.insert(It, STRXpre);
- const TargetSubtargetInfo &STI = MF.getSubtarget();
- const MCRegisterInfo *MRI = STI.getRegisterInfo();
- unsigned DwarfReg = MRI->getDwarfRegNum(AArch64::LR, true);
-
- // Add a CFI saying the stack was moved 16 B down.
- int64_t StackPosEntry =
- MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, 16));
- BuildMI(MBB, It, DebugLoc(), get(AArch64::CFI_INSTRUCTION))
- .addCFIIndex(StackPosEntry)
- .setMIFlags(MachineInstr::FrameSetup);
-
- // Add a CFI saying that the LR that we want to find is now 16 B higher than
- // before.
- int64_t LRPosEntry =
- MF.addFrameInst(MCCFIInstruction::createOffset(nullptr, DwarfReg, -16));
- BuildMI(MBB, It, DebugLoc(), get(AArch64::CFI_INSTRUCTION))
- .addCFIIndex(LRPosEntry)
- .setMIFlags(MachineInstr::FrameSetup);
+ if (MF.getInfo<AArch64FunctionInfo>()->needsDwarfUnwindInfo()) {
+ const TargetSubtargetInfo &STI = MF.getSubtarget();
+ const MCRegisterInfo *MRI = STI.getRegisterInfo();
+ unsigned DwarfReg = MRI->getDwarfRegNum(AArch64::LR, true);
+
+ // Add a CFI saying the stack was moved 16 B down.
+ int64_t StackPosEntry =
+ MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, 16));
+ BuildMI(MBB, It, DebugLoc(), get(AArch64::CFI_INSTRUCTION))
+ .addCFIIndex(StackPosEntry)
+ .setMIFlags(MachineInstr::FrameSetup);
+
+ // Add a CFI saying that the LR that we want to find is now 16 B higher
+ // than before.
+ int64_t LRPosEntry = MF.addFrameInst(
+ MCCFIInstruction::createOffset(nullptr, DwarfReg, -16));
+ BuildMI(MBB, It, DebugLoc(), get(AArch64::CFI_INSTRUCTION))
+ .addCFIIndex(LRPosEntry)
+ .setMIFlags(MachineInstr::FrameSetup);
+ }
// Insert a restore before the terminator for the function.
MachineInstr *LDRXpost = BuildMI(MF, DebugLoc(), get(AArch64::LDRXpost))
diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
index 7d08f073fd81d..16b6cd3aa0081 100644
--- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp
@@ -15,6 +15,7 @@
#include "AArch64MachineFunctionInfo.h"
#include "AArch64InstrInfo.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
@@ -115,3 +116,19 @@ bool AArch64FunctionInfo::shouldSignReturnAddress() const {
MF.getFrameInfo().getCalleeSavedInfo(),
[](const auto &Info) { return Info.getReg() == AArch64::LR; }));
}
+
+bool AArch64FunctionInfo::needsDwarfUnwindInfo() const {
+ if (!NeedsDwarfUnwindInfo.hasValue())
+ NeedsDwarfUnwindInfo = MF.needsFrameMoves() &&
+ !MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
+
+ return NeedsDwarfUnwindInfo.getValue();
+}
+
+bool AArch64FunctionInfo::needsAsyncDwarfUnwindInfo() const {
+ if (!NeedsDwarfAsyncUnwindInfo.hasValue())
+ NeedsDwarfAsyncUnwindInfo =
+ needsDwarfUnwindInfo() &&
+ MF.getFunction().getUWTableKind() == UWTableKind::Async;
+ return NeedsDwarfAsyncUnwindInfo.getValue();
+}
diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
index e5e08e6c00d67..1248d15a3bd56 100644
--- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h
@@ -173,6 +173,12 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
/// The stack slot where the Swift asynchronous context is stored.
int SwiftAsyncContextFrameIdx = std::numeric_limits<int>::max();
+ /// True if the function need unwind information.
+ mutable Optional<bool> NeedsDwarfUnwindInfo;
+
+ /// True if the function need asynchronous unwind information.
+ mutable Optional<bool> NeedsDwarfAsyncUnwindInfo;
+
public:
explicit AArch64FunctionInfo(MachineFunction &MF);
@@ -408,6 +414,9 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
}
int getSwiftAsyncContextFrameIdx() const { return SwiftAsyncContextFrameIdx; }
+ bool needsDwarfUnwindInfo() const;
+ bool needsAsyncDwarfUnwindInfo() const;
+
private:
// Hold the lists of LOHs.
MILOHContainer LOHContainerSet;
diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-regsave.mir b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-regsave.mir
index 9e2ea8a6d1045..5a99fe72f1082 100644
--- a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-regsave.mir
+++ b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-regsave.mir
@@ -9,18 +9,19 @@
ret void
}
- define void @bar() #0 {
+ define void @bar() #1 {
ret void
}
- attributes #0 = { nounwind "sign-return-address"="non-leaf" "sign-return-address-key"="b_key" minsize noinline noredzone "frame-pointer"="all" }
+ attributes #0 = { nounwind "sign-return-address"="non-leaf" "sign-return-address-key"="b_key" minsize noinline noredzone "frame-pointer"="all" }
+ attributes #1 = { nounwind uwtable "sign-return-address"="non-leaf" "sign-return-address-key"="b_key" minsize noinline noredzone "frame-pointer"="all" }
...
---
# CHECK-LABEL: name: foo
# CHECK: bb.0:
# CHECK: frame-setup EMITBKEY
# CHECK-NEXT: frame-setup PACIBSP
-# CHECK-NEXT: frame-setup CFI_INSTRUCTION negate_ra_sign_state
+# CHECK-NOT: frame-setup CFI_INSTRUCTION negate_ra_sign_state
# CHECK: bb.1:
# CHECK: BL @[[OUTLINED_FUNCTION:OUTLINED_FUNCTION_[0-9]+]]
# CHECK: bb.2:
@@ -79,6 +80,9 @@ body: |
---
# CHECK: name: bar
# CHECK: bb.0:
+# CHECK: frame-setup EMITBKEY
+# CHECK-NEXT: frame-setup PACIBSP implicit-def $lr, implicit $lr, implicit $sp
+# CHECK-NEXT: frame-setup CFI_INSTRUCTION negate_ra_sign_state
# CHECK-NOT: OUTLINED_FUNCTION_
# CHECK: bb.1:
# CHECK-NOT: OUTLINED_FUNCTION_
diff --git a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-sp-mod.mir b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-sp-mod.mir
index d20053b40991b..43d3a856d6461 100644
--- a/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-sp-mod.mir
+++ b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-sp-mod.mir
@@ -58,7 +58,7 @@
ret void
}
- attributes #0 = { nounwind "sign-return-address"="all" "sign-return-address-key"="a_key" noinline noredzone "frame-pointer"="all" }
+ attributes #0 = { nounwind uwtable "sign-return-address"="all" "sign-return-address-key"="a_key" noinline noredzone "frame-pointer"="all" }
...
---
More information about the llvm-commits
mailing list