diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp --- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -1109,8 +1109,7 @@ const TargetInstrInfo *TII = Subtarget.getInstrInfo(); MachineModuleInfo &MMI = MF.getMMI(); AArch64FunctionInfo *AFI = MF.getInfo(); - 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 @@ .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 @@ 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 @@ } } - if (needsFrameMoves) { + if (EmitCFI) { // An example of the prologue: // // .globl __foo @@ -2490,27 +2490,29 @@ .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(unsigned(dwarf::DW_OP_breg18)), - static_cast(-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()->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(unsigned(dwarf::DW_OP_breg18)), + static_cast(-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 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -7427,11 +7427,13 @@ .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()->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 @@ .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()->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.h b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h --- a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h +++ b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h @@ -173,6 +173,12 @@ /// The stack slot where the Swift asynchronous context is stored. int SwiftAsyncContextFrameIdx = std::numeric_limits::max(); + /// True if the function need unwind information. + mutable Optional NeedsDwarfUnwindInfo; + + /// True if the function need asynchronous unwind information. + mutable Optional NeedsDwarfAsyncUnwindInfo; + public: explicit AArch64FunctionInfo(MachineFunction &MF); @@ -408,6 +414,9 @@ } int getSwiftAsyncContextFrameIdx() const { return SwiftAsyncContextFrameIdx; } + bool needsDwarfUnwindInfo() const; + bool needsAsyncDwarfUnwindInfo() const; + private: // Hold the lists of LOHs. MILOHContainer LOHContainerSet; diff --git a/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp b/llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.cpp --- 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 @@ 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/test/CodeGen/AArch64/machine-outliner-retaddr-sign-regsave.mir b/llvm/test/CodeGen/AArch64/machine-outliner-retaddr-sign-regsave.mir --- 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 @@ --- # 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 --- 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" } ... ---