diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp | 219 |
1 files changed, 148 insertions, 71 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp index aab3c2681339..d6f487c18b03 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp @@ -12,8 +12,8 @@ #include "llvm/CodeGen/AccelTable.h" #include "DwarfCompileUnit.h" +#include "DwarfUnit.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringMap.h" #include "llvm/ADT/Twine.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/CodeGen/AsmPrinter.h" @@ -200,32 +200,35 @@ class Dwarf5AccelTableWriter : public AccelTableWriter { uint32_t AugmentationStringSize = sizeof(AugmentationString); char AugmentationString[8] = {'L', 'L', 'V', 'M', '0', '7', '0', '0'}; - Header(uint32_t CompUnitCount, uint32_t BucketCount, uint32_t NameCount) - : CompUnitCount(CompUnitCount), BucketCount(BucketCount), + Header(uint32_t CompUnitCount, uint32_t LocalTypeUnitCount, + uint32_t ForeignTypeUnitCount, uint32_t BucketCount, + uint32_t NameCount) + : CompUnitCount(CompUnitCount), LocalTypeUnitCount(LocalTypeUnitCount), + ForeignTypeUnitCount(ForeignTypeUnitCount), BucketCount(BucketCount), NameCount(NameCount) {} void emit(Dwarf5AccelTableWriter &Ctx); }; - struct AttributeEncoding { - dwarf::Index Index; - dwarf::Form Form; - }; Header Header; - DenseMap<uint32_t, SmallVector<AttributeEncoding, 2>> Abbreviations; - ArrayRef<MCSymbol *> CompUnits; - llvm::function_ref<unsigned(const DataT &)> getCUIndexForEntry; + DenseMap<uint32_t, SmallVector<DWARF5AccelTableData::AttributeEncoding, 2>> + Abbreviations; + ArrayRef<std::variant<MCSymbol *, uint64_t>> CompUnits; + ArrayRef<std::variant<MCSymbol *, uint64_t>> TypeUnits; + llvm::function_ref<std::optional<DWARF5AccelTable::UnitIndexAndEncoding>( + const DataT &)> + getIndexForEntry; MCSymbol *ContributionEnd = nullptr; MCSymbol *AbbrevStart = Asm->createTempSymbol("names_abbrev_start"); MCSymbol *AbbrevEnd = Asm->createTempSymbol("names_abbrev_end"); MCSymbol *EntryPool = Asm->createTempSymbol("names_entries"); + // Indicates if this module is built with Split Dwarf enabled. + bool IsSplitDwarf = false; - DenseSet<uint32_t> getUniqueTags() const; - - // Right now, we emit uniform attributes for all tags. - SmallVector<AttributeEncoding, 2> getUniformAttributes() const; + void populateAbbrevsMap(); void emitCUList() const; + void emitTUList() const; void emitBuckets() const; void emitStringOffsets() const; void emitAbbrevs() const; @@ -235,8 +238,12 @@ class Dwarf5AccelTableWriter : public AccelTableWriter { public: Dwarf5AccelTableWriter( AsmPrinter *Asm, const AccelTableBase &Contents, - ArrayRef<MCSymbol *> CompUnits, - llvm::function_ref<unsigned(const DataT &)> GetCUIndexForEntry); + ArrayRef<std::variant<MCSymbol *, uint64_t>> CompUnits, + ArrayRef<std::variant<MCSymbol *, uint64_t>> TypeUnits, + llvm::function_ref< + std::optional<DWARF5AccelTable::UnitIndexAndEncoding>(const DataT &)> + getIndexForEntry, + bool IsSplitDwarf); void emit(); }; @@ -358,6 +365,11 @@ void AppleAccelTableWriter::emit() const { emitData(); } +DWARF5AccelTableData::DWARF5AccelTableData(const DIE &Die, + const uint32_t UnitID, + const bool IsTU) + : OffsetVal(&Die), DieTag(Die.getTag()), UnitID(UnitID), IsTU(IsTU) {} + template <typename DataT> void Dwarf5AccelTableWriter<DataT>::Header::emit(Dwarf5AccelTableWriter &Ctx) { assert(CompUnitCount > 0 && "Index must have at least one CU."); @@ -388,38 +400,65 @@ void Dwarf5AccelTableWriter<DataT>::Header::emit(Dwarf5AccelTableWriter &Ctx) { Asm->OutStreamer->emitBytes({AugmentationString, AugmentationStringSize}); } +static uint32_t constexpr LowerBitSize = dwarf::DW_IDX_type_hash; +static uint32_t getTagFromAbbreviationTag(const uint32_t AbbrvTag) { + return AbbrvTag >> LowerBitSize; +} + +/// Constructs a unique AbbrevTag that captures what a DIE accesses. +/// Using this tag we can emit a unique abbreviation for each DIE. +static uint32_t constructAbbreviationTag( + const unsigned Tag, + const std::optional<DWARF5AccelTable::UnitIndexAndEncoding> &EntryRet) { + uint32_t AbbrvTag = 0; + if (EntryRet) + AbbrvTag |= 1 << EntryRet->Endoding.Index; + AbbrvTag |= 1 << dwarf::DW_IDX_die_offset; + AbbrvTag |= Tag << LowerBitSize; + return AbbrvTag; +} template <typename DataT> -DenseSet<uint32_t> Dwarf5AccelTableWriter<DataT>::getUniqueTags() const { - DenseSet<uint32_t> UniqueTags; +void Dwarf5AccelTableWriter<DataT>::populateAbbrevsMap() { for (auto &Bucket : Contents.getBuckets()) { for (auto *Hash : Bucket) { for (auto *Value : Hash->Values) { + std::optional<DWARF5AccelTable::UnitIndexAndEncoding> EntryRet = + getIndexForEntry(*static_cast<const DataT *>(Value)); unsigned Tag = static_cast<const DataT *>(Value)->getDieTag(); - UniqueTags.insert(Tag); + uint32_t AbbrvTag = constructAbbreviationTag(Tag, EntryRet); + if (Abbreviations.count(AbbrvTag) == 0) { + SmallVector<DWARF5AccelTableData::AttributeEncoding, 2> UA; + if (EntryRet) + UA.push_back(EntryRet->Endoding); + UA.push_back({dwarf::DW_IDX_die_offset, dwarf::DW_FORM_ref4}); + Abbreviations.try_emplace(AbbrvTag, UA); + } } } } - return UniqueTags; } template <typename DataT> -SmallVector<typename Dwarf5AccelTableWriter<DataT>::AttributeEncoding, 2> -Dwarf5AccelTableWriter<DataT>::getUniformAttributes() const { - SmallVector<AttributeEncoding, 2> UA; - if (CompUnits.size() > 1) { - size_t LargestCUIndex = CompUnits.size() - 1; - dwarf::Form Form = DIEInteger::BestForm(/*IsSigned*/ false, LargestCUIndex); - UA.push_back({dwarf::DW_IDX_compile_unit, Form}); +void Dwarf5AccelTableWriter<DataT>::emitCUList() const { + for (const auto &CU : enumerate(CompUnits)) { + Asm->OutStreamer->AddComment("Compilation unit " + Twine(CU.index())); + if (std::holds_alternative<MCSymbol *>(CU.value())) + Asm->emitDwarfSymbolReference(std::get<MCSymbol *>(CU.value())); + else + Asm->emitDwarfLengthOrOffset(std::get<uint64_t>(CU.value())); } - UA.push_back({dwarf::DW_IDX_die_offset, dwarf::DW_FORM_ref4}); - return UA; } template <typename DataT> -void Dwarf5AccelTableWriter<DataT>::emitCUList() const { - for (const auto &CU : enumerate(CompUnits)) { - Asm->OutStreamer->AddComment("Compilation unit " + Twine(CU.index())); - Asm->emitDwarfSymbolReference(CU.value()); +void Dwarf5AccelTableWriter<DataT>::emitTUList() const { + for (const auto &TU : enumerate(TypeUnits)) { + Asm->OutStreamer->AddComment("Type unit " + Twine(TU.index())); + if (std::holds_alternative<MCSymbol *>(TU.value())) + Asm->emitDwarfSymbolReference(std::get<MCSymbol *>(TU.value())); + else if (IsSplitDwarf) + Asm->emitInt64(std::get<uint64_t>(TU.value())); + else + Asm->emitDwarfLengthOrOffset(std::get<uint64_t>(TU.value())); } } @@ -450,10 +489,11 @@ void Dwarf5AccelTableWriter<DataT>::emitAbbrevs() const { Asm->OutStreamer->emitLabel(AbbrevStart); for (const auto &Abbrev : Abbreviations) { Asm->OutStreamer->AddComment("Abbrev code"); - assert(Abbrev.first != 0); - Asm->emitULEB128(Abbrev.first); - Asm->OutStreamer->AddComment(dwarf::TagString(Abbrev.first)); + uint32_t Tag = getTagFromAbbreviationTag(Abbrev.first); + assert(Tag != 0); Asm->emitULEB128(Abbrev.first); + Asm->OutStreamer->AddComment(dwarf::TagString(Tag)); + Asm->emitULEB128(Tag); for (const auto &AttrEnc : Abbrev.second) { Asm->emitULEB128(AttrEnc.Index, dwarf::IndexString(AttrEnc.Index).data()); Asm->emitULEB128(AttrEnc.Form, @@ -468,16 +508,22 @@ void Dwarf5AccelTableWriter<DataT>::emitAbbrevs() const { template <typename DataT> void Dwarf5AccelTableWriter<DataT>::emitEntry(const DataT &Entry) const { - auto AbbrevIt = Abbreviations.find(Entry.getDieTag()); + std::optional<DWARF5AccelTable::UnitIndexAndEncoding> EntryRet = + getIndexForEntry(Entry); + uint32_t AbbrvTag = constructAbbreviationTag(Entry.getDieTag(), EntryRet); + auto AbbrevIt = Abbreviations.find(AbbrvTag); assert(AbbrevIt != Abbreviations.end() && "Why wasn't this abbrev generated?"); - + assert(getTagFromAbbreviationTag(AbbrevIt->first) == Entry.getDieTag() && + "Invalid Tag"); Asm->emitULEB128(AbbrevIt->first, "Abbreviation code"); + for (const auto &AttrEnc : AbbrevIt->second) { Asm->OutStreamer->AddComment(dwarf::IndexString(AttrEnc.Index)); switch (AttrEnc.Index) { - case dwarf::DW_IDX_compile_unit: { - DIEInteger ID(getCUIndexForEntry(Entry)); + case dwarf::DW_IDX_compile_unit: + case dwarf::DW_IDX_type_unit: { + DIEInteger ID(EntryRet->Index); ID.emitValue(Asm, AttrEnc.Form); break; } @@ -508,23 +554,26 @@ template <typename DataT> void Dwarf5AccelTableWriter<DataT>::emitData() const { template <typename DataT> Dwarf5AccelTableWriter<DataT>::Dwarf5AccelTableWriter( AsmPrinter *Asm, const AccelTableBase &Contents, - ArrayRef<MCSymbol *> CompUnits, - llvm::function_ref<unsigned(const DataT &)> getCUIndexForEntry) + ArrayRef<std::variant<MCSymbol *, uint64_t>> CompUnits, + ArrayRef<std::variant<MCSymbol *, uint64_t>> TypeUnits, + llvm::function_ref< + std::optional<DWARF5AccelTable::UnitIndexAndEncoding>(const DataT &)> + getIndexForEntry, + bool IsSplitDwarf) : AccelTableWriter(Asm, Contents, false), - Header(CompUnits.size(), Contents.getBucketCount(), + Header(CompUnits.size(), IsSplitDwarf ? 0 : TypeUnits.size(), + IsSplitDwarf ? TypeUnits.size() : 0, Contents.getBucketCount(), Contents.getUniqueNameCount()), - CompUnits(CompUnits), getCUIndexForEntry(std::move(getCUIndexForEntry)) { - DenseSet<uint32_t> UniqueTags = getUniqueTags(); - SmallVector<AttributeEncoding, 2> UniformAttributes = getUniformAttributes(); - - Abbreviations.reserve(UniqueTags.size()); - for (uint32_t Tag : UniqueTags) - Abbreviations.try_emplace(Tag, UniformAttributes); + CompUnits(CompUnits), TypeUnits(TypeUnits), + getIndexForEntry(std::move(getIndexForEntry)), + IsSplitDwarf(IsSplitDwarf) { + populateAbbrevsMap(); } template <typename DataT> void Dwarf5AccelTableWriter<DataT>::emit() { Header.emit(*this); emitCUList(); + emitTUList(); emitBuckets(); emitHashes(); emitStringOffsets(); @@ -543,11 +592,15 @@ void llvm::emitAppleAccelTableImpl(AsmPrinter *Asm, AccelTableBase &Contents, } void llvm::emitDWARF5AccelTable( - AsmPrinter *Asm, AccelTable<DWARF5AccelTableData> &Contents, - const DwarfDebug &DD, ArrayRef<std::unique_ptr<DwarfCompileUnit>> CUs) { - std::vector<MCSymbol *> CompUnits; + AsmPrinter *Asm, DWARF5AccelTable &Contents, const DwarfDebug &DD, + ArrayRef<std::unique_ptr<DwarfCompileUnit>> CUs) { + TUVectorTy TUSymbols = Contents.getTypeUnitsSymbols(); + std::vector<std::variant<MCSymbol *, uint64_t>> CompUnits; + std::vector<std::variant<MCSymbol *, uint64_t>> TypeUnits; SmallVector<unsigned, 1> CUIndex(CUs.size()); - int Count = 0; + DenseMap<unsigned, unsigned> TUIndex(TUSymbols.size()); + int CUCount = 0; + int TUCount = 0; for (const auto &CU : enumerate(CUs)) { switch (CU.value()->getCUNode()->getNameTableKind()) { case DICompileUnit::DebugNameTableKind::Default: @@ -556,13 +609,21 @@ void llvm::emitDWARF5AccelTable( default: continue; } - CUIndex[CU.index()] = Count++; + CUIndex[CU.index()] = CUCount++; assert(CU.index() == CU.value()->getUniqueID()); const DwarfCompileUnit *MainCU = DD.useSplitDwarf() ? CU.value()->getSkeleton() : CU.value().get(); CompUnits.push_back(MainCU->getLabelBegin()); } + for (const auto &TU : TUSymbols) { + TUIndex[TU.UniqueID] = TUCount++; + if (DD.useSplitDwarf()) + TypeUnits.push_back(std::get<uint64_t>(TU.LabelOrSignature)); + else + TypeUnits.push_back(std::get<MCSymbol *>(TU.LabelOrSignature)); + } + if (CompUnits.empty()) return; @@ -570,23 +631,44 @@ void llvm::emitDWARF5AccelTable( Asm->getObjFileLowering().getDwarfDebugNamesSection()); Contents.finalize(Asm, "names"); + dwarf::Form CUIndexForm = + DIEInteger::BestForm(/*IsSigned*/ false, CompUnits.size() - 1); + dwarf::Form TUIndexForm = + DIEInteger::BestForm(/*IsSigned*/ false, TypeUnits.size() - 1); Dwarf5AccelTableWriter<DWARF5AccelTableData>( - Asm, Contents, CompUnits, - [&](const DWARF5AccelTableData &Entry) { - const DIE *CUDie = Entry.getDie().getUnitDie(); - return CUIndex[DD.lookupCU(CUDie)->getUniqueID()]; - }) + Asm, Contents, CompUnits, TypeUnits, + [&](const DWARF5AccelTableData &Entry) + -> std::optional<DWARF5AccelTable::UnitIndexAndEncoding> { + if (Entry.isTU()) + return {{TUIndex[Entry.getUnitID()], + {dwarf::DW_IDX_type_unit, TUIndexForm}}}; + if (CUIndex.size() > 1) + return {{CUIndex[Entry.getUnitID()], + {dwarf::DW_IDX_compile_unit, CUIndexForm}}}; + return std::nullopt; + }, + DD.useSplitDwarf()) .emit(); } +void DWARF5AccelTable::addTypeUnitSymbol(DwarfTypeUnit &U) { + TUSymbolsOrHashes.push_back({U.getLabelBegin(), U.getUniqueID()}); +} + +void DWARF5AccelTable::addTypeUnitSignature(DwarfTypeUnit &U) { + TUSymbolsOrHashes.push_back({U.getTypeSignature(), U.getUniqueID()}); +} + void llvm::emitDWARF5AccelTable( - AsmPrinter *Asm, AccelTable<DWARF5AccelTableStaticData> &Contents, - ArrayRef<MCSymbol *> CUs, - llvm::function_ref<unsigned(const DWARF5AccelTableStaticData &)> - getCUIndexForEntry) { + AsmPrinter *Asm, DWARF5AccelTable &Contents, + ArrayRef<std::variant<MCSymbol *, uint64_t>> CUs, + llvm::function_ref<std::optional<DWARF5AccelTable::UnitIndexAndEncoding>( + const DWARF5AccelTableData &)> + getIndexForEntry) { + std::vector<std::variant<MCSymbol *, uint64_t>> TypeUnits; Contents.finalize(Asm, "names"); - Dwarf5AccelTableWriter<DWARF5AccelTableStaticData>(Asm, Contents, CUs, - getCUIndexForEntry) + Dwarf5AccelTableWriter<DWARF5AccelTableData>(Asm, Contents, CUs, TypeUnits, + getIndexForEntry, false) .emit(); } @@ -685,11 +767,6 @@ void DWARF5AccelTableData::print(raw_ostream &OS) const { 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 { OS << " Offset: " << Die.getOffset() << "\n"; } |
