Index: llvm/include/llvm/CodeGen/AccelTable.h =================================================================== --- llvm/include/llvm/CodeGen/AccelTable.h +++ llvm/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; @@ -261,6 +261,8 @@ #endif const DIE &getDie() const { return Die; } + uint64_t getDieOffset() const { return Die.getOffset(); } + unsigned getDieTag() const { return Die.getTag(); } protected: const DIE &Die; @@ -268,6 +270,27 @@ uint64_t order() const override { return Die.getOffset(); } }; +class DWARF5AccelTableStaticData : public AccelTableData { +public: + static uint32_t hash(StringRef Name) { return caseFoldingDjbHash(Name); } + + DWARF5AccelTableStaticData(uint64_t DieOffset, unsigned DieTag) + : DieOffset(DieOffset), DieTag(DieTag) {} + +#ifndef NDEBUG + void print(raw_ostream &OS) const override; +#endif + + uint64_t getDieOffset() const { return DieOffset; } + unsigned getDieTag() const { return DieTag; } + +protected: + uint64_t DieOffset; + unsigned DieTag; + + uint64_t order() const override { return DieOffset; } +}; + void emitAppleAccelTableImpl(AsmPrinter *Asm, AccelTableBase &Contents, StringRef Prefix, const MCSymbol *SecBegin, ArrayRef Atoms); @@ -287,6 +310,12 @@ const DwarfDebug &DD, ArrayRef> CUs); +void emitDWARF5AccelTable( + AsmPrinter *Asm, AccelTable &Contents, + ArrayRef CUs, + std::function + getCUIndexForEntry); + /// Accelerator table data implementation for simple Apple accelerator tables /// with just a DIE reference. class AppleAccelTableOffsetData : public AppleAccelTableData { Index: llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp +++ llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp @@ -21,6 +21,7 @@ #include "llvm/CodeGen/DIE.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -180,8 +181,14 @@ #endif }; -/// Class responsible for emitting a DWARF v5 Accelerator Table. The only public -/// function is emit(), which performs the actual emission. +/// Class responsible for emitting a DWARF v5 Accelerator Table. The only +/// public function is emit(), which performs the actual emission. +/// +/// The class is templated in its data type. This allows us to emit both dyamic +/// and static data entries. A callback abstract the logic to provide a CU +/// index for a given entry, which is different per data type, but identical +/// for every entry in the same table. +template class Dwarf5AccelTableWriter : public AccelTableWriter { struct Header { uint32_t UnitLength = 0; @@ -209,8 +216,8 @@ Header Header; DenseMap> Abbreviations; - const DwarfDebug ⅅ - ArrayRef> CompUnits; + ArrayRef CompUnits; + std::function getCUIndexForEntry; MCSymbol *ContributionStart = Asm->createTempSymbol("names_start"); MCSymbol *ContributionEnd = Asm->createTempSymbol("names_end"); MCSymbol *AbbrevStart = Asm->createTempSymbol("names_abbrev_start"); @@ -226,13 +233,14 @@ void emitBuckets() const; void emitStringOffsets() const; void emitAbbrevs() const; - void emitEntry(const DWARF5AccelTableData &Data) const; + void emitEntry(const DataT &Data) const; void emitData() const; public: - Dwarf5AccelTableWriter(AsmPrinter *Asm, const AccelTableBase &Contents, - const DwarfDebug &DD, - ArrayRef> CompUnits); + Dwarf5AccelTableWriter( + AsmPrinter *Asm, const AccelTableBase &Contents, + ArrayRef CompUnits, + std::function GetCUIndexForEntry); void emit() const; }; @@ -354,7 +362,8 @@ emitData(); } -void Dwarf5AccelTableWriter::Header::emit( +template +void Dwarf5AccelTableWriter::Header::emit( const Dwarf5AccelTableWriter &Ctx) const { assert(CompUnitCount > 0 && "Index must have at least one CU."); @@ -386,22 +395,23 @@ Asm->OutStreamer->EmitBytes({AugmentationString, AugmentationStringSize}); } -DenseSet Dwarf5AccelTableWriter::getUniqueTags() const { +template +DenseSet Dwarf5AccelTableWriter::getUniqueTags() const { DenseSet UniqueTags; for (auto &Bucket : Contents.getBuckets()) { for (auto *Hash : Bucket) { for (auto *Value : Hash->Values) { - const DIE &Die = - static_cast(Value)->getDie(); - UniqueTags.insert(Die.getTag()); + unsigned Tag = static_cast(Value)->getDieTag(); + UniqueTags.insert(Tag); } } } return UniqueTags; } -SmallVector -Dwarf5AccelTableWriter::getUniformAttributes() const { +template +SmallVector::AttributeEncoding, 2> +Dwarf5AccelTableWriter::getUniformAttributes() const { SmallVector UA; if (CompUnits.size() > 1) { size_t LargestCUIndex = CompUnits.size() - 1; @@ -412,17 +422,16 @@ return UA; } -void Dwarf5AccelTableWriter::emitCUList() const { +template +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()); + Asm->emitDwarfSymbolReference(CU.value()); } } -void Dwarf5AccelTableWriter::emitBuckets() const { +template +void Dwarf5AccelTableWriter::emitBuckets() const { uint32_t Index = 1; for (const auto &Bucket : enumerate(Contents.getBuckets())) { Asm->OutStreamer->AddComment("Bucket " + Twine(Bucket.index())); @@ -431,7 +440,8 @@ } } -void Dwarf5AccelTableWriter::emitStringOffsets() const { +template +void Dwarf5AccelTableWriter::emitStringOffsets() const { for (const auto &Bucket : enumerate(Contents.getBuckets())) { for (auto *Hash : Bucket.value()) { DwarfStringPoolEntryRef String = Hash->Name; @@ -442,7 +452,8 @@ } } -void Dwarf5AccelTableWriter::emitAbbrevs() const { +template +void Dwarf5AccelTableWriter::emitAbbrevs() const { Asm->OutStreamer->EmitLabel(AbbrevStart); for (const auto &Abbrev : Abbreviations) { Asm->OutStreamer->AddComment("Abbrev code"); @@ -462,9 +473,9 @@ Asm->OutStreamer->EmitLabel(AbbrevEnd); } -void Dwarf5AccelTableWriter::emitEntry( - const DWARF5AccelTableData &Entry) const { - auto AbbrevIt = Abbreviations.find(Entry.getDie().getTag()); +template +void Dwarf5AccelTableWriter::emitEntry(const DataT &Entry) const { + auto AbbrevIt = Abbreviations.find(Entry.getDieTag()); assert(AbbrevIt != Abbreviations.end() && "Why wasn't this abbrev generated?"); @@ -473,14 +484,13 @@ Asm->OutStreamer->AddComment(dwarf::IndexString(AttrEnc.Index)); switch (AttrEnc.Index) { case dwarf::DW_IDX_compile_unit: { - const DIE *CUDie = Entry.getDie().getUnitDie(); - DIEInteger ID(DD.lookupCU(CUDie)->getUniqueID()); + DIEInteger ID(getCUIndexForEntry(Entry)); ID.EmitValue(Asm, AttrEnc.Form); break; } case dwarf::DW_IDX_die_offset: assert(AttrEnc.Form == dwarf::DW_FORM_ref4); - Asm->emitInt32(Entry.getDie().getOffset()); + Asm->emitInt32(Entry.getDieOffset()); break; default: llvm_unreachable("Unexpected index attribute!"); @@ -488,27 +498,29 @@ } } -void Dwarf5AccelTableWriter::emitData() const { +template void Dwarf5AccelTableWriter::emitData() const { Asm->OutStreamer->EmitLabel(EntryPool); for (auto &Bucket : Contents.getBuckets()) { for (auto *Hash : Bucket) { // Remember to emit the label for our offset. Asm->OutStreamer->EmitLabel(Hash->Sym); for (const auto *Value : Hash->Values) - emitEntry(*static_cast(Value)); + emitEntry(*static_cast(Value)); Asm->OutStreamer->AddComment("End of list: " + Hash->Name.getString()); Asm->emitInt32(0); } } } -Dwarf5AccelTableWriter::Dwarf5AccelTableWriter( - AsmPrinter *Asm, const AccelTableBase &Contents, const DwarfDebug &DD, - ArrayRef> CompUnits) +template +Dwarf5AccelTableWriter::Dwarf5AccelTableWriter( + AsmPrinter *Asm, const AccelTableBase &Contents, + ArrayRef CompUnits, + std::function getCUIndexForEntry) : AccelTableWriter(Asm, Contents, false), Header(CompUnits.size(), Contents.getBucketCount(), Contents.getUniqueNameCount()), - DD(DD), CompUnits(CompUnits) { + CompUnits(CompUnits), getCUIndexForEntry(std::move(getCUIndexForEntry)) { DenseSet UniqueTags = getUniqueTags(); SmallVector UniformAttributes = getUniformAttributes(); @@ -517,7 +529,7 @@ Abbreviations.try_emplace(Tag, UniformAttributes); } -void Dwarf5AccelTableWriter::emit() const { +template void Dwarf5AccelTableWriter::emit() const { Header.emit(*this); emitCUList(); emitBuckets(); @@ -540,8 +552,33 @@ void llvm::emitDWARF5AccelTable( AsmPrinter *Asm, AccelTable &Contents, const DwarfDebug &DD, ArrayRef> CUs) { + std::vector CompUnits; + for (const auto &CU : enumerate(CUs)) { + assert(CU.index() == CU.value()->getUniqueID()); + const DwarfCompileUnit *MainCU = + DD.useSplitDwarf() ? CU.value()->getSkeleton() : CU.value().get(); + CompUnits.push_back(MainCU->getLabelBegin()); + } + + Contents.finalize(Asm, "names"); + Dwarf5AccelTableWriter( + Asm, Contents, CompUnits, + [&DD](const DWARF5AccelTableData &Entry) { + const DIE *CUDie = Entry.getDie().getUnitDie(); + return DD.lookupCU(CUDie)->getUniqueID(); + }) + .emit(); +} + +void emitDWARF5AccelTable( + AsmPrinter *Asm, AccelTable &Contents, + ArrayRef CUs, + std::function + getCUIndexForEntry) { Contents.finalize(Asm, "names"); - Dwarf5AccelTableWriter(Asm, Contents, DD, CUs).emit(); + Dwarf5AccelTableWriter(Asm, Contents, CUs, + getCUIndexForEntry) + .emit(); } void AppleAccelTableOffsetData::emit(AsmPrinter *Asm) const { @@ -651,8 +688,13 @@ } void DWARF5AccelTableData::print(raw_ostream &OS) const { - OS << " Offset: " << Die.getOffset() << "\n"; - OS << " Tag: " << dwarf::TagString(Die.getTag()) << "\n"; + OS << " Offset: " << getDieOffset() << "\n"; + OS << " Tag: " << dwarf::TagString(getDieTag()) << "\n"; +} + +void DWARF5AccelTableStaticData::print(raw_ostream &OS) const { + OS << " Offset: " << getDieOffset() << "\n"; + OS << " Tag: " << dwarf::TagString(getDieTag()) << "\n"; } void AppleAccelTableOffsetData::print(raw_ostream &OS) const {