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 sections are required for a function/module. + enum 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; + /// Cached bitwise OR of CFISection flags for all functions in the module. + unsigned ModuleCFISections = 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 flags for a function. + unsigned getFunctionCFISectionTypes(const Function &F) const; + + /// Get the CFISection flags for a function. + unsigned getFunctionCFISectionTypes(const MachineFunction &MF) const; - /// Returns false if needsCFIMoves() == CFI_M_EH for any function - /// in the module. - bool needsOnlyDebugCFIMoves() const { return isCFIMoveForDebugging; } + /// Get the bitwise OR of CFISection flags for all functions in the module. + unsigned getModuleCFISectionTypes() const { return ModuleCFISections; } 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,12 @@ 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 && + assert(!(Asm->getFunctionCFISectionTypes(*MF) & AsmPrinter::CFISection::EH) && "non-EH CFI not yet supported in prologue with EHABI lowering"); - if (MoveType == AsmPrinter::CFI_M_Debug) { + if (Asm->getFunctionCFISectionTypes(*MF) & AsmPrinter::CFISection::Debug) { if (!hasEmittedCFISections) { - if (Asm->needsOnlyDebugCFIMoves()) + if (Asm->getModuleCFISectionTypes() == 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 @@ -351,21 +351,12 @@ 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; - break; - } - } + for (auto &F : M.getFunctionList()) + ModuleCFISections |= getFunctionCFISectionTypes(F); + assert(MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI || + !(ModuleCFISections & AsmPrinter::CFISection::EH)); break; default: - isCFIMoveForDebugging = false; break; } @@ -1037,15 +1028,29 @@ return true; } -AsmPrinter::CFIMoveType AsmPrinter::needsCFIMoves() const { +unsigned AsmPrinter::getFunctionCFISectionTypes(const Function &F) const { + unsigned CFISections = AsmPrinter::CFISection::None; + + // Ignore functions that won't get emitted. + if (F.isDeclarationForLinker()) + return CFISections; + if (MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI && - MF->getFunction().needsUnwindTableEntry()) - return CFI_M_EH; + F.needsUnwindTableEntry()) { + CFISections = AsmPrinter::CFISection::EH; + } else if (MMI->hasDebugInfo()) { + CFISections = AsmPrinter::CFISection::Debug; + } - if (MMI->hasDebugInfo() || MF->getTarget().Options.ForceDwarfFrameSection) - return CFI_M_Debug; + if (TM.Options.ForceDwarfFrameSection) + CFISections |= AsmPrinter::CFISection::Debug; + + return CFISections; +} - return CFI_M_None; +unsigned +AsmPrinter::getFunctionCFISectionTypes(const MachineFunction &MF) const { + return getFunctionCFISectionTypes(MF.getFunction()); } bool AsmPrinter::needsSEHMoves() { @@ -1058,7 +1063,7 @@ ExceptionHandlingType != ExceptionHandling::ARM) return; - if (needsCFIMoves() == CFI_M_None) + if (getFunctionCFISectionTypes(*MF) == AsmPrinter::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->getFunctionCFISectionTypes(*MF) != AsmPrinter::CFISection::None; const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); unsigned PerEncoding = TLOF.getPersonalityEncoding(); @@ -132,10 +131,12 @@ return; if (!hasEmittedCFISections) { - if (Asm->needsOnlyDebugCFIMoves()) - Asm->OutStreamer->emitCFISections(false, true); - else if (Asm->TM.Options.ForceDwarfFrameSection) - Asm->OutStreamer->emitCFISections(true, true); + unsigned CFISections = Asm->getModuleCFISectionTypes(); + // If we don't say anything it implies `.cfi_sections .eh_frame`, so we + // chose not to be verbose in that case. + if (CFISections & AsmPrinter::CFISection::Debug) + Asm->OutStreamer->emitCFISections( + CFISections & 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 (getFunctionCFISectionTypes(*MF) == AsmPrinter::CFISection::None) return; OutStreamer->emitCFIBKeyFrame();