[NFC] Refactor how CFI section types are represented in AsmPrinter

In terms of readability, the `enum CFIMoveType` didn't better document what it
intends to convey i.e. the type of CFI section that gets emitted.

Reviewed By: dblaikie, MaskRay

Differential Revision: https://reviews.llvm.org/D76519
This commit is contained in:
RamNalamothu 2021-04-24 23:26:52 +05:30
parent ef2dc7ed9f
commit 0ce723cb22
5 changed files with 56 additions and 37 deletions

View File

@ -157,6 +157,13 @@ public:
TimerGroupDescription(TimerGroupDescription) {} 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: private:
MCSymbol *CurrentFnEnd = nullptr; MCSymbol *CurrentFnEnd = nullptr;
@ -199,8 +206,8 @@ private:
/// context. /// context.
PseudoProbeHandler *PP = nullptr; PseudoProbeHandler *PP = nullptr;
/// If the current module uses dwarf CFI annotations strictly for debugging. /// CFISection type the module needs i.e. either .eh_frame or .debug_frame.
bool isCFIMoveForDebugging = false; CFISection ModuleCFISection = CFISection::None;
protected: protected:
explicit AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer); explicit AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer);
@ -357,12 +364,14 @@ public:
void emitRemarksSection(remarks::RemarkStreamer &RS); void emitRemarksSection(remarks::RemarkStreamer &RS);
enum CFIMoveType { CFI_M_None, CFI_M_EH, CFI_M_Debug }; /// Get the CFISection type for a function.
CFIMoveType needsCFIMoves() const; CFISection getFunctionCFISectionType(const Function &F) const;
/// Returns false if needsCFIMoves() == CFI_M_EH for any function /// Get the CFISection type for a function.
/// in the module. CFISection getFunctionCFISectionType(const MachineFunction &MF) const;
bool needsOnlyDebugCFIMoves() const { return isCFIMoveForDebugging; }
/// Get the CFISection type for the module.
CFISection getModuleCFISectionType() const { return ModuleCFISection; }
bool needsSEHMoves(); bool needsSEHMoves();

View File

@ -39,13 +39,13 @@ void ARMException::beginFunction(const MachineFunction *MF) {
if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM) if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
getTargetStreamer().emitFnStart(); getTargetStreamer().emitFnStart();
// See if we need call frame info. // See if we need call frame info.
AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves(); AsmPrinter::CFISection CFISecType = Asm->getFunctionCFISectionType(*MF);
assert(MoveType != AsmPrinter::CFI_M_EH && assert(CFISecType != AsmPrinter::CFISection::EH &&
"non-EH CFI not yet supported in prologue with EHABI lowering"); "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 (!hasEmittedCFISections) {
if (Asm->needsOnlyDebugCFIMoves()) if (Asm->getModuleCFISectionType() == AsmPrinter::CFISection::Debug)
Asm->OutStreamer->emitCFISections(false, true); Asm->OutStreamer->emitCFISections(false, true);
hasEmittedCFISections = true; hasEmittedCFISections = true;
} }

View File

@ -351,21 +351,18 @@ bool AsmPrinter::doInitialization(Module &M) {
case ExceptionHandling::SjLj: case ExceptionHandling::SjLj:
case ExceptionHandling::DwarfCFI: case ExceptionHandling::DwarfCFI:
case ExceptionHandling::ARM: case ExceptionHandling::ARM:
isCFIMoveForDebugging = true; for (auto &F : M.getFunctionList()) {
if (MAI->getExceptionHandlingType() != ExceptionHandling::DwarfCFI) // If any function needsUnwindTableEntry(), it needs .eh_frame and hence
break; // the module needs .eh_frame. If we have found that case, we are done.
for (auto &F: M.getFunctionList()) { if (ModuleCFISection == AsmPrinter::CFISection::EH)
// 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; break;
} if (ModuleCFISection == AsmPrinter::CFISection::None)
ModuleCFISection = getFunctionCFISectionType(F);
} }
assert(MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI ||
ModuleCFISection != AsmPrinter::CFISection::EH);
break; break;
default: default:
isCFIMoveForDebugging = false;
break; break;
} }
@ -1037,15 +1034,25 @@ static bool emitDebugLabelComment(const MachineInstr *MI, AsmPrinter &AP) {
return true; 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 && if (MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI &&
MF->getFunction().needsUnwindTableEntry()) F.needsUnwindTableEntry())
return CFI_M_EH; return CFISection::EH;
if (MMI->hasDebugInfo() || MF->getTarget().Options.ForceDwarfFrameSection) if (MMI->hasDebugInfo() || TM.Options.ForceDwarfFrameSection)
return CFI_M_Debug; return CFISection::Debug;
return CFI_M_None; return CFISection::None;
}
AsmPrinter::CFISection
AsmPrinter::getFunctionCFISectionType(const MachineFunction &MF) const {
return getFunctionCFISectionType(MF.getFunction());
} }
bool AsmPrinter::needsSEHMoves() { bool AsmPrinter::needsSEHMoves() {
@ -1058,7 +1065,7 @@ void AsmPrinter::emitCFIInstruction(const MachineInstr &MI) {
ExceptionHandlingType != ExceptionHandling::ARM) ExceptionHandlingType != ExceptionHandling::ARM)
return; return;
if (needsCFIMoves() == CFI_M_None) if (getFunctionCFISectionType(*MF) == AsmPrinter::CFISection::None)
return; return;
// If there is no "real" instruction following this CFI instruction, skip // If there is no "real" instruction following this CFI instruction, skip

View File

@ -93,9 +93,8 @@ void DwarfCFIException::beginFunction(const MachineFunction *MF) {
bool hasLandingPads = !MF->getLandingPads().empty(); bool hasLandingPads = !MF->getLandingPads().empty();
// See if we need frame move info. // See if we need frame move info.
AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves(); bool shouldEmitMoves =
Asm->getFunctionCFISectionType(*MF) != AsmPrinter::CFISection::None;
bool shouldEmitMoves = MoveType != AsmPrinter::CFI_M_None;
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
unsigned PerEncoding = TLOF.getPersonalityEncoding(); unsigned PerEncoding = TLOF.getPersonalityEncoding();
@ -132,10 +131,14 @@ void DwarfCFIException::beginFragment(const MachineBasicBlock *MBB,
return; return;
if (!hasEmittedCFISections) { if (!hasEmittedCFISections) {
if (Asm->needsOnlyDebugCFIMoves()) AsmPrinter::CFISection CFISecType = Asm->getModuleCFISectionType();
Asm->OutStreamer->emitCFISections(false, true); // If we don't say anything it implies `.cfi_sections .eh_frame`, so we
else if (Asm->TM.Options.ForceDwarfFrameSection) // chose not to be verbose in that case. And with `ForceDwarfFrameSection`,
Asm->OutStreamer->emitCFISections(true, true); // 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; hasEmittedCFISections = true;
} }

View File

@ -1229,7 +1229,7 @@ void AArch64AsmPrinter::emitInstruction(const MachineInstr *MI) {
ExceptionHandlingType != ExceptionHandling::ARM) ExceptionHandlingType != ExceptionHandling::ARM)
return; return;
if (needsCFIMoves() == CFI_M_None) if (getFunctionCFISectionType(*MF) == CFISection::None)
return; return;
OutStreamer->emitCFIBKeyFrame(); OutStreamer->emitCFIBKeyFrame();