1313#include " llvm/CodeGen/AccelTable.h"
1414#include " DwarfCompileUnit.h"
1515#include " llvm/ADT/STLExtras.h"
16- #include " llvm/ADT/StringMap.h"
1716#include " llvm/ADT/Twine.h"
1817#include " llvm/BinaryFormat/Dwarf.h"
1918#include " llvm/CodeGen/AsmPrinter.h"
@@ -200,32 +199,30 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
200199 uint32_t AugmentationStringSize = sizeof (AugmentationString);
201200 char AugmentationString[8 ] = {' L' , ' L' , ' V' , ' M' , ' 0' , ' 7' , ' 0' , ' 0' };
202201
203- Header (uint32_t CompUnitCount, uint32_t BucketCount, uint32_t NameCount)
204- : CompUnitCount(CompUnitCount), BucketCount(BucketCount),
205- NameCount (NameCount) {}
202+ Header (uint32_t CompUnitCount, uint32_t LocalTypeUnitCount,
203+ uint32_t BucketCount, uint32_t NameCount)
204+ : CompUnitCount(CompUnitCount), LocalTypeUnitCount(LocalTypeUnitCount),
205+ BucketCount (BucketCount), NameCount(NameCount) {}
206206
207207 void emit (Dwarf5AccelTableWriter &Ctx);
208208 };
209- struct AttributeEncoding {
210- dwarf::Index Index;
211- dwarf::Form Form;
212- };
213209
214210 Header Header;
215- DenseMap<uint32_t , SmallVector<AttributeEncoding, 2 >> Abbreviations;
211+ DenseMap<uint32_t , SmallVector<DWARF5AccelTableData::AttributeEncoding, 2 >>
212+ Abbreviations;
216213 ArrayRef<std::variant<MCSymbol *, uint64_t >> CompUnits;
217- llvm::function_ref<unsigned (const DataT &)> getCUIndexForEntry;
214+ ArrayRef<std::variant<MCSymbol *, uint64_t >> TypeUnits;
215+ llvm::function_ref<GetIndexForEntryReturnType(const DataT &)>
216+ getIndexForEntry;
218217 MCSymbol *ContributionEnd = nullptr ;
219218 MCSymbol *AbbrevStart = Asm->createTempSymbol (" names_abbrev_start" );
220219 MCSymbol *AbbrevEnd = Asm->createTempSymbol (" names_abbrev_end" );
221220 MCSymbol *EntryPool = Asm->createTempSymbol (" names_entries" );
222221
223- DenseSet<uint32_t > getUniqueTags () const ;
224-
225- // Right now, we emit uniform attributes for all tags.
226- SmallVector<AttributeEncoding, 2 > getUniformAttributes () const ;
222+ void populateAbbrevsMap ();
227223
228224 void emitCUList () const ;
225+ void emitTUList () const ;
229226 void emitBuckets () const ;
230227 void emitStringOffsets () const ;
231228 void emitAbbrevs () const ;
@@ -236,7 +233,9 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
236233 Dwarf5AccelTableWriter (
237234 AsmPrinter *Asm, const AccelTableBase &Contents,
238235 ArrayRef<std::variant<MCSymbol *, uint64_t >> CompUnits,
239- llvm::function_ref<unsigned (const DataT &)> GetCUIndexForEntry);
236+ ArrayRef<std::variant<MCSymbol *, uint64_t >> TypeUnits,
237+ llvm::function_ref<GetIndexForEntryReturnType(const DataT &)>
238+ getIndexForEntry);
240239
241240 void emit ();
242241};
@@ -388,31 +387,39 @@ void Dwarf5AccelTableWriter<DataT>::Header::emit(Dwarf5AccelTableWriter &Ctx) {
388387 Asm->OutStreamer ->emitBytes ({AugmentationString, AugmentationStringSize});
389388}
390389
390+ static uint32_t constexpr LowerBitSize = dwarf::DW_IDX_type_hash;
391+ static uint32_t getTagFromAbbreviationTag (const uint32_t AbbrvTag) {
392+ return AbbrvTag >> LowerBitSize;
393+ }
394+ static uint32_t
395+ constructAbbreviationTag (const unsigned Tag,
396+ const GetIndexForEntryReturnType &EntryRet) {
397+ uint32_t AbbrvTag = 0 ;
398+ if (EntryRet)
399+ AbbrvTag |= 1 << EntryRet->second .Index ;
400+ AbbrvTag |= 1 << dwarf::DW_IDX_die_offset;
401+ AbbrvTag |= Tag << LowerBitSize;
402+ return AbbrvTag;
403+ }
391404template <typename DataT>
392- DenseSet<uint32_t > Dwarf5AccelTableWriter<DataT>::getUniqueTags() const {
393- DenseSet<uint32_t > UniqueTags;
405+ void Dwarf5AccelTableWriter<DataT>::populateAbbrevsMap() {
394406 for (auto &Bucket : Contents.getBuckets ()) {
395407 for (auto *Hash : Bucket) {
396408 for (auto *Value : Hash->Values ) {
409+ GetIndexForEntryReturnType EntryRet =
410+ getIndexForEntry (*static_cast <const DataT *>(Value));
397411 unsigned Tag = static_cast <const DataT *>(Value)->getDieTag ();
398- UniqueTags.insert (Tag);
412+ uint32_t AbbrvTag = constructAbbreviationTag (Tag, EntryRet);
413+ if (Abbreviations.count (AbbrvTag) == 0 ) {
414+ SmallVector<DWARF5AccelTableData::AttributeEncoding, 2 > UA;
415+ if (EntryRet)
416+ UA.push_back (EntryRet->second );
417+ UA.push_back ({dwarf::DW_IDX_die_offset, dwarf::DW_FORM_ref4});
418+ Abbreviations.try_emplace (AbbrvTag, UA);
419+ }
399420 }
400421 }
401422 }
402- return UniqueTags;
403- }
404-
405- template <typename DataT>
406- SmallVector<typename Dwarf5AccelTableWriter<DataT>::AttributeEncoding, 2 >
407- Dwarf5AccelTableWriter<DataT>::getUniformAttributes() const {
408- SmallVector<AttributeEncoding, 2 > UA;
409- if (CompUnits.size () > 1 ) {
410- size_t LargestCUIndex = CompUnits.size () - 1 ;
411- dwarf::Form Form = DIEInteger::BestForm (/* IsSigned*/ false , LargestCUIndex);
412- UA.push_back ({dwarf::DW_IDX_compile_unit, Form});
413- }
414- UA.push_back ({dwarf::DW_IDX_die_offset, dwarf::DW_FORM_ref4});
415- return UA;
416423}
417424
418425template <typename DataT>
@@ -426,6 +433,17 @@ void Dwarf5AccelTableWriter<DataT>::emitCUList() const {
426433 }
427434}
428435
436+ template <typename DataT>
437+ void Dwarf5AccelTableWriter<DataT>::emitTUList() const {
438+ for (const auto &TU : enumerate(TypeUnits)) {
439+ Asm->OutStreamer ->AddComment (" Type unit " + Twine (TU.index ()));
440+ if (std::holds_alternative<MCSymbol *>(TU.value ()))
441+ Asm->emitDwarfSymbolReference (std::get<MCSymbol *>(TU.value ()));
442+ else
443+ Asm->emitDwarfLengthOrOffset (std::get<uint64_t >(TU.value ()));
444+ }
445+ }
446+
429447template <typename DataT>
430448void Dwarf5AccelTableWriter<DataT>::emitBuckets() const {
431449 uint32_t Index = 1 ;
@@ -453,10 +471,11 @@ void Dwarf5AccelTableWriter<DataT>::emitAbbrevs() const {
453471 Asm->OutStreamer ->emitLabel (AbbrevStart);
454472 for (const auto &Abbrev : Abbreviations) {
455473 Asm->OutStreamer ->AddComment (" Abbrev code" );
456- assert (Abbrev.first != 0 );
457- Asm->emitULEB128 (Abbrev.first );
458- Asm->OutStreamer ->AddComment (dwarf::TagString (Abbrev.first ));
474+ uint32_t Tag = getTagFromAbbreviationTag (Abbrev.first );
475+ assert (Tag != 0 );
459476 Asm->emitULEB128 (Abbrev.first );
477+ Asm->OutStreamer ->AddComment (dwarf::TagString (Tag));
478+ Asm->emitULEB128 (Tag);
460479 for (const auto &AttrEnc : Abbrev.second ) {
461480 Asm->emitULEB128 (AttrEnc.Index , dwarf::IndexString (AttrEnc.Index ).data ());
462481 Asm->emitULEB128 (AttrEnc.Form ,
@@ -471,16 +490,21 @@ void Dwarf5AccelTableWriter<DataT>::emitAbbrevs() const {
471490
472491template <typename DataT>
473492void Dwarf5AccelTableWriter<DataT>::emitEntry(const DataT &Entry) const {
474- auto AbbrevIt = Abbreviations.find (Entry.getDieTag ());
493+ GetIndexForEntryReturnType EntryRet = getIndexForEntry (Entry);
494+ uint32_t AbbrvTag = constructAbbreviationTag (Entry.getDieTag (), EntryRet);
495+ auto AbbrevIt = Abbreviations.find (AbbrvTag);
475496 assert (AbbrevIt != Abbreviations.end () &&
476497 " Why wasn't this abbrev generated?" );
477-
498+ assert (getTagFromAbbreviationTag (AbbrevIt->first ) == Entry.getDieTag () &&
499+ " Invalid Tag" );
478500 Asm->emitULEB128 (AbbrevIt->first , " Abbreviation code" );
501+
479502 for (const auto &AttrEnc : AbbrevIt->second ) {
480503 Asm->OutStreamer ->AddComment (dwarf::IndexString (AttrEnc.Index ));
481504 switch (AttrEnc.Index ) {
482- case dwarf::DW_IDX_compile_unit: {
483- DIEInteger ID (getCUIndexForEntry (Entry));
505+ case dwarf::DW_IDX_compile_unit:
506+ case dwarf::DW_IDX_type_unit: {
507+ DIEInteger ID (EntryRet->first );
484508 ID.emitValue (Asm, AttrEnc.Form );
485509 break ;
486510 }
@@ -512,22 +536,21 @@ template <typename DataT>
512536Dwarf5AccelTableWriter<DataT>::Dwarf5AccelTableWriter(
513537 AsmPrinter *Asm, const AccelTableBase &Contents,
514538 ArrayRef<std::variant<MCSymbol *, uint64_t >> CompUnits,
515- llvm::function_ref<unsigned (const DataT &)> getCUIndexForEntry)
539+ ArrayRef<std::variant<MCSymbol *, uint64_t >> TypeUnits,
540+ llvm::function_ref<GetIndexForEntryReturnType(const DataT &)>
541+ getIndexForEntry)
516542 : AccelTableWriter(Asm, Contents, false ),
517- Header (CompUnits.size(), Contents.getBucketCount(),
543+ Header (CompUnits.size(), TypeUnits.size(), Contents.getBucketCount(),
518544 Contents.getUniqueNameCount()),
519- CompUnits(CompUnits), getCUIndexForEntry(std::move(getCUIndexForEntry)) {
520- DenseSet<uint32_t > UniqueTags = getUniqueTags ();
521- SmallVector<AttributeEncoding, 2 > UniformAttributes = getUniformAttributes ();
522-
523- Abbreviations.reserve (UniqueTags.size ());
524- for (uint32_t Tag : UniqueTags)
525- Abbreviations.try_emplace (Tag, UniformAttributes);
545+ CompUnits(CompUnits), TypeUnits(TypeUnits),
546+ getIndexForEntry(std::move(getIndexForEntry)) {
547+ populateAbbrevsMap ();
526548}
527549
528550template <typename DataT> void Dwarf5AccelTableWriter<DataT>::emit() {
529551 Header.emit (*this );
530552 emitCUList ();
553+ emitTUList ();
531554 emitBuckets ();
532555 emitHashes ();
533556 emitStringOffsets ();
@@ -545,12 +568,17 @@ void llvm::emitAppleAccelTableImpl(AsmPrinter *Asm, AccelTableBase &Contents,
545568 AppleAccelTableWriter (Asm, Contents, Atoms, SecBegin).emit ();
546569}
547570
548- void llvm::emitDWARF5AccelTable (
549- AsmPrinter *Asm, AccelTable<DWARF5AccelTableData> &Contents,
550- const DwarfDebug &DD, ArrayRef<std::unique_ptr<DwarfCompileUnit>> CUs) {
571+ void llvm::emitDWARF5AccelTable (AsmPrinter *Asm,
572+ AccelTable<DWARF5AccelTableData> &Contents,
573+ const DwarfDebug &DD,
574+ ArrayRef<std::unique_ptr<DwarfCompileUnit>> CUs,
575+ ArrayRef<std::unique_ptr<DwarfTypeUnit>> TUs) {
551576 std::vector<std::variant<MCSymbol *, uint64_t >> CompUnits;
577+ std::vector<std::variant<MCSymbol *, uint64_t >> TypeUnits;
552578 SmallVector<unsigned , 1 > CUIndex (CUs.size ());
553- int Count = 0 ;
579+ DenseMap<const DIE *, unsigned > TUIndex (TUs.size ());
580+ int CUCount = 0 ;
581+ int TUCount = 0 ;
554582 for (const auto &CU : enumerate(CUs)) {
555583 switch (CU.value ()->getCUNode ()->getNameTableKind ()) {
556584 case DICompileUnit::DebugNameTableKind::Default:
@@ -559,37 +587,61 @@ void llvm::emitDWARF5AccelTable(
559587 default :
560588 continue ;
561589 }
562- CUIndex[CU.index ()] = Count ++;
590+ CUIndex[CU.index ()] = CUCount ++;
563591 assert (CU.index () == CU.value ()->getUniqueID ());
564592 const DwarfCompileUnit *MainCU =
565593 DD.useSplitDwarf () ? CU.value ()->getSkeleton () : CU.value ().get ();
566594 CompUnits.push_back (MainCU->getLabelBegin ());
567595 }
568596
597+ for (const auto &TU : enumerate(TUs)) {
598+ switch (TU.value ()->getCUNode ()->getNameTableKind ()) {
599+ case DICompileUnit::DebugNameTableKind::Default:
600+ break ;
601+ default :
602+ continue ;
603+ }
604+ TUIndex[&TU.value ()->getUnitDie ()] = TUCount++;
605+ const DwarfTypeUnit *MainTU = TU.value ().get ();
606+ TypeUnits.push_back (MainTU->getLabelBegin ());
607+ }
608+
569609 if (CompUnits.empty ())
570610 return ;
571611
572612 Asm->OutStreamer ->switchSection (
573613 Asm->getObjFileLowering ().getDwarfDebugNamesSection ());
574614
575615 Contents.finalize (Asm, " names" );
616+ dwarf::Form CUIndexForm =
617+ DIEInteger::BestForm (/* IsSigned*/ false , CompUnits.size () - 1 );
618+ dwarf::Form TUIndexForm =
619+ DIEInteger::BestForm (/* IsSigned*/ false , TypeUnits.size () - 1 );
576620 Dwarf5AccelTableWriter<DWARF5AccelTableData>(
577- Asm, Contents, CompUnits,
578- [&](const DWARF5AccelTableData &Entry) {
621+ Asm, Contents, CompUnits, TypeUnits,
622+ [&](const DWARF5AccelTableData &Entry) -> GetIndexForEntryReturnType {
579623 const DIE *CUDie = Entry.getDie ().getUnitDie ();
580- return CUIndex[DD.lookupCU (CUDie)->getUniqueID ()];
624+ GetIndexForEntryReturnType Index = std::nullopt ;
625+ if (CUDie->getTag () == dwarf::DW_TAG_type_unit)
626+ Index = {TUIndex[CUDie], {dwarf::DW_IDX_type_unit, TUIndexForm}};
627+ else if (CUIndex.size () > 1 )
628+ Index = {CUIndex[DD.lookupCU (CUDie)->getUniqueID ()],
629+ {dwarf::DW_IDX_compile_unit, CUIndexForm}};
630+ return Index;
581631 })
582632 .emit ();
583633}
584634
585635void llvm::emitDWARF5AccelTable (
586636 AsmPrinter *Asm, AccelTable<DWARF5AccelTableStaticData> &Contents,
587637 ArrayRef<std::variant<MCSymbol *, uint64_t >> CUs,
588- llvm::function_ref<unsigned (const DWARF5AccelTableStaticData &)>
589- getCUIndexForEntry) {
638+ llvm::function_ref<
639+ GetIndexForEntryReturnType (const DWARF5AccelTableStaticData &)>
640+ getIndexForEntry) {
641+ std::vector<std::variant<MCSymbol *, uint64_t >> TypeUnits;
590642 Contents.finalize (Asm, " names" );
591- Dwarf5AccelTableWriter<DWARF5AccelTableStaticData>(Asm, Contents, CUs,
592- getCUIndexForEntry )
643+ Dwarf5AccelTableWriter<DWARF5AccelTableStaticData>(
644+ Asm, Contents, CUs, TypeUnits, getIndexForEntry )
593645 .emit ();
594646}
595647
0 commit comments