Index: llvm/trunk/include/llvm/CodeGen/AccelTable.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/AccelTable.h +++ llvm/trunk/include/llvm/CodeGen/AccelTable.h @@ -122,8 +122,8 @@ return order() < Other.order(); } - // Subclasses should implement: - // static uint32_t hash(StringRef Name); + // Subclasses should implement: + // static uint32_t hash(StringRef Name); #ifndef NDEBUG virtual void print(raw_ostream &OS) const = 0; @@ -287,6 +287,25 @@ const DwarfDebug &DD, ArrayRef> CUs); +/// Abstraction to allow different users (DwarfDebug and dsymutil) to emit +/// Dwarf accelerator tables. +class AccelTableWriterInfo { +public: + virtual ~AccelTableWriterInfo() = default; + virtual MCSymbol* getLabelForCU(unsigned Idx) const = 0; + virtual unsigned getNumberOfCUs() const = 0; + virtual unsigned getUnqiueIDForUnitDie(const DIE* UnitDie) const = 0; +}; + +void emitDWARF5AccelTable(AsmPrinter *Asm, + AccelTable &Contents, + const DwarfDebug &DD, + ArrayRef> CUs); + +void emitDWARF5AccelTable( + AsmPrinter *Asm, AccelTable &Contents, + std::unique_ptr WriterInfo); + /// Accelerator table data implementation for simple Apple accelerator tables /// with just a DIE reference. class AppleAccelTableOffsetData : public AppleAccelTableData { Index: llvm/trunk/lib/CodeGen/AsmPrinter/AccelTable.cpp =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/AccelTable.cpp +++ llvm/trunk/lib/CodeGen/AsmPrinter/AccelTable.cpp @@ -209,8 +209,7 @@ Header Header; DenseMap> Abbreviations; - const DwarfDebug ⅅ - ArrayRef> CompUnits; + std::unique_ptr WriterInfo; MCSymbol *ContributionStart = Asm->createTempSymbol("names_start"); MCSymbol *ContributionEnd = Asm->createTempSymbol("names_end"); MCSymbol *AbbrevStart = Asm->createTempSymbol("names_abbrev_start"); @@ -231,13 +230,47 @@ public: Dwarf5AccelTableWriter(AsmPrinter *Asm, const AccelTableBase &Contents, - const DwarfDebug &DD, - ArrayRef> CompUnits); + std::unique_ptr WriterInfo); void emit() const; }; + +/// Default emitter info used by DwarfDebug. +class DefaultAccelTableWriterInfo final : public AccelTableWriterInfo { +private: + const DwarfDebug ⅅ + ArrayRef> CompUnits; + +public: + DefaultAccelTableWriterInfo(const DwarfDebug &DD, ArrayRef> CompUnits); + MCSymbol *getLabelForCU(unsigned Idx) const override; + unsigned getNumberOfCUs() const override; + unsigned getUnqiueIDForUnitDie(const DIE *UnitDie) const override; +}; } // namespace +DefaultAccelTableWriterInfo::DefaultAccelTableWriterInfo( + const DwarfDebug &DD, ArrayRef> CompUnits) + : DD(DD), CompUnits(CompUnits) {} + +MCSymbol *DefaultAccelTableWriterInfo::getLabelForCU(unsigned Idx) const { + assert(Idx < CompUnits.size()); + const auto &CU = CompUnits[Idx]; + assert(Idx == CU->getUniqueID()); + const DwarfCompileUnit *MainCU = + DD.useSplitDwarf() ? CU->getSkeleton() : CU.get(); + return MainCU->getLabelBegin(); +} + +unsigned DefaultAccelTableWriterInfo::getNumberOfCUs() const { + return CompUnits.size(); +} + +unsigned +DefaultAccelTableWriterInfo::getUnqiueIDForUnitDie(const DIE *UnitDie) const { + return DD.lookupCU(UnitDie)->getUniqueID(); +} + void AccelTableWriter::emitHashes() const { uint64_t PrevHash = std::numeric_limits::max(); unsigned BucketIdx = 0; @@ -403,8 +436,8 @@ SmallVector Dwarf5AccelTableWriter::getUniformAttributes() const { SmallVector UA; - if (CompUnits.size() > 1) { - size_t LargestCUIndex = CompUnits.size() - 1; + if (WriterInfo->getNumberOfCUs() > 1) { + size_t LargestCUIndex = WriterInfo->getNumberOfCUs() - 1; dwarf::Form Form = DIEInteger::BestForm(/*IsSigned*/ false, LargestCUIndex); UA.push_back({dwarf::DW_IDX_compile_unit, Form}); } @@ -413,12 +446,10 @@ } void Dwarf5AccelTableWriter::emitCUList() const { - for (const auto &CU : enumerate(CompUnits)) { - assert(CU.index() == CU.value()->getUniqueID()); - Asm->OutStreamer->AddComment("Compilation unit " + Twine(CU.index())); - const DwarfCompileUnit *MainCU = - DD.useSplitDwarf() ? CU.value()->getSkeleton() : CU.value().get(); - Asm->emitDwarfSymbolReference(MainCU->getLabelBegin()); + for (unsigned Idx = 0, CUs = WriterInfo->getNumberOfCUs(); Idx < CUs; + ++Idx) { + Asm->OutStreamer->AddComment("Compilation unit " + Twine(Idx)); + Asm->emitDwarfSymbolReference(WriterInfo->getLabelForCU(Idx)); } } @@ -474,7 +505,7 @@ switch (AttrEnc.Index) { case dwarf::DW_IDX_compile_unit: { const DIE *CUDie = Entry.getDie().getUnitDie(); - DIEInteger ID(DD.lookupCU(CUDie)->getUniqueID()); + DIEInteger ID(WriterInfo->getUnqiueIDForUnitDie(CUDie)); ID.EmitValue(Asm, AttrEnc.Form); break; } @@ -503,12 +534,12 @@ } Dwarf5AccelTableWriter::Dwarf5AccelTableWriter( - AsmPrinter *Asm, const AccelTableBase &Contents, const DwarfDebug &DD, - ArrayRef> CompUnits) + AsmPrinter *Asm, const AccelTableBase &Contents, + std::unique_ptr WriterInfo) : AccelTableWriter(Asm, Contents, false), - Header(CompUnits.size(), Contents.getBucketCount(), + Header(WriterInfo->getNumberOfCUs(), Contents.getBucketCount(), Contents.getUniqueNameCount()), - DD(DD), CompUnits(CompUnits) { + WriterInfo(std::move(WriterInfo)) { DenseSet UniqueTags = getUniqueTags(); SmallVector UniformAttributes = getUniformAttributes(); @@ -540,8 +571,15 @@ void llvm::emitDWARF5AccelTable( AsmPrinter *Asm, AccelTable &Contents, const DwarfDebug &DD, ArrayRef> CUs) { + auto WriterInfo = llvm::make_unique(DD, CUs); + emitDWARF5AccelTable(Asm, Contents, std::move(WriterInfo)); +} + +void llvm::emitDWARF5AccelTable( + AsmPrinter *Asm, AccelTable &Contents, + std::unique_ptr WriterInfo) { Contents.finalize(Asm, "names"); - Dwarf5AccelTableWriter(Asm, Contents, DD, CUs).emit(); + Dwarf5AccelTableWriter(Asm, Contents, std::move(WriterInfo)).emit(); } void AppleAccelTableOffsetData::emit(AsmPrinter *Asm) const {