diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h --- a/llvm/include/llvm/CodeGen/AsmPrinter.h +++ b/llvm/include/llvm/CodeGen/AsmPrinter.h @@ -157,6 +157,13 @@ TimerGroupDescription(TimerGroupDescription) {} }; + // Flags representing which CFI section is required for a function/module. + enum class CFISection : unsigned { + None = 0, ///< Do not emit either .eh_frame or .debug_frame + EH = 1, ///< Emit .eh_frame + Debug = 2 ///< Emit .debug_frame + }; + private: MCSymbol *CurrentFnEnd = nullptr; @@ -199,8 +206,8 @@ /// context. PseudoProbeHandler *PP = nullptr; - /// If the current module uses dwarf CFI annotations strictly for debugging. - bool isCFIMoveForDebugging = false; + /// CFISection type the module needs i.e. either .eh_frame or .debug_frame. + CFISection ModuleCFISection = CFISection::None; protected: explicit AsmPrinter(TargetMachine &TM, std::unique_ptr Streamer); @@ -357,12 +364,14 @@ void emitRemarksSection(remarks::RemarkStreamer &RS); - enum CFIMoveType { CFI_M_None, CFI_M_EH, CFI_M_Debug }; - CFIMoveType needsCFIMoves() const; + /// Get the CFISection type for a function. + CFISection getFunctionCFISectionType(const Function &F) const; + + /// Get the CFISection type for a function. + CFISection getFunctionCFISectionType(const MachineFunction &MF) const; - /// Returns false if needsCFIMoves() == CFI_M_EH for any function - /// in the module. - bool needsOnlyDebugCFIMoves() const { return isCFIMoveForDebugging; } + /// Get the CFISection type for the module. + CFISection getModuleCFISectionType() const { return ModuleCFISection; } bool needsSEHMoves(); diff --git a/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp b/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp --- a/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/ARMException.cpp @@ -39,13 +39,13 @@ if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM) getTargetStreamer().emitFnStart(); // See if we need call frame info. - AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves(); - assert(MoveType != AsmPrinter::CFI_M_EH && + AsmPrinter::CFISection CFISecType = Asm->getFunctionCFISectionType(*MF); + assert(CFISecType != AsmPrinter::CFISection::EH && "non-EH CFI not yet supported in prologue with EHABI lowering"); - if (MoveType == AsmPrinter::CFI_M_Debug) { + if (CFISecType == AsmPrinter::CFISection::Debug) { if (!hasEmittedCFISections) { - if (Asm->needsOnlyDebugCFIMoves()) + if (Asm->getModuleCFISectionType() == AsmPrinter::CFISection::Debug) Asm->OutStreamer->emitCFISections(false, true); hasEmittedCFISections = true; } diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -354,21 +354,18 @@ case ExceptionHandling::SjLj: case ExceptionHandling::DwarfCFI: case ExceptionHandling::ARM: - isCFIMoveForDebugging = true; - if (MAI->getExceptionHandlingType() != ExceptionHandling::DwarfCFI) - break; for (auto &F : M.getFunctionList()) { - // If the module contains any function with unwind data, - // .eh_frame has to be emitted. - // Ignore functions that won't get emitted. - if (!F.isDeclarationForLinker() && F.needsUnwindTableEntry()) { - isCFIMoveForDebugging = false; + if (getFunctionCFISectionType(F) != CFISection::None) + ModuleCFISection = getFunctionCFISectionType(F); + // If any function needsUnwindTableEntry(), it needs .eh_frame and hence + // the module needs .eh_frame. If we have found that case, we are done. + if (ModuleCFISection == CFISection::EH) break; - } } + assert(MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI || + ModuleCFISection != CFISection::EH); break; default: - isCFIMoveForDebugging = false; break; } @@ -1040,15 +1037,25 @@ return true; } -AsmPrinter::CFIMoveType AsmPrinter::needsCFIMoves() const { +AsmPrinter::CFISection +AsmPrinter::getFunctionCFISectionType(const Function &F) const { + // Ignore functions that won't get emitted. + if (F.isDeclarationForLinker()) + return CFISection::None; + if (MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI && - MF->getFunction().needsUnwindTableEntry()) - return CFI_M_EH; + F.needsUnwindTableEntry()) + return CFISection::EH; - if (MMI->hasDebugInfo() || MF->getTarget().Options.ForceDwarfFrameSection) - return CFI_M_Debug; + if (MMI->hasDebugInfo() || TM.Options.ForceDwarfFrameSection) + return CFISection::Debug; + + return CFISection::None; +} - return CFI_M_None; +AsmPrinter::CFISection +AsmPrinter::getFunctionCFISectionType(const MachineFunction &MF) const { + return getFunctionCFISectionType(MF.getFunction()); } bool AsmPrinter::needsSEHMoves() { @@ -1061,7 +1068,7 @@ ExceptionHandlingType != ExceptionHandling::ARM) return; - if (needsCFIMoves() == CFI_M_None) + if (getFunctionCFISectionType(*MF) == CFISection::None) return; // If there is no "real" instruction following this CFI instruction, skip diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp @@ -93,9 +93,8 @@ bool hasLandingPads = !MF->getLandingPads().empty(); // See if we need frame move info. - AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves(); - - bool shouldEmitMoves = MoveType != AsmPrinter::CFI_M_None; + bool shouldEmitMoves = + Asm->getFunctionCFISectionType(*MF) != AsmPrinter::CFISection::None; const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); unsigned PerEncoding = TLOF.getPersonalityEncoding(); @@ -132,10 +131,14 @@ return; if (!hasEmittedCFISections) { - if (Asm->needsOnlyDebugCFIMoves()) - Asm->OutStreamer->emitCFISections(false, true); - else if (Asm->TM.Options.ForceDwarfFrameSection) - Asm->OutStreamer->emitCFISections(true, true); + AsmPrinter::CFISection CFISecType = Asm->getModuleCFISectionType(); + // If we don't say anything it implies `.cfi_sections .eh_frame`, so we + // chose not to be verbose in that case. And with `ForceDwarfFrameSection`, + // we should always emit .debug_frame. + if (CFISecType == AsmPrinter::CFISection::Debug || + Asm->TM.Options.ForceDwarfFrameSection) + Asm->OutStreamer->emitCFISections( + CFISecType == AsmPrinter::CFISection::EH, true); hasEmittedCFISections = true; } diff --git a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp --- a/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp +++ b/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -1229,7 +1229,7 @@ ExceptionHandlingType != ExceptionHandling::ARM) return; - if (needsCFIMoves() == CFI_M_None) + if (getFunctionCFISectionType(*MF) == CFISection::None) return; OutStreamer->emitCFIBKeyFrame();