Index: llvm/trunk/include/llvm/CodeGen/DIE.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/DIE.h +++ llvm/trunk/include/llvm/CodeGen/DIE.h @@ -244,25 +244,6 @@ }; //===--------------------------------------------------------------------===// -/// \brief A signature reference to a type unit. -class DIETypeSignature { - const DwarfTypeUnit *Unit; - - DIETypeSignature() = delete; - -public: - explicit DIETypeSignature(const DwarfTypeUnit &Unit) : Unit(&Unit) {} - - void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; - unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { - assert(Form == dwarf::DW_FORM_ref_sig8); - return 8; - } - - void print(raw_ostream &O) const; -}; - -//===--------------------------------------------------------------------===// /// DIELocList - Represents a pointer to a location list in the debug_loc /// section. // @@ -308,8 +289,9 @@ /// All values that aren't standard layout (or are larger than 8 bytes) /// should be stored by reference instead of by value. typedef AlignedCharArrayUnion ValTy; + DIEDelta *, DIEEntry, DIEBlock *, DIELoc *, + DIELocList> + ValTy; static_assert(sizeof(ValTy) <= sizeof(uint64_t) || sizeof(ValTy) <= sizeof(void *), "Expected all large types to be stored via pointer"); Index: llvm/trunk/include/llvm/CodeGen/DIEValue.def =================================================================== --- llvm/trunk/include/llvm/CodeGen/DIEValue.def +++ llvm/trunk/include/llvm/CodeGen/DIEValue.def @@ -37,7 +37,6 @@ HANDLE_DIEVALUE_SMALL(Label) HANDLE_DIEVALUE_LARGE(Delta) HANDLE_DIEVALUE_SMALL(Entry) -HANDLE_DIEVALUE_SMALL(TypeSignature) HANDLE_DIEVALUE_LARGE(Block) HANDLE_DIEVALUE_LARGE(Loc) HANDLE_DIEVALUE_SMALL(LocList) Index: llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp +++ llvm/trunk/lib/CodeGen/AsmPrinter/DIE.cpp @@ -479,20 +479,6 @@ } //===----------------------------------------------------------------------===// -// DIETypeSignature Implementation -//===----------------------------------------------------------------------===// -void DIETypeSignature::EmitValue(const AsmPrinter *Asm, - dwarf::Form Form) const { - assert(Form == dwarf::DW_FORM_ref_sig8); - Asm->OutStreamer->EmitIntValue(Unit->getTypeSignature(), 8); -} - -LLVM_DUMP_METHOD -void DIETypeSignature::print(raw_ostream &O) const { - O << format("Type Unit: 0x%lx", Unit->getTypeSignature()); -} - -//===----------------------------------------------------------------------===// // DIELoc Implementation //===----------------------------------------------------------------------===// Index: llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp +++ llvm/trunk/lib/CodeGen/AsmPrinter/DIEHash.cpp @@ -353,7 +353,6 @@ case DIEValue::isExpr: case DIEValue::isLabel: case DIEValue::isDelta: - case DIEValue::isTypeSignature: llvm_unreachable("Add support for additional value types."); } } Index: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -29,6 +29,12 @@ class LexicalScope; class DwarfCompileUnit : public DwarfUnit { + /// A numeric ID unique among all CUs in the module + unsigned UniqueID; + + /// Offset of the UnitDie from beginning of debug info section. + unsigned DebugInfoOffset = 0; + /// The attribute index of DW_AT_stmt_list in the compile unit DIE, avoiding /// the need to search for it in applyStmtList. DIE::value_iterator StmtListValue; @@ -77,6 +83,10 @@ DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU); + unsigned getUniqueID() const { return UniqueID; } + unsigned getDebugInfoOffset() const { return DebugInfoOffset; } + void setDebugInfoOffset(unsigned DbgInfoOff) { DebugInfoOffset = DbgInfoOff; } + DwarfCompileUnit *getSkeleton() const { return Skeleton; } Index: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -19,7 +19,7 @@ DwarfCompileUnit::DwarfCompileUnit(unsigned UID, const DICompileUnit *Node, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU) - : DwarfUnit(UID, dwarf::DW_TAG_compile_unit, Node, A, DW, DWU), + : DwarfUnit(dwarf::DW_TAG_compile_unit, Node, A, DW, DWU), UniqueID(UID), Skeleton(nullptr), BaseAddress(nullptr) { insertDIE(Node, &getUnitDie()); MacroLabelBegin = Asm->createTempSymbol("cu_macro_begin"); Index: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -235,9 +235,9 @@ /// Holders for the various debug information flags that we might need to /// have exposed. See accessor functions below for description. - /// Map from MDNodes for user-defined types to the type units that - /// describe them. - DenseMap DwarfTypeUnits; + /// Map from MDNodes for user-defined types to their type signatures. Also + /// used to keep track of which types we have emitted type units for. + DenseMap TypeSignatures; SmallVector< std::pair, const DICompositeType *>, 1> @@ -295,7 +295,7 @@ MCDwarfDwoLineTable *getDwoLineTable(const DwarfCompileUnit &); - const SmallVectorImpl> &getUnits() { + const SmallVectorImpl> &getUnits() { return InfoHolder.getUnits(); } @@ -391,7 +391,7 @@ /// Initialize common features of skeleton units. void initSkeletonUnit(const DwarfUnit &U, DIE &Die, - std::unique_ptr NewU); + std::unique_ptr NewU); /// Construct the split debug info compile unit for the debug info /// section. Index: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1628,9 +1628,10 @@ } // Sort the CU list (again, to ensure consistent output order). - std::sort(CUs.begin(), CUs.end(), [](const DwarfUnit *A, const DwarfUnit *B) { - return A->getUniqueID() < B->getUniqueID(); - }); + std::sort(CUs.begin(), CUs.end(), + [](const DwarfCompileUnit *A, const DwarfCompileUnit *B) { + return A->getUniqueID() < B->getUniqueID(); + }); // Emit an arange table for each CU we used. for (DwarfCompileUnit *CU : CUs) { @@ -1793,7 +1794,7 @@ // DWARF5 Experimental Separate Dwarf emitters. void DwarfDebug::initSkeletonUnit(const DwarfUnit &U, DIE &Die, - std::unique_ptr NewU) { + std::unique_ptr NewU) { NewU->addString(Die, dwarf::DW_AT_GNU_dwo_name, U.getCUNode()->getSplitDebugFilename()); @@ -1882,21 +1883,19 @@ if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed()) return; - const DwarfTypeUnit *&TU = DwarfTypeUnits[CTy]; - if (TU) { - CU.addDIETypeSignature(RefDie, *TU); + auto Ins = TypeSignatures.insert(std::make_pair(CTy, 0)); + if (!Ins.second) { + CU.addDIETypeSignature(RefDie, Ins.first->second); return; } bool TopLevelType = TypeUnitsUnderConstruction.empty(); AddrPool.resetUsedFlag(); - auto OwnedUnit = make_unique( - InfoHolder.getUnits().size() + TypeUnitsUnderConstruction.size(), CU, Asm, - this, &InfoHolder, getDwoLineTable(CU)); + auto OwnedUnit = make_unique(CU, Asm, this, &InfoHolder, + getDwoLineTable(CU)); DwarfTypeUnit &NewTU = *OwnedUnit; DIE &UnitDie = NewTU.getUnitDie(); - TU = &NewTU; TypeUnitsUnderConstruction.push_back( std::make_pair(std::move(OwnedUnit), CTy)); @@ -1905,6 +1904,7 @@ uint64_t Signature = makeTypeSignature(Identifier); NewTU.setTypeSignature(Signature); + Ins.first->second = Signature; if (useSplitDwarf()) NewTU.initSection(Asm->getObjFileLowering().getDwarfTypesDWOSection()); @@ -1928,7 +1928,7 @@ // This is pessimistic as some of these types might not be dependent on // the type that used an address. for (const auto &TU : TypeUnitsToAdd) - DwarfTypeUnits.erase(TU.second); + TypeSignatures.erase(TU.second); // Construct this type in the CU directly. // This is inefficient because all the dependent types will be rebuilt @@ -1940,10 +1940,12 @@ // If the type wasn't dependent on fission addresses, finish adding the type // and all its dependent types. - for (auto &TU : TypeUnitsToAdd) - InfoHolder.addUnit(std::move(TU.first)); + for (auto &TU : TypeUnitsToAdd) { + InfoHolder.computeSizeAndOffsetsForUnit(TU.first.get()); + InfoHolder.emitUnit(TU.first.get(), useSplitDwarf()); + } } - CU.addDIETypeSignature(RefDie, NewTU); + CU.addDIETypeSignature(RefDie, Signature); } // Accelerator table mutators - add each name along with its companion Index: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.h @@ -25,6 +25,7 @@ namespace llvm { class AsmPrinter; class DbgVariable; +class DwarfCompileUnit; class DwarfUnit; class DIEAbbrev; class MCSymbol; @@ -47,7 +48,7 @@ std::vector Abbreviations; // A pointer to all units in the section. - SmallVector, 1> CUs; + SmallVector, 1> CUs; DwarfStringPool StrPool; @@ -67,7 +68,9 @@ ~DwarfFile(); - const SmallVectorImpl> &getUnits() { return CUs; } + const SmallVectorImpl> &getUnits() { + return CUs; + } /// \brief Compute the size and offset of a DIE given an incoming Offset. unsigned computeSizeAndOffset(DIE &Die, unsigned Offset); @@ -75,6 +78,10 @@ /// \brief Compute the size and offset of all the DIEs. void computeSizeAndOffsets(); + /// \brief Compute the size and offset of all the DIEs in the given unit. + /// \returns The size of the root DIE. + unsigned computeSizeAndOffsetsForUnit(DwarfUnit *TheU); + /// Define a unique number for the abbreviation. /// /// Compute the abbreviation for \c Die, look up its unique number, and @@ -82,12 +89,15 @@ DIEAbbrev &assignAbbrevNumber(DIE &Die); /// \brief Add a unit to the list of CUs. - void addUnit(std::unique_ptr U); + void addUnit(std::unique_ptr U); /// \brief Emit all of the units to the section listed with the given /// abbreviation section. void emitUnits(bool UseOffsets); + /// \brief Emit the given unit to its section. + void emitUnit(DwarfUnit *U, bool UseOffsets); + /// \brief Emit a set of abbreviations to the specific section. void emitAbbrevs(MCSection *); Index: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.cpp =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.cpp +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfFile.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "DwarfFile.h" +#include "DwarfCompileUnit.h" #include "DwarfDebug.h" #include "DwarfUnit.h" #include "llvm/ADT/STLExtras.h" @@ -50,22 +51,25 @@ return *New; } -void DwarfFile::addUnit(std::unique_ptr U) { +void DwarfFile::addUnit(std::unique_ptr U) { CUs.push_back(std::move(U)); } // Emit the various dwarf units to the unit section USection with // the abbreviations going into ASection. void DwarfFile::emitUnits(bool UseOffsets) { - for (const auto &TheU : CUs) { - DIE &Die = TheU->getUnitDie(); - MCSection *USection = TheU->getSection(); - Asm->OutStreamer->SwitchSection(USection); + for (const auto &TheU : CUs) + emitUnit(TheU.get(), UseOffsets); +} - TheU->emitHeader(UseOffsets); +void DwarfFile::emitUnit(DwarfUnit *TheU, bool UseOffsets) { + DIE &Die = TheU->getUnitDie(); + MCSection *USection = TheU->getSection(); + Asm->OutStreamer->SwitchSection(USection); - Asm->emitDwarfDIE(Die); - } + TheU->emitHeader(UseOffsets); + + Asm->emitDwarfDIE(Die); } // Compute the size and offset for each DIE. @@ -77,17 +81,20 @@ // DIE within each compile unit. All offsets are CU relative. for (const auto &TheU : CUs) { TheU->setDebugInfoOffset(SecOffset); - - // CU-relative offset is reset to 0 here. - unsigned Offset = sizeof(int32_t) + // Length of Unit Info - TheU->getHeaderSize(); // Unit-specific headers - - // EndOffset here is CU-relative, after laying out - // all of the CU DIE. - unsigned EndOffset = computeSizeAndOffset(TheU->getUnitDie(), Offset); - SecOffset += EndOffset; + SecOffset += computeSizeAndOffsetsForUnit(TheU.get()); } } + +unsigned DwarfFile::computeSizeAndOffsetsForUnit(DwarfUnit *TheU) { + // CU-relative offset is reset to 0 here. + unsigned Offset = sizeof(int32_t) + // Length of Unit Info + TheU->getHeaderSize(); // Unit-specific headers + + // The return value here is CU-relative, after laying out + // all of the CU DIE. + return computeSizeAndOffset(TheU->getUnitDie(), Offset); +} + // Compute the size and offset of a DIE. The offset is relative to start of the // CU. It returns the offset after laying out the DIE. unsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) { Index: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.h =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -67,9 +67,6 @@ /// source file. class DwarfUnit { protected: - /// A numeric ID unique among all CUs in the module - unsigned UniqueID; - /// MDNode for the compile unit. const DICompileUnit *CUNode; @@ -79,9 +76,6 @@ /// Unit debug information entry. DIE &UnitDie; - /// Offset of the UnitDie from beginning of debug info section. - unsigned DebugInfoOffset; - /// Target of Dwarf emission. AsmPrinter *Asm; @@ -110,8 +104,8 @@ /// The section this unit will be emitted in. MCSection *Section; - DwarfUnit(unsigned UID, dwarf::Tag, const DICompileUnit *CU, AsmPrinter *A, - DwarfDebug *DW, DwarfFile *DWU); + DwarfUnit(dwarf::Tag, const DICompileUnit *CU, AsmPrinter *A, DwarfDebug *DW, + DwarfFile *DWU); bool applySubprogramDefinitionAttributes(const DISubprogram *SP, DIE &SPDie); @@ -127,14 +121,10 @@ // Accessors. AsmPrinter* getAsmPrinter() const { return Asm; } - unsigned getUniqueID() const { return UniqueID; } uint16_t getLanguage() const { return CUNode->getSourceLanguage(); } const DICompileUnit *getCUNode() const { return CUNode; } DIE &getUnitDie() { return UnitDie; } - unsigned getDebugInfoOffset() const { return DebugInfoOffset; } - void setDebugInfoOffset(unsigned DbgInfoOff) { DebugInfoOffset = DbgInfoOff; } - /// Return true if this compile unit has something to write out. bool hasContent() const { return UnitDie.hasChildren(); } @@ -221,7 +211,7 @@ void addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIEEntry Entry); /// Add a type's DW_AT_signature and set the declaration flag. - void addDIETypeSignature(DIE &Die, const DwarfTypeUnit &Type); + void addDIETypeSignature(DIE &Die, uint64_t Signature); /// Add an attribute containing the type signature for a unique identifier. void addDIETypeSignature(DIE &Die, dwarf::Attribute Attribute, StringRef Identifier); @@ -383,12 +373,10 @@ bool isDwoUnit() const override; public: - DwarfTypeUnit(unsigned UID, DwarfCompileUnit &CU, AsmPrinter *A, - DwarfDebug *DW, DwarfFile *DWU, - MCDwarfDwoLineTable *SplitLineTable = nullptr); + DwarfTypeUnit(DwarfCompileUnit &CU, AsmPrinter *A, DwarfDebug *DW, + DwarfFile *DWU, MCDwarfDwoLineTable *SplitLineTable = nullptr); void setTypeSignature(uint64_t Signature) { TypeSignature = Signature; } - uint64_t getTypeSignature() const { return TypeSignature; } void setType(const DIE *Ty) { this->Ty = Ty; } /// Emit the header for this unit, not including the initial length field. Index: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -63,21 +63,19 @@ return MachineReg == TRI.getFrameRegister(*AP.MF); } -DwarfUnit::DwarfUnit(unsigned UID, dwarf::Tag UnitTag, - const DICompileUnit *Node, AsmPrinter *A, DwarfDebug *DW, - DwarfFile *DWU) - : UniqueID(UID), CUNode(Node), - UnitDie(*DIE::get(DIEValueAllocator, UnitTag)), DebugInfoOffset(0), - Asm(A), DD(DW), DU(DWU), IndexTyDie(nullptr), Section(nullptr) { +DwarfUnit::DwarfUnit(dwarf::Tag UnitTag, const DICompileUnit *Node, + AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU) + : CUNode(Node), UnitDie(*DIE::get(DIEValueAllocator, UnitTag)), Asm(A), + DD(DW), DU(DWU), IndexTyDie(nullptr), Section(nullptr) { assert(UnitTag == dwarf::DW_TAG_compile_unit || UnitTag == dwarf::DW_TAG_type_unit); } -DwarfTypeUnit::DwarfTypeUnit(unsigned UID, DwarfCompileUnit &CU, AsmPrinter *A, +DwarfTypeUnit::DwarfTypeUnit(DwarfCompileUnit &CU, AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU, MCDwarfDwoLineTable *SplitLineTable) - : DwarfUnit(UID, dwarf::DW_TAG_type_unit, CU.getCUNode(), A, DW, DWU), - CU(CU), SplitLineTable(SplitLineTable) { + : DwarfUnit(dwarf::DW_TAG_type_unit, CU.getCUNode(), A, DW, DWU), CU(CU), + SplitLineTable(SplitLineTable) { if (SplitLineTable) addSectionOffset(UnitDie, dwarf::DW_AT_stmt_list, 0); } @@ -268,7 +266,7 @@ addDIEEntry(Die, Attribute, DIEEntry(Entry)); } -void DwarfUnit::addDIETypeSignature(DIE &Die, const DwarfTypeUnit &Type) { +void DwarfUnit::addDIETypeSignature(DIE &Die, uint64_t Signature) { // Flag the type unit reference as a declaration so that if it contains // members (implicit special members, static data member definitions, member // declarations for definitions in this CU, etc) consumers don't get confused @@ -276,7 +274,7 @@ addFlag(Die, dwarf::DW_AT_declaration); Die.addValue(DIEValueAllocator, dwarf::DW_AT_signature, - dwarf::DW_FORM_ref_sig8, DIETypeSignature(Type)); + dwarf::DW_FORM_ref_sig8, DIEInteger(Signature)); } void DwarfUnit::addDIETypeSignature(DIE &Die, dwarf::Attribute Attribute, @@ -1524,8 +1522,11 @@ // start of the section. Use a relocatable offset where needed to ensure // linking doesn't invalidate that offset. const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); - Asm->emitDwarfSymbolReference(TLOF.getDwarfAbbrevSection()->getBeginSymbol(), - UseOffsets); + if (UseOffsets) + Asm->EmitInt32(0); + else + Asm->emitDwarfSymbolReference( + TLOF.getDwarfAbbrevSection()->getBeginSymbol(), false); Asm->OutStreamer->AddComment("Address Size (in bytes)"); Asm->EmitInt8(Asm->getDataLayout().getPointerSize());