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 @@ -109,6 +109,9 @@ /// This is a pointer to the current MachineLoopInfo. MachineLoopInfo *MLI = nullptr; + // Custom assembly annotations writer customizations + std::unique_ptr AAW; + /// Optimization remark emitter. MachineOptimizationRemarkEmitter *ORE; @@ -149,6 +152,43 @@ static char ID; + /// Simple adapter class to work around lack of a garbage collector: + /// this turns the expected unique_ptr back into an unmanaged pointer + /// wrapping our unique_ptr. + class AsmPrinterHandlerAdapter : public AsmPrinterHandler { + private: + AsmPrinterHandler *AAW; + + public: + AsmPrinterHandlerAdapter(AsmPrinterHandler &AAW) : AAW(&AAW) {} + virtual ~AsmPrinterHandlerAdapter(){}; + virtual void setSymbolSize(const MCSymbol *Sym, uint64_t Size) { + AAW->setSymbolSize(Sym, Size); + } + virtual void endModule() { AAW->endModule(); } + virtual void beginFunction(const MachineFunction *MF) { + AAW->beginFunction(MF); + } + virtual void markFunctionEnd() { AAW->markFunctionEnd(); } + virtual void endFunction(const MachineFunction *MF) { + AAW->endFunction(MF); + } + virtual void beginFragment(const MachineBasicBlock *MBB, + ExceptionSymbolProvider ESP) { + AAW->beginFragment(MBB, ESP); + } + virtual void endFragment() { AAW->endFragment(); } + virtual void beginFunclet(const MachineBasicBlock &MBB, MCSymbol *Sym) { + AAW->beginFunclet(MBB, Sym); + } + virtual void endFunclet() { AAW->endFunclet(); } + virtual void beginInstruction(const MachineInstr *MI) { + AAW->beginInstruction(MI); + } + virtual void endInstruction() { AAW->endInstruction(); } + virtual void beginModule(Module *M) { AAW->beginModule(M); } + }; + protected: MCSymbol *CurrentFnBegin = nullptr; diff --git a/llvm/include/llvm/CodeGen/AsmPrinterHandler.h b/llvm/include/llvm/CodeGen/AsmPrinterHandler.h --- a/llvm/include/llvm/CodeGen/AsmPrinterHandler.h +++ b/llvm/include/llvm/CodeGen/AsmPrinterHandler.h @@ -23,6 +23,7 @@ class MachineFunction; class MachineInstr; class MCSymbol; +class Module; typedef MCSymbol *ExceptionSymbolProvider(AsmPrinter *Asm); @@ -36,6 +37,8 @@ /// this tracks that size. virtual void setSymbolSize(const MCSymbol *Sym, uint64_t Size) = 0; + virtual void beginModule(Module *M){}; + /// Emit all sections that should come after the content. virtual void endModule() = 0; @@ -68,6 +71,7 @@ /// Process end of an instruction. virtual void endInstruction() = 0; }; + } // End of namespace llvm #endif diff --git a/llvm/include/llvm/CodeGen/DebugHandlerBase.h b/llvm/include/llvm/CodeGen/DebugHandlerBase.h --- a/llvm/include/llvm/CodeGen/DebugHandlerBase.h +++ b/llvm/include/llvm/CodeGen/DebugHandlerBase.h @@ -112,6 +112,8 @@ // AsmPrinterHandler overrides. public: + void beginModule(Module *M) override; + void beginInstruction(const MachineInstr *MI) override; void endInstruction() override; 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 @@ -146,6 +146,10 @@ static const char *const CodeViewLineTablesGroupName = "linetables"; static const char *const CodeViewLineTablesGroupDescription = "CodeView Line Tables"; +static const char *const AAWTimerName = "annotations"; +static const char *const AAWTimerDescription = "Assembly Annotations"; +static const char *const AAWGroupName = "annotations"; +static const char *const AAWGroupDescription = "Assembly Annotations"; STATISTIC(EmittedInsts, "Number of machine instrs printed"); @@ -311,6 +315,12 @@ OutStreamer->AddBlankLine(); } + if (AAW) { + Handlers.emplace_back(std::make_unique(*AAW), + AAWTimerName, AAWTimerDescription, AAWGroupName, + AAWGroupDescription); + } + if (MAI->doesSupportDebugInformation()) { bool EmitCodeView = MMI->getModule()->getCodeViewFlag(); if (EmitCodeView && TM.getTargetTriple().isOSWindows()) { @@ -320,8 +330,7 @@ CodeViewLineTablesGroupDescription); } if (!EmitCodeView || MMI->getModule()->getDwarfVersion()) { - DD = new DwarfDebug(this, &M); - DD->beginModule(); + DD = new DwarfDebug(this); Handlers.emplace_back(std::unique_ptr(DD), DbgTimerName, DbgTimerDescription, DWARFGroupName, DWARFGroupDescription); @@ -387,6 +396,13 @@ Handlers.emplace_back(std::make_unique(this), CFGuardName, CFGuardDescription, DWARFGroupName, DWARFGroupDescription); + + for (const HandlerInfo &HI : Handlers) { + NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName, + HI.TimerGroupDescription, TimePassesIsEnabled); + HI.Handler->beginModule(&M); + } + return false; } @@ -1072,8 +1088,6 @@ // Emit target-specific gunk before the function body. EmitFunctionBodyStart(); - bool ShouldPrintDebugScopes = MMI->hasDebugInfo(); - if (isVerbose()) { // Get MachineDominatorTree or compute it on the fly if it's unavailable MDT = getAnalysisIfAvailable(); @@ -1110,13 +1124,10 @@ if (MCSymbol *S = MI.getPreInstrSymbol()) OutStreamer->EmitLabel(S); - if (ShouldPrintDebugScopes) { - for (const HandlerInfo &HI : Handlers) { - NamedRegionTimer T(HI.TimerName, HI.TimerDescription, - HI.TimerGroupName, HI.TimerGroupDescription, - TimePassesIsEnabled); - HI.Handler->beginInstruction(&MI); - } + for (const HandlerInfo &HI : Handlers) { + NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName, + HI.TimerGroupDescription, TimePassesIsEnabled); + HI.Handler->beginInstruction(&MI); } if (isVerbose()) @@ -1165,13 +1176,10 @@ if (MCSymbol *S = MI.getPostInstrSymbol()) OutStreamer->EmitLabel(S); - if (ShouldPrintDebugScopes) { - for (const HandlerInfo &HI : Handlers) { - NamedRegionTimer T(HI.TimerName, HI.TimerDescription, - HI.TimerGroupName, HI.TimerGroupDescription, - TimePassesIsEnabled); - HI.Handler->endInstruction(); - } + for (const HandlerInfo &HI : Handlers) { + NamedRegionTimer T(HI.TimerName, HI.TimerDescription, HI.TimerGroupName, + HI.TimerGroupDescription, TimePassesIsEnabled); + HI.Handler->endInstruction(); } } diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -154,7 +154,6 @@ if (!MMI->getModule()->getNamedMetadata("llvm.dbg.cu") || !AP->getObjFileLowering().getCOFFDebugSymbolsSection()) { Asm = nullptr; - MMI->setDebugInfoAvailability(false); return; } // Tell MMI that we have debug info. @@ -558,8 +557,6 @@ if (!Asm || !MMI->hasDebugInfo()) return; - assert(Asm != nullptr); - // The COFF .debug$S section consists of several subsections, each starting // with a 4-byte control code (e.g. 0xF1, 0xF2, etc) and then a 4-byte length // of the payload followed by the payload itself. The subsections are 4-byte diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp @@ -86,6 +86,13 @@ DebugHandlerBase::DebugHandlerBase(AsmPrinter *A) : Asm(A), MMI(Asm->MMI) {} +void DebugHandlerBase::beginModule(Module *M) { + if (M->debug_compile_units().empty()) + Asm = nullptr; + else + MMI->setDebugInfoAvailability(true); +} + // Each LexicalScope has first instruction and last instruction to mark // beginning and end of a scope respectively. Create an inverse map that list // scopes starts (and ends) with an instruction. One instruction may start (or @@ -262,7 +269,7 @@ } void DebugHandlerBase::beginInstruction(const MachineInstr *MI) { - if (!MMI->hasDebugInfo()) + if (!Asm || !MMI->hasDebugInfo()) return; assert(CurMI == nullptr); @@ -288,7 +295,7 @@ } void DebugHandlerBase::endInstruction() { - if (!MMI->hasDebugInfo()) + if (!Asm || !MMI->hasDebugInfo()) return; assert(CurMI != nullptr); @@ -320,7 +327,7 @@ } void DebugHandlerBase::endFunction(const MachineFunction *MF) { - if (hasDebugInfo(MMI, MF)) + if (Asm && hasDebugInfo(MMI, MF)) endFunctionImpl(MF); DbgValues.clear(); DbgLabels.clear(); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -609,13 +609,13 @@ //===--------------------------------------------------------------------===// // Main entry points. // - DwarfDebug(AsmPrinter *A, Module *M); + DwarfDebug(AsmPrinter *A); ~DwarfDebug() override; /// Emit all Dwarf sections that should come prior to the /// content. - void beginModule(); + void beginModule(Module *M) override; /// Emit all Dwarf sections that should come after the content. void endModule() override; diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -163,10 +163,6 @@ "Abstract subprograms")), cl::init(DefaultLinkageNames)); -static const char *const DWARFGroupName = "dwarf"; -static const char *const DWARFGroupDescription = "DWARF Emission"; -static const char *const DbgTimerName = "writer"; -static const char *const DbgTimerDescription = "DWARF Debug Writer"; static constexpr unsigned ULEB128PadSize = 4; void DebugLocDwarfExpression::emitOp(uint8_t Op, const char *Comment) { @@ -345,7 +341,7 @@ return AccelTableKind::None; } -DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M) +DwarfDebug::DwarfDebug(AsmPrinter *A) : DebugHandlerBase(A), DebugLocs(A->OutStreamer->isVerboseAsm()), InfoHolder(A, "info_string", DIEValueAllocator), SkeletonHolder(A, "skel_string", DIEValueAllocator), @@ -992,21 +988,17 @@ // Emit all Dwarf sections that should come prior to the content. Create // global DIEs and emit initial debug info sections. This is invoked by // the target AsmPrinter. -void DwarfDebug::beginModule() { - NamedRegionTimer T(DbgTimerName, DbgTimerDescription, DWARFGroupName, - DWARFGroupDescription, TimePassesIsEnabled); - if (DisableDebugInfoPrinting) { - MMI->setDebugInfoAvailability(false); - return; - } +void DwarfDebug::beginModule(Module *M) { + DebugHandlerBase::beginModule(M); - const Module *M = MMI->getModule(); + if (!Asm || !MMI->hasDebugInfo() || DisableDebugInfoPrinting) + return; unsigned NumDebugCUs = std::distance(M->debug_compile_units_begin(), M->debug_compile_units_end()); - // Tell MMI whether we have debug info. - assert(MMI->hasDebugInfo() == (NumDebugCUs > 0) && - "DebugInfoAvailabilty initialized unexpectedly"); + assert(NumDebugCUs > 0 && "Asm unexpectedly initialized"); + assert(MMI->hasDebugInfo() && + "DebugInfoAvailabilty unexpectedly not initialized"); SingleCU = NumDebugCUs == 1; DenseMap> GVMap; @@ -1254,7 +1246,7 @@ // If we aren't actually generating debug info (check beginModule - // conditionalized on !DisableDebugInfoPrinting and the presence of the // llvm.dbg.cu metadata node) - if (!MMI->hasDebugInfo()) + if (!Asm || !MMI->hasDebugInfo() || DisableDebugInfoPrinting) return; // Finalize the debug info for the module. @@ -1715,7 +1707,8 @@ // Process beginning of an instruction. void DwarfDebug::beginInstruction(const MachineInstr *MI) { DebugHandlerBase::beginInstruction(MI); - assert(CurMI); + if (!CurMI) + return; const auto *SP = MI->getMF()->getFunction().getSubprogram(); if (!SP || SP->getUnit()->getEmissionKind() == DICompileUnit::NoDebug) diff --git a/llvm/lib/CodeGen/MachineModuleInfo.cpp b/llvm/lib/CodeGen/MachineModuleInfo.cpp --- a/llvm/lib/CodeGen/MachineModuleInfo.cpp +++ b/llvm/lib/CodeGen/MachineModuleInfo.cpp @@ -313,7 +313,7 @@ bool MachineModuleInfoWrapperPass::doInitialization(Module &M) { MMI.initialize(); MMI.TheModule = &M; - MMI.DbgInfoAvailable = !M.debug_compile_units().empty(); + MMI.DbgInfoAvailable = false; return false; } @@ -328,6 +328,6 @@ ModuleAnalysisManager &) { MachineModuleInfo MMI(TM); MMI.TheModule = &M; - MMI.DbgInfoAvailable = !M.debug_compile_units().empty(); + MMI.DbgInfoAvailable = false; return MMI; } diff --git a/llvm/lib/Target/BPF/BTFDebug.cpp b/llvm/lib/Target/BPF/BTFDebug.cpp --- a/llvm/lib/Target/BPF/BTFDebug.cpp +++ b/llvm/lib/Target/BPF/BTFDebug.cpp @@ -1022,6 +1022,9 @@ } } + if (!CurMI) // no debug info + return; + // Skip this instruction if no DebugLoc or the DebugLoc // is the same as the previous instruction. const DebugLoc &DL = MI->getDebugLoc();