Index: include/llvm/CodeGen/AsmPrinter.h =================================================================== --- include/llvm/CodeGen/AsmPrinter.h +++ include/llvm/CodeGen/AsmPrinter.h @@ -22,6 +22,7 @@ #include "llvm/Support/ErrorHandling.h" namespace llvm { + class AsmPrinterObserver; class BlockAddress; class GCStrategy; class Constant; @@ -110,12 +111,21 @@ /// function. MachineLoopInfo *LI; - /// DD - If the target supports dwarf debug info, this pointer is non-null. - DwarfDebug *DD; + struct ObserverInfo { + AsmPrinterObserver *Observer; + const char *TimerName, *TimerGroupName; + ObserverInfo(AsmPrinterObserver *Observer, const char *TimerName, + const char *TimerGroupName) + : Observer(Observer), TimerName(TimerName), + TimerGroupName(TimerGroupName) {} + }; + /// Observers - a vector of all debug/EH info emitters we should use. + /// This vector maintains ownership of the emitters. + SmallVector Observers; - /// DE - If the target supports dwarf exception info, this pointer is - /// non-null. - DwarfException *DE; + /// DwarfVersion - If the target supports dwarf debug info, holds the Dwarf + /// Version. Otherwise, zero. + unsigned DwarfVersion; protected: explicit AsmPrinter(TargetMachine &TM, MCStreamer &Streamer); @@ -123,7 +133,8 @@ public: virtual ~AsmPrinter(); - const DwarfDebug *getDwarfDebug() const { return DD; } + /// Returns the Dwarf Version or zero. + unsigned getDwarfVersion() const { return DwarfVersion; } /// isVerbose - Return true if assembly output should contain comments. /// Index: lib/CodeGen/AsmPrinter/ARMException.cpp =================================================================== --- lib/CodeGen/AsmPrinter/ARMException.cpp +++ lib/CodeGen/AsmPrinter/ARMException.cpp @@ -52,12 +52,9 @@ return static_cast(TS); } -void ARMException::EndModule() { -} - /// BeginFunction - Gather pre-function exception information. Assumes it's /// being emitted immediately after the function entry point. -void ARMException::BeginFunction(const MachineFunction *MF) { +void ARMException::beginFunction(const MachineFunction *MF) { getTargetStreamer().emitFnStart(); if (Asm->MF->getFunction()->needsUnwindTableEntry()) Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin", @@ -66,7 +63,7 @@ /// EndFunction - Gather and emit post-function exception information. /// -void ARMException::EndFunction() { +void ARMException::endFunction() { ARMTargetStreamer &ATS = getTargetStreamer(); if (!Asm->MF->getFunction()->needsUnwindTableEntry()) ATS.emitCantUnwind(); Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -99,14 +99,15 @@ OutContext(Streamer.getContext()), OutStreamer(Streamer), LastMI(0), LastFn(0), Counter(~0U), SetCounter(0) { - DD = 0; DE = 0; MMI = 0; LI = 0; MF = 0; + MMI = 0; LI = 0; MF = 0; + DwarfVersion = 0; CurrentFnSym = CurrentFnSymForSize = 0; GCMetadataPrinters = 0; VerboseAsm = Streamer.isVerboseAsm(); } AsmPrinter::~AsmPrinter() { - assert(DD == 0 && DE == 0 && "Debug/EH info didn't get finalized"); + assert(Observers.empty() && "Debug/EH info didn't get finalized"); if (GCMetadataPrinters != 0) { gcp_map_type &GCMap = getGCMap(GCMetadataPrinters); @@ -192,25 +193,30 @@ OutStreamer.AddBlankLine(); } - if (MAI->doesSupportDebugInformation()) - DD = new DwarfDebug(this, &M); + if (MAI->doesSupportDebugInformation()) { + DwarfDebug *DD = new DwarfDebug(this, &M); + DwarfVersion = DD->getDwarfVersion(); + Observers.push_back(ObserverInfo(DD, DbgTimerName, DWARFGroupName)); + } + DwarfException *DE = 0; switch (MAI->getExceptionHandlingType()) { case ExceptionHandling::None: - return false; + break; case ExceptionHandling::SjLj: case ExceptionHandling::DwarfCFI: DE = new DwarfCFIException(this); - return false; + break; case ExceptionHandling::ARM: DE = new ARMException(this); - return false; + break; case ExceptionHandling::Win64: DE = new Win64Exception(this); - return false; + break; } - - llvm_unreachable("Unknown exception type."); + if (DE) + Observers.push_back(ObserverInfo(DE, EHTimerName, DWARFGroupName)); + return false; } void AsmPrinter::EmitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const { @@ -311,8 +317,11 @@ // sections and expected to be contiguous (e.g. ObjC metadata). unsigned AlignLog = getGVAlignmentLog2(GV, *DL); - if (DD) - DD->setSymbolSize(GVSym, Size); + for (unsigned I = 0, E = Observers.size(); I != E; ++I) { + const ObserverInfo &OI = Observers[I]; + NamedRegionTimer T(OI.TimerName, OI.TimerGroupName, TimePassesIsEnabled); + OI.Observer->setSymbolSize(GVSym, Size); + } // Handle common and BSS local symbols (.lcomm). if (GVKind.isCommon() || GVKind.isBSSLocal()) { @@ -482,13 +491,10 @@ } // Emit pre-function debug and/or EH information. - if (DE) { - NamedRegionTimer T(EHTimerName, DWARFGroupName, TimePassesIsEnabled); - DE->BeginFunction(MF); - } - if (DD) { - NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); - DD->beginFunction(MF); + for (unsigned I = 0, E = Observers.size(); I != E; ++I) { + const ObserverInfo &OI = Observers[I]; + NamedRegionTimer T(OI.TimerName, OI.TimerGroupName, TimePassesIsEnabled); + OI.Observer->beginFunction(MF); } // Emit the prefix data. @@ -693,7 +699,7 @@ // Emit target-specific gunk before the function body. EmitFunctionBodyStart(); - bool ShouldPrintDebugScopes = DD && MMI->hasDebugInfo(); + bool ShouldPrintDebugScopes = MMI->hasDebugInfo(); // Print out code for the function. bool HasAnyRealCode = false; @@ -714,8 +720,12 @@ } if (ShouldPrintDebugScopes) { - NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); - DD->beginInstruction(II); + for (unsigned III = 0, EEE = Observers.size(); III != EEE; ++III) { + const ObserverInfo &OI = Observers[III]; + NamedRegionTimer T(OI.TimerName, OI.TimerGroupName, + TimePassesIsEnabled); + OI.Observer->beginInstruction(II); + } } if (isVerbose()) @@ -754,8 +764,12 @@ } if (ShouldPrintDebugScopes) { - NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); - DD->endInstruction(II); + for (unsigned III = 0, EEE = Observers.size(); III != EEE; ++III) { + const ObserverInfo &OI = Observers[III]; + NamedRegionTimer T(OI.TimerName, OI.TimerGroupName, + TimePassesIsEnabled); + OI.Observer->endInstruction(II); + } } } } @@ -811,14 +825,12 @@ OutStreamer.EmitELFSize(CurrentFnSym, SizeExp); } - // Emit post-function debug information. - if (DD) { - NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); - DD->endFunction(MF); - } - if (DE) { - NamedRegionTimer T(EHTimerName, DWARFGroupName, TimePassesIsEnabled); - DE->EndFunction(); + // Emit post-function debug and/or EH information. + for (unsigned I = 0, E = Observers.size(); I != E; ++I) { + const ObserverInfo &OI = Observers[I]; + NamedRegionTimer T(OI.TimerName, OI.TimerGroupName, + TimePassesIsEnabled); + OI.Observer->endFunction(); } MMI->EndFunction(); @@ -907,20 +919,14 @@ OutStreamer.Flush(); // Finalize debug and EH information. - if (DE) { - { - NamedRegionTimer T(EHTimerName, DWARFGroupName, TimePassesIsEnabled); - DE->EndModule(); - } - delete DE; DE = 0; - } - if (DD) { - { - NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled); - DD->endModule(); - } - delete DD; DD = 0; - } + for (unsigned I = 0, E = Observers.size(); I != E; ++I) { + const ObserverInfo &OI = Observers[I]; + NamedRegionTimer T(OI.TimerName, OI.TimerGroupName, + TimePassesIsEnabled); + OI.Observer->endModule(); + delete OI.Observer; + } + Observers.clear(); // If the target wants to know about weak references, print them all. if (MAI->getWeakRefDirective()) { Index: lib/CodeGen/AsmPrinter/AsmPrinterObserver.h =================================================================== --- /dev/null +++ lib/CodeGen/AsmPrinter/AsmPrinterObserver.h @@ -0,0 +1,53 @@ +//===-- lib/CodeGen/AsmPrinter/AsmPrinterObserver.h ------------*- C++ -*--===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains a generic interface for AsmPrinter observers, +// like debug and EH info emitters. +// +//===----------------------------------------------------------------------===// + +#ifndef CODEGEN_ASMPRINTER_ASMPRINTEROBSERVER_H__ +#define CODEGEN_ASMPRINTER_ASMPRINTEROBSERVER_H__ + +#include + +namespace llvm { + +class MachineFunction; +class MachineInstr; +class MCSymbol; + +/// \brief Collects and handles AsmPrinter objects required to build debug +/// or EH information. +class AsmPrinterObserver { +public: + virtual ~AsmPrinterObserver() {} + + /// \brief For symbols that have a size designated (e.g. common symbols), + /// this tracks that size. + virtual void setSymbolSize(const MCSymbol *Sym, uint64_t Size) = 0; + + /// \brief Emit all sections that should come after the content. + virtual void endModule() = 0; + + /// \brief Gather pre-function debug information. + virtual void beginFunction(const MachineFunction *MF) = 0; + + /// \brief Gather post-function debug information. + virtual void endFunction() = 0; + + /// \brief Process beginning of an instruction. + virtual void beginInstruction(const MachineInstr *MI) = 0; + + /// \brief Process end of an instruction. + virtual void endInstruction(const MachineInstr *MI) = 0; +}; +} // End of namespace llvm + +#endif Index: lib/CodeGen/AsmPrinter/DIE.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DIE.cpp +++ lib/CodeGen/AsmPrinter/DIE.cpp @@ -386,7 +386,9 @@ // specified to be four bytes in the DWARF 32-bit format and eight bytes // in the DWARF 64-bit format, while DWARF Version 2 specifies that such // references have the same size as an address on the target system. - if (AP->getDwarfDebug()->getDwarfVersion() == 2) + unsigned DwarfVersion = AP->getDwarfVersion(); + assert(DwarfVersion && "Expected Dwarf Debug info to be available"); + if (DwarfVersion == 2) return AP->getDataLayout().getPointerSize(); return sizeof(int32_t); } Index: lib/CodeGen/AsmPrinter/DwarfCFIException.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfCFIException.cpp +++ lib/CodeGen/AsmPrinter/DwarfCFIException.cpp @@ -48,7 +48,7 @@ /// EndModule - Emit all exception information that should come after the /// content. -void DwarfCFIException::EndModule() { +void DwarfCFIException::endModule() { if (moveTypeModule == AsmPrinter::CFI_M_Debug) Asm->OutStreamer.EmitCFISections(false, true); @@ -84,7 +84,7 @@ /// BeginFunction - Gather pre-function exception information. Assumes it's /// being emitted immediately after the function entry point. -void DwarfCFIException::BeginFunction(const MachineFunction *MF) { +void DwarfCFIException::beginFunction(const MachineFunction *MF) { shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false; // If any landing pads survive, we need an EH table. @@ -137,7 +137,7 @@ /// EndFunction - Gather and emit post-function exception information. /// -void DwarfCFIException::EndFunction() { +void DwarfCFIException::endFunction() { if (!shouldEmitPersonality && !shouldEmitMoves) return; Index: lib/CodeGen/AsmPrinter/DwarfDebug.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.h +++ lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -14,6 +14,7 @@ #ifndef CODEGEN_ASMPRINTER_DWARFDEBUG_H__ #define CODEGEN_ASMPRINTER_DWARFDEBUG_H__ +#include "AsmPrinterObserver.h" #include "DIE.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" @@ -310,7 +311,7 @@ }; /// \brief Collects and handles dwarf debug information. -class DwarfDebug { +class DwarfDebug : public AsmPrinterObserver { // Target of Dwarf emission. AsmPrinter *Asm; @@ -414,6 +415,9 @@ // body. DebugLoc PrologEndLoc; + // If nonnull, stores the current machine function we're processing. + const MachineFunction *CurFn; + // Section Symbols: these are assembler temporary labels that are emitted at // the beginning of each supported dwarf section. These are used to form // section offsets and are created by EmitSectionLabels. @@ -685,7 +689,7 @@ void beginFunction(const MachineFunction *MF); /// \brief Gather and emit post-function debug information. - void endFunction(const MachineFunction *MF); + void endFunction(); /// \brief Process beginning of an instruction. void beginInstruction(const MachineInstr *MI); Index: lib/CodeGen/AsmPrinter/DwarfDebug.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -192,6 +192,7 @@ DwarfAddrSectionSym = 0; DwarfAbbrevDWOSectionSym = DwarfStrDWOSectionSym = 0; FunctionBeginSym = FunctionEndSym = 0; + CurFn = 0; // Turn on accelerator tables for Darwin by default, pubnames by // default for non-Darwin, and handle split dwarf. @@ -1154,6 +1155,7 @@ // Emit all Dwarf sections that should come after the content. void DwarfDebug::endModule() { + assert(CurFn == 0); if (!FirstCU) return; @@ -1584,6 +1586,7 @@ // Gather pre-function debug information. Assumes being called immediately // after the function entry point has been emitted. void DwarfDebug::beginFunction(const MachineFunction *MF) { + CurFn = MF; // If there's no debug info for the function we're not going to do anything. if (!MMI->hasDebugInfo()) @@ -1810,9 +1813,13 @@ } // Gather and emit post-function debug information. -void DwarfDebug::endFunction(const MachineFunction *MF) { - if (!MMI->hasDebugInfo() || LScopes.empty()) +void DwarfDebug::endFunction() { + assert(CurFn != 0); + + if (!MMI->hasDebugInfo() || LScopes.empty()) { + CurFn = 0; return; + } // Define end label for subprogram. FunctionEndSym = Asm->GetTempSymbol("func_end", Asm->getFunctionNumber()); @@ -1822,7 +1829,7 @@ Asm->OutStreamer.getContext().setDwarfCompileUnitID(0); SmallPtrSet ProcessedVars; - collectVariableInfo(MF, ProcessedVars); + collectVariableInfo(CurFn, ProcessedVars); LexicalScope *FnScope = LScopes.getCurrentFunctionScope(); CompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode()); @@ -1856,7 +1863,7 @@ DIE *CurFnDIE = constructScopeDIE(TheCU, FnScope); - if (!MF->getTarget().Options.DisableFramePointerElim(*MF)) + if (!CurFn->getTarget().Options.DisableFramePointerElim(*CurFn)) TheCU->addFlag(CurFnDIE, dwarf::DW_AT_APPLE_omit_frame_ptr); // Clear debug info @@ -1872,6 +1879,7 @@ LabelsBeforeInsn.clear(); LabelsAfterInsn.clear(); PrevLabel = NULL; + CurFn = 0; } // Register a source line with debug info. Returns the unique label that was Index: lib/CodeGen/AsmPrinter/DwarfException.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfException.h +++ lib/CodeGen/AsmPrinter/DwarfException.h @@ -14,6 +14,7 @@ #ifndef LLVM_CODEGEN_ASMPRINTER_DWARFEXCEPTION_H #define LLVM_CODEGEN_ASMPRINTER_DWARFEXCEPTION_H +#include "AsmPrinterObserver.h" #include "llvm/ADT/DenseMap.h" #include "llvm/CodeGen/AsmPrinter.h" #include @@ -35,7 +36,7 @@ //===----------------------------------------------------------------------===// /// DwarfException - Emits Dwarf exception handling directives. /// -class DwarfException { +class DwarfException : public AsmPrinterObserver { protected: /// Asm - Target of Dwarf emission. AsmPrinter *Asm; @@ -132,14 +133,19 @@ /// EndModule - Emit all exception information that should come after the /// content. - virtual void EndModule(); + virtual void endModule(); /// BeginFunction - Gather pre-function exception information. Assumes being /// emitted immediately after the function entry point. - virtual void BeginFunction(const MachineFunction *MF); + virtual void beginFunction(const MachineFunction *MF); /// EndFunction - Gather and emit post-function exception information. - virtual void EndFunction(); + virtual void endFunction(); + + // We don't need these. + virtual void setSymbolSize(const MCSymbol *Sym, uint64_t Size) {} + virtual void beginInstruction(const MachineInstr *MI) {} + virtual void endInstruction(const MachineInstr *MI) {} }; class DwarfCFIException : public DwarfException { @@ -166,14 +172,14 @@ /// EndModule - Emit all exception information that should come after the /// content. - virtual void EndModule(); + virtual void endModule(); /// BeginFunction - Gather pre-function exception information. Assumes being /// emitted immediately after the function entry point. - virtual void BeginFunction(const MachineFunction *MF); + virtual void beginFunction(const MachineFunction *MF); /// EndFunction - Gather and emit post-function exception information. - virtual void EndFunction(); + virtual void endFunction(); }; class ARMException : public DwarfException { @@ -187,16 +193,15 @@ ARMException(AsmPrinter *A); virtual ~ARMException(); - /// EndModule - Emit all exception information that should come after the - /// content. - virtual void EndModule(); - /// BeginFunction - Gather pre-function exception information. Assumes being /// emitted immediately after the function entry point. - virtual void BeginFunction(const MachineFunction *MF); + virtual void beginFunction(const MachineFunction *MF); /// EndFunction - Gather and emit post-function exception information. - virtual void EndFunction(); + virtual void endFunction(); + + // Nothing to do. + virtual void endModule() {} }; class Win64Exception : public DwarfException { @@ -219,16 +224,15 @@ Win64Exception(AsmPrinter *A); virtual ~Win64Exception(); - /// EndModule - Emit all exception information that should come after the - /// content. - virtual void EndModule(); - /// BeginFunction - Gather pre-function exception information. Assumes being /// emitted immediately after the function entry point. - virtual void BeginFunction(const MachineFunction *MF); + virtual void beginFunction(const MachineFunction *MF); /// EndFunction - Gather and emit post-function exception information. - virtual void EndFunction(); + virtual void endFunction(); + + // Nothing to do. + virtual void endModule() {} }; } // End of namespace llvm Index: lib/CodeGen/AsmPrinter/DwarfException.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfException.cpp +++ lib/CodeGen/AsmPrinter/DwarfException.cpp @@ -719,18 +719,18 @@ /// EndModule - Emit all exception information that should come after the /// content. -void DwarfException::EndModule() { +void DwarfException::endModule() { llvm_unreachable("Should be implemented"); } /// BeginFunction - Gather pre-function exception information. Assumes it's /// being emitted immediately after the function entry point. -void DwarfException::BeginFunction(const MachineFunction *MF) { +void DwarfException::beginFunction(const MachineFunction *MF) { llvm_unreachable("Should be implemented"); } /// EndFunction - Gather and emit post-function exception information. /// -void DwarfException::EndFunction() { +void DwarfException::endFunction() { llvm_unreachable("Should be implemented"); } Index: lib/CodeGen/AsmPrinter/Win64Exception.cpp =================================================================== --- lib/CodeGen/AsmPrinter/Win64Exception.cpp +++ lib/CodeGen/AsmPrinter/Win64Exception.cpp @@ -44,14 +44,9 @@ Win64Exception::~Win64Exception() {} -/// EndModule - Emit all exception information that should come after the -/// content. -void Win64Exception::EndModule() { -} - /// BeginFunction - Gather pre-function exception information. Assumes it's /// being emitted immediately after the function entry point. -void Win64Exception::BeginFunction(const MachineFunction *MF) { +void Win64Exception::beginFunction(const MachineFunction *MF) { shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false; // If any landing pads survive, we need an EH table. @@ -88,7 +83,7 @@ /// EndFunction - Gather and emit post-function exception information. /// -void Win64Exception::EndFunction() { +void Win64Exception::endFunction() { if (!shouldEmitPersonality && !shouldEmitMoves) return;