X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FCodeGen%2FAsmPrinter%2FDwarfDebug.h;h=169e9421699c0c808aaf8fb123f24fb1be208906;hp=424595070d82a022fb99d5a9048d7f5792ad2453;hb=ee129ed18ddc77b3bd12567987af302ec0e25c3a;hpb=b2d73d1556b47a79d01b188be3cf0b25631d3982 diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index 424595070d8..169e9421699 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -11,25 +11,31 @@ // //===----------------------------------------------------------------------===// -#ifndef CODEGEN_ASMPRINTER_DWARFDEBUG_H__ -#define CODEGEN_ASMPRINTER_DWARFDEBUG_H__ +#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H +#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H +#include "DwarfFile.h" #include "AsmPrinterHandler.h" #include "DIE.h" +#include "DbgValueHistoryCalculator.h" #include "DebugLocEntry.h" #include "DebugLocList.h" +#include "DwarfAccelTable.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/CodeGen/LexicalScopes.h" +#include "llvm/CodeGen/MachineInstr.h" #include "llvm/IR/DebugInfo.h" #include "llvm/IR/DebugLoc.h" #include "llvm/MC/MachineLocation.h" #include "llvm/MC/MCDwarf.h" #include "llvm/Support/Allocator.h" +#include + namespace llvm { class AsmPrinter; @@ -64,33 +70,41 @@ public: /// \brief This class is used to track local variable information. class DbgVariable { DIVariable Var; // Variable Descriptor. + DIExpression Expr; // Complex address location expression. DIE *TheDIE; // Variable DIE. unsigned DotDebugLocOffset; // Offset in DotDebugLocEntries. - DbgVariable *AbsVar; // Corresponding Abstract variable, if any. const MachineInstr *MInsn; // DBG_VALUE instruction of the variable. int FrameIndex; DwarfDebug *DD; public: - // AbsVar may be NULL. - DbgVariable(DIVariable V, DbgVariable *AV, DwarfDebug *DD) - : Var(V), TheDIE(0), DotDebugLocOffset(~0U), AbsVar(AV), MInsn(0), + /// Construct a DbgVariable from a DIVariable. + DbgVariable(DIVariable V, DIExpression E, DwarfDebug *DD) + : Var(V), Expr(E), TheDIE(nullptr), DotDebugLocOffset(~0U), + MInsn(nullptr), FrameIndex(~0), DD(DD) { + assert(Var.Verify() && Expr.Verify()); + } + + /// Construct a DbgVariable from a DEBUG_VALUE. + /// AbstractVar may be NULL. + DbgVariable(const MachineInstr *DbgValue, DwarfDebug *DD) + : Var(DbgValue->getDebugVariable()), Expr(DbgValue->getDebugExpression()), + TheDIE(nullptr), DotDebugLocOffset(~0U), MInsn(DbgValue), FrameIndex(~0), DD(DD) {} // Accessors. DIVariable getVariable() const { return Var; } - void setDIE(DIE *D) { TheDIE = D; } + DIExpression getExpression() const { return Expr; } + void setDIE(DIE &D) { TheDIE = &D; } DIE *getDIE() const { return TheDIE; } void setDotDebugLocOffset(unsigned O) { DotDebugLocOffset = O; } unsigned getDotDebugLocOffset() const { return DotDebugLocOffset; } StringRef getName() const { return Var.getName(); } - DbgVariable *getAbstractVariable() const { return AbsVar; } const MachineInstr *getMInsn() const { return MInsn; } - void setMInsn(const MachineInstr *M) { MInsn = M; } int getFrameIndex() const { return FrameIndex; } void setFrameIndex(int FI) { FrameIndex = FI; } // Translate tag to proper Dwarf tag. - uint16_t getTag() const { + dwarf::Tag getTag() const { if (Var.getTag() == dwarf::DW_TAG_arg_variable) return dwarf::DW_TAG_formal_parameter; @@ -115,14 +129,14 @@ public: bool variableHasComplexAddress() const { assert(Var.isVariable() && "Invalid complex DbgVariable!"); - return Var.hasComplexAddress(); + return Expr.getNumElements() > 0; } bool isBlockByrefVariable() const; unsigned getNumAddrElements() const { assert(Var.isVariable() && "Invalid complex DbgVariable!"); - return Var.getNumAddrElements(); + return Expr.getNumElements(); } - uint64_t getAddrElement(unsigned i) const { return Var.getAddrElement(i); } + uint64_t getAddrElement(unsigned i) const { return Expr.getElement(i); } DIType getType() const; private: @@ -131,99 +145,6 @@ private: template T resolve(DIRef Ref) const; }; -/// \brief Collects and handles information specific to a particular -/// collection of units. This collection represents all of the units -/// that will be ultimately output into a single object file. -class DwarfFile { - // Target of Dwarf emission, used for sizing of abbreviations. - AsmPrinter *Asm; - - // Used to uniquely define abbreviations. - FoldingSet AbbreviationsSet; - - // A list of all the unique abbreviations in use. - std::vector Abbreviations; - - // A pointer to all units in the section. - SmallVector CUs; - - // Collection of strings for this unit and assorted symbols. - // A String->Symbol mapping of strings used by indirect - // references. - typedef StringMap, BumpPtrAllocator &> - StrPool; - StrPool StringPool; - unsigned NextStringPoolNumber; - std::string StringPref; - - struct AddressPoolEntry { - unsigned Number; - bool TLS; - AddressPoolEntry(unsigned Number, bool TLS) : Number(Number), TLS(TLS) {} - }; - // Collection of addresses for this unit and assorted labels. - // A Symbol->unsigned mapping of addresses used by indirect - // references. - typedef DenseMap AddrPool; - AddrPool AddressPool; - unsigned NextAddrPoolNumber; - -public: - DwarfFile(AsmPrinter *AP, const char *Pref, BumpPtrAllocator &DA) - : Asm(AP), StringPool(DA), NextStringPoolNumber(0), StringPref(Pref), - AddressPool(), NextAddrPoolNumber(0) {} - - ~DwarfFile(); - - const SmallVectorImpl &getUnits() { return CUs; } - - /// \brief Compute the size and offset of a DIE given an incoming Offset. - unsigned computeSizeAndOffset(DIE *Die, unsigned Offset); - - /// \brief Compute the size and offset of all the DIEs. - void computeSizeAndOffsets(); - - /// \brief Define a unique number for the abbreviation. - void assignAbbrevNumber(DIEAbbrev &Abbrev); - - /// \brief Add a unit to the list of CUs. - void addUnit(DwarfUnit *CU) { CUs.push_back(CU); } - - /// \brief Emit all of the units to the section listed with the given - /// abbreviation section. - void emitUnits(DwarfDebug *DD, const MCSymbol *ASectionSym); - - /// \brief Emit a set of abbreviations to the specific section. - void emitAbbrevs(const MCSection *); - - /// \brief Emit all of the strings to the section given. - void emitStrings(const MCSection *StrSection, const MCSection *OffsetSection, - const MCSymbol *StrSecSym); - - /// \brief Emit all of the addresses to the section given. - void emitAddresses(const MCSection *AddrSection); - - /// \brief Returns the entry into the start of the pool. - MCSymbol *getStringPoolSym(); - - /// \brief Returns an entry into the string pool with the given - /// string text. - MCSymbol *getStringPoolEntry(StringRef Str); - - /// \brief Returns the index into the string pool with the given - /// string text. - unsigned getStringPoolIndex(StringRef Str); - - /// \brief Returns the string pool. - StrPool *getStringPool() { return &StringPool; } - - /// \brief Returns the index into the address pool with the given - /// label/symbol. - unsigned getAddrPoolIndex(const MCSymbol *Sym, bool TLS = false); - - /// \brief Returns the address pool. - AddrPool *getAddrPool() { return &AddressPool; } -}; /// \brief Helper used to pair up a symbol and its DWARF compile unit. struct SymbolCU { @@ -253,7 +174,7 @@ class DwarfDebug : public AsmPrinterHandler { MapVector CUMap; // Maps subprogram MDNode with its corresponding DwarfCompileUnit. - DenseMap SPMap; + MapVector SPMap; // Maps a CU DIE with its corresponding DwarfCompileUnit. DenseMap CUDieMap; @@ -287,16 +208,13 @@ class DwarfDebug : public AsmPrinterHandler { ScopeVariablesMap ScopeVariables; // Collection of abstract variables. - DenseMap AbstractVariables; + DenseMap> AbstractVariables; + SmallVector, 64> ConcreteVariables; // Collection of DebugLocEntry. Stored in a linked list so that DIELocLists // can refer to them in spite of insertions into this list. SmallVector DotDebugLocEntries; - // Collection of subprogram DIEs that are marked (at the end of the module) - // as DW_AT_inline. - SmallPtrSet InlinedSubprogramDIEs; - // This is a collection of subprogram MDNodes that are processed to // create DIEs. SmallPtrSet ProcessedSPNodes; @@ -307,15 +225,8 @@ class DwarfDebug : public AsmPrinterHandler { // Maps instruction with label emitted after instruction. DenseMap LabelsAfterInsn; - // Every user variable mentioned by a DBG_VALUE instruction in order of - // appearance. - SmallVector UserVariables; - - // For each user variable, keep a list of DBG_VALUE instructions in order. - // The list can also contain normal instructions that clobber the previous - // DBG_VALUE. - typedef DenseMap > - DbgValueHistoryMap; + // History of DBG_VALUE and clobber instructions for each user variable. + // Variables are listed in order of appearance. DbgValueHistoryMap DbgValues; // Previous instruction's location information. This is used to determine @@ -333,10 +244,6 @@ class DwarfDebug : public AsmPrinterHandler { // If nonnull, stores the current machine instruction we're processing. const MachineInstr *CurMI; - // If nonnull, stores the section that the previous function was allocated to - // emitting. - const MCSection *PrevSection; - // If nonnull, stores the CU in which the previous subprogram was contained. const DwarfCompileUnit *PrevCU; @@ -348,6 +255,7 @@ class DwarfDebug : public AsmPrinterHandler { MCSymbol *DwarfDebugLocSectionSym, *DwarfLineSectionSym, *DwarfAddrSectionSym; MCSymbol *FunctionBeginSym, *FunctionEndSym; MCSymbol *DwarfInfoDWOSectionSym, *DwarfAbbrevDWOSectionSym; + MCSymbol *DwarfTypesDWOSectionSym; MCSymbol *DwarfStrDWOSectionSym; MCSymbol *DwarfGnuPubNamesSectionSym, *DwarfGnuPubTypesSectionSym; @@ -373,6 +281,8 @@ class DwarfDebug : public AsmPrinterHandler { // them. DenseMap DwarfTypeUnits; + SmallVector, DICompositeType>, 1> TypeUnitsUnderConstruction; + // Whether to emit the pubnames/pubtypes sections. bool HasDwarfPubSections; @@ -410,46 +320,38 @@ class DwarfDebug : public AsmPrinterHandler { // True iff there are multiple CUs in this module. bool SingleCU; + bool IsDarwin; + + AddressPool AddrPool; + + DwarfAccelTable AccelNames; + DwarfAccelTable AccelObjC; + DwarfAccelTable AccelNamespace; + DwarfAccelTable AccelTypes; + + DenseMap FunctionDIs; MCDwarfDwoLineTable *getDwoLineTable(const DwarfCompileUnit &); void addScopeVariable(LexicalScope *LS, DbgVariable *Var); + void addNonArgumentScopeVariable(LexicalScope *LS, DbgVariable *Var); - const SmallVectorImpl &getUnits() { + const SmallVectorImpl> &getUnits() { return InfoHolder.getUnits(); } /// \brief Find abstract variable associated with Var. - DbgVariable *findAbstractVariable(DIVariable &Var, DebugLoc Loc); - - /// \brief Find DIE for the given subprogram and attach appropriate - /// DW_AT_low_pc and DW_AT_high_pc attributes. If there are global - /// variables in this scope then create and insert DIEs for these - /// variables. - DIE *updateSubprogramScopeDIE(DwarfCompileUnit *SPCU, DISubprogram SP); - - /// \brief A helper function to check whether the DIE for a given Scope is - /// going to be null. - bool isLexicalScopeDIENull(LexicalScope *Scope); - - /// \brief A helper function to construct a RangeSpanList for a given - /// lexical scope. - void addScopeRangeList(DwarfCompileUnit *TheCU, DIE *ScopeDIE, - const SmallVectorImpl &Range); - - /// \brief Construct new DW_TAG_lexical_block for this scope and - /// attach DW_AT_low_pc/DW_AT_high_pc labels. - DIE *constructLexicalScopeDIE(DwarfCompileUnit *TheCU, LexicalScope *Scope); - - /// \brief This scope represents inlined body of a function. Construct - /// DIE to represent this concrete inlined copy of the function. - DIE *constructInlinedScopeDIE(DwarfCompileUnit *TheCU, LexicalScope *Scope); - - /// \brief Construct a DIE for this scope. - DIE *constructScopeDIE(DwarfCompileUnit *TheCU, LexicalScope *Scope); - /// A helper function to create children of a Scope DIE. - DIE *createScopeChildrenDIE(DwarfCompileUnit *TheCU, LexicalScope *Scope, - SmallVectorImpl &Children); + DbgVariable *getExistingAbstractVariable(const DIVariable &DV, + DIVariable &Cleansed); + DbgVariable *getExistingAbstractVariable(const DIVariable &DV); + void createAbstractVariable(const DIVariable &DV, LexicalScope *Scope); + void ensureAbstractVariableIsCreated(const DIVariable &Var, + const MDNode *Scope); + void ensureAbstractVariableIsCreatedIfScoped(const DIVariable &Var, + const MDNode *Scope); + + /// \brief Construct a DIE for this abstract scope. + void constructAbstractSubprogramScopeDIE(LexicalScope *Scope); /// \brief Emit initial Dwarf sections with a label at the start of each one. void emitSectionLabels(); @@ -460,12 +362,13 @@ class DwarfDebug : public AsmPrinterHandler { /// \brief Compute the size and offset of all the DIEs. void computeSizeAndOffsets(); - /// \brief Attach DW_AT_inline attribute with inlined subprogram DIEs. - void computeInlinedDIEs(); - /// \brief Collect info for variables that were optimized out. void collectDeadVariables(); + void finishVariableDefinitions(); + + void finishSubprogramDefinitions(); + /// \brief Finish off debug information after all functions have been /// processed. void finalizeModuleInfo(); @@ -484,6 +387,10 @@ class DwarfDebug : public AsmPrinterHandler { /// the line matrix. void emitEndOfLineMatrix(unsigned SectionEnd); + /// \brief Emit a specified accelerator table. + void emitAccel(DwarfAccelTable &Accel, const MCSection *Section, + StringRef TableName, StringRef SymName); + /// \brief Emit visible names into a hashed accelerator table section. void emitAccelNames(); @@ -520,6 +427,9 @@ class DwarfDebug : public AsmPrinterHandler { /// \brief Emit visible names into a debug loc section. void emitDebugLoc(); + /// \brief Emit visible names into a debug loc dwo section. + void emitDebugLocDWO(); + /// \brief Emit visible names into a debug aranges section. void emitDebugARanges(); @@ -532,15 +442,16 @@ class DwarfDebug : public AsmPrinterHandler { /// DWARF 5 Experimental Split Dwarf Emitters /// \brief Initialize common features of skeleton units. - void initSkeletonUnit(const DwarfUnit *U, DIE *Die, DwarfUnit *NewU); + void initSkeletonUnit(const DwarfUnit &U, DIE &Die, + std::unique_ptr NewU); /// \brief Construct the split debug info compile unit for the debug info /// section. - DwarfCompileUnit *constructSkeletonCU(const DwarfCompileUnit *CU); + DwarfCompileUnit &constructSkeletonCU(const DwarfCompileUnit &CU); /// \brief Construct the split debug info compile unit for the debug info /// section. - DwarfTypeUnit *constructSkeletonTU(DwarfTypeUnit *TU); + DwarfTypeUnit &constructSkeletonTU(DwarfTypeUnit &TU); /// \brief Emit the debug info dwo section. void emitDebugInfoDWO(); @@ -556,25 +467,15 @@ class DwarfDebug : public AsmPrinterHandler { /// Flags to let the linker know we have emitted new style pubnames. Only /// emit it here if we don't have a skeleton CU for split dwarf. - void addGnuPubAttributes(DwarfUnit *U, DIE *D) const; + void addGnuPubAttributes(DwarfUnit &U, DIE &D) const; /// \brief Create new DwarfCompileUnit for the given metadata node with tag /// DW_TAG_compile_unit. - DwarfCompileUnit *constructDwarfCompileUnit(DICompileUnit DIUnit); - - /// \brief Construct subprogram DIE. - void constructSubprogramDIE(DwarfCompileUnit *TheCU, const MDNode *N); + DwarfCompileUnit &constructDwarfCompileUnit(DICompileUnit DIUnit); /// \brief Construct imported_module or imported_declaration DIE. - void constructImportedEntityDIE(DwarfCompileUnit *TheCU, const MDNode *N); - - /// \brief Construct import_module DIE. - void constructImportedEntityDIE(DwarfCompileUnit *TheCU, const MDNode *N, - DIE *Context); - - /// \brief Construct import_module DIE. - void constructImportedEntityDIE(DwarfCompileUnit *TheCU, - const DIImportedEntity &Module, DIE *Context); + void constructAndAddImportedEntityDIE(DwarfCompileUnit &TheCU, + const MDNode *N); /// \brief Register a source line with debug info. Returns the unique /// label that was emitted and which provides correspondence to the @@ -591,37 +492,36 @@ class DwarfDebug : public AsmPrinterHandler { bool addCurrentFnArgument(DbgVariable *Var, LexicalScope *Scope); /// \brief Populate LexicalScope entries with variables' info. - void collectVariableInfo(SmallPtrSet &ProcessedVars); + void collectVariableInfo(DwarfCompileUnit &TheCU, DISubprogram SP, + SmallPtrSetImpl &ProcessedVars); + + /// \brief Build the location list for all DBG_VALUEs in the + /// function that describe the same variable. + void buildLocationList(SmallVectorImpl &DebugLoc, + const DbgValueHistoryMap::InstrRanges &Ranges); /// \brief Collect variable information from the side table maintained /// by MMI. - void collectVariableInfoFromMMITable(SmallPtrSet &P); + void collectVariableInfoFromMMITable(SmallPtrSetImpl &P); /// \brief Ensure that a label will be emitted before MI. void requestLabelBeforeInsn(const MachineInstr *MI) { - LabelsBeforeInsn.insert(std::make_pair(MI, (MCSymbol *)0)); + LabelsBeforeInsn.insert(std::make_pair(MI, nullptr)); } - /// \brief Return Label preceding the instruction. - MCSymbol *getLabelBeforeInsn(const MachineInstr *MI); - /// \brief Ensure that a label will be emitted after MI. void requestLabelAfterInsn(const MachineInstr *MI) { - LabelsAfterInsn.insert(std::make_pair(MI, (MCSymbol *)0)); + LabelsAfterInsn.insert(std::make_pair(MI, nullptr)); } - /// \brief Return Label immediately following the instruction. - MCSymbol *getLabelAfterInsn(const MachineInstr *MI); - - void attachLowHighPC(DwarfCompileUnit *Unit, DIE *D, MCSymbol *Begin, - MCSymbol *End); - public: //===--------------------------------------------------------------------===// // Main entry points. // DwarfDebug(AsmPrinter *A, Module *M); + ~DwarfDebug() override; + void insertDIE(const MDNode *TypeMD, DIE *Die) { MDTypeNodeToDieMap.insert(std::make_pair(TypeMD, Die)); } @@ -651,7 +551,7 @@ public: /// \brief Add a DIE to the set of types that we're going to pull into /// type units. void addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier, - DIE *Die, DICompositeType CTy); + DIE &Die, DICompositeType CTy); /// \brief Add a label so that arange data can be generated for it. void addArangeLabel(SymbolCU SCU) { ArangeLabels.push_back(SCU); } @@ -663,7 +563,7 @@ public: } /// \brief Recursively Emits a debug information entry. - void emitDIE(DIE *Die); + void emitDIE(DIE &Die); // Experimental DWARF5 features. @@ -681,11 +581,15 @@ public: /// Returns the section symbol for the .debug_loc section. MCSymbol *getDebugLocSym() const { return DwarfDebugLocSectionSym; } - /// Returns the previous section that was emitted into. - const MCSection *getPrevSection() const { return PrevSection; } + /// Returns the section symbol for the .debug_str section. + MCSymbol *getDebugStrSym() const { return DwarfStrSectionSym; } + + /// Returns the section symbol for the .debug_ranges section. + MCSymbol *getRangeSectionSym() const { return DwarfDebugRangeSectionSym; } /// Returns the previous CU that was being updated const DwarfCompileUnit *getPrevCU() const { return PrevCU; } + void setPrevCU(const DwarfCompileUnit *PrevCU) { this->PrevCU = PrevCU; } /// Returns the entries for the .debug_loc section. const SmallVectorImpl & @@ -696,6 +600,13 @@ public: /// \brief Emit an entry for the debug loc section. This can be used to /// handle an entry that's going to be emitted into the debug loc section. void emitDebugLocEntry(ByteStreamer &Streamer, const DebugLocEntry &Entry); + /// \brief emit a single value for the debug loc section. + void emitDebugLocValue(ByteStreamer &Streamer, + const DebugLocEntry::Value &Value); + /// Emits an optimal (=sorted) sequence of DW_OP_pieces. + void emitLocPieces(ByteStreamer &Streamer, + const DITypeIdentifierMap &Map, + ArrayRef Values); /// Emit the location for a debug loc entry, including the size header. void emitDebugLocEntryLocation(const DebugLocEntry &Entry); @@ -717,6 +628,62 @@ public: /// isSubprogramContext - Return true if Context is either a subprogram /// or another context nested inside a subprogram. bool isSubprogramContext(const MDNode *Context); + + void addSubprogramNames(DISubprogram SP, DIE &Die); + + AddressPool &getAddressPool() { return AddrPool; } + + void addAccelName(StringRef Name, const DIE &Die); + + void addAccelObjC(StringRef Name, const DIE &Die); + + void addAccelNamespace(StringRef Name, const DIE &Die); + + void addAccelType(StringRef Name, const DIE &Die, char Flags); + + const MachineFunction *getCurrentFunction() const { return CurFn; } + const MCSymbol *getFunctionBeginSym() const { return FunctionBeginSym; } + const MCSymbol *getFunctionEndSym() const { return FunctionEndSym; } + + iterator_range + findImportedEntitiesForScope(const MDNode *Scope) const { + return make_range(std::equal_range( + ScopesWithImportedEntities.begin(), ScopesWithImportedEntities.end(), + std::pair(Scope, nullptr), + less_first())); + } + + /// \brief A helper function to check whether the DIE for a given Scope is + /// going to be null. + bool isLexicalScopeDIENull(LexicalScope *Scope); + + /// \brief Return Label preceding the instruction. + MCSymbol *getLabelBeforeInsn(const MachineInstr *MI); + + /// \brief Return Label immediately following the instruction. + MCSymbol *getLabelAfterInsn(const MachineInstr *MI); + + // FIXME: Consider rolling ranges up into DwarfDebug since we use a single + // range_base anyway, so there's no need to keep them as separate per-CU range + // lists. (though one day we might end up with a range.dwo section, in which + // case it'd go to DwarfFile) + unsigned getNextRangeNumber() { return GlobalRangeCount++; } + + // FIXME: Sink these functions down into DwarfFile/Dwarf*Unit. + + DenseMap &getAbstractSPDies() { + return AbstractSPDies; + } + + ScopeVariablesMap &getScopeVariables() { return ScopeVariables; } + + SmallPtrSet &getProcessedSPNodes() { + return ProcessedSPNodes; + } + + SmallVector &getCurrentFnArguments() { + return CurrentFnArguments; + } }; } // End of namespace llvm