@@ -208,8 +208,13 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
208208 };
209209
210210 Header Header;
211- DenseMap<uint32_t , SmallVector<DWARF5AccelTableData::AttributeEncoding, 3 >>
212- Abbreviations;
211+ // / FoldingSet that uniques the abbreviations.
212+ FoldingSet<DebugNamesAbbrev> AbbreviationsSet;
213+ // / Vector containing DebugNames abbreviations for iteration in order.
214+ SmallVector<DebugNamesAbbrev *, 5 > AbbreviationsVector;
215+ // / The bump allocator to use when creating DIEAbbrev objects in the uniqued
216+ // / storage container.
217+ BumpPtrAllocator Alloc;
213218 ArrayRef<std::variant<MCSymbol *, uint64_t >> CompUnits;
214219 ArrayRef<std::variant<MCSymbol *, uint64_t >> TypeUnits;
215220 llvm::function_ref<std::optional<DWARF5AccelTable::UnitIndexAndEncoding>(
@@ -234,7 +239,7 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
234239 void emitEntry (
235240 const DWARF5AccelTableData &Entry,
236241 const DenseMap<OffsetAndUnitID, MCSymbol *> &DIEOffsetToAccelEntryLabel,
237- DenseSet<MCSymbol *> &EmittedAccelEntrySymbols) const ;
242+ DenseSet<MCSymbol *> &EmittedAccelEntrySymbols);
238243 void emitData ();
239244
240245public:
@@ -370,7 +375,7 @@ void AppleAccelTableWriter::emit() const {
370375DWARF5AccelTableData::DWARF5AccelTableData (const DIE &Die,
371376 const uint32_t UnitID,
372377 const bool IsTU)
373- : OffsetVal(&Die), DieTag(Die.getTag()), UnitID(UnitID ), IsTU(IsTU ) {}
378+ : OffsetVal(&Die), DieTag(Die.getTag()), IsTU(IsTU ), UnitID(UnitID ) {}
374379
375380void Dwarf5AccelTableWriter::Header::emit (Dwarf5AccelTableWriter &Ctx) {
376381 assert (CompUnitCount > 0 && " Index must have at least one CU." );
@@ -409,51 +414,6 @@ DWARF5AccelTableData::getDefiningParentDieOffset(const DIE &Die) {
409414 return {};
410415}
411416
412- enum IdxParentEncoding : uint8_t {
413- NoIndexedParent = 0 , // / Parent information present but parent isn't indexed.
414- Ref4 = 1 , // / Parent information present and parent is indexed.
415- NoParent = 2 , // / Parent information missing.
416- };
417-
418- static uint32_t constexpr NumBitsIdxParent = 2 ;
419-
420- uint8_t encodeIdxParent (const std::optional<dwarf::Form> MaybeParentForm) {
421- if (!MaybeParentForm)
422- return NoParent;
423- switch (*MaybeParentForm) {
424- case dwarf::Form::DW_FORM_flag_present:
425- return NoIndexedParent;
426- case dwarf::Form::DW_FORM_ref4:
427- return Ref4;
428- default :
429- // This is not crashing on bad input: we should only reach this if the
430- // internal compiler logic is faulty; see getFormForIdxParent.
431- llvm_unreachable (" Bad form for IDX_parent" );
432- }
433- }
434-
435- static uint32_t constexpr ParentBitOffset = dwarf::DW_IDX_type_hash;
436- static uint32_t constexpr TagBitOffset = ParentBitOffset + NumBitsIdxParent;
437- static uint32_t getTagFromAbbreviationTag (const uint32_t AbbrvTag) {
438- return AbbrvTag >> TagBitOffset;
439- }
440-
441- // / Constructs a unique AbbrevTag that captures what a DIE accesses.
442- // / Using this tag we can emit a unique abbreviation for each DIE.
443- static uint32_t constructAbbreviationTag (
444- const unsigned Tag,
445- const std::optional<DWARF5AccelTable::UnitIndexAndEncoding> &EntryRet,
446- std::optional<dwarf::Form> MaybeParentForm) {
447- uint32_t AbbrvTag = 0 ;
448- if (EntryRet)
449- AbbrvTag |= 1 << EntryRet->Encoding .Index ;
450- AbbrvTag |= 1 << dwarf::DW_IDX_die_offset;
451- AbbrvTag |= 1 << dwarf::DW_IDX_parent;
452- AbbrvTag |= encodeIdxParent (MaybeParentForm) << ParentBitOffset;
453- AbbrvTag |= Tag << TagBitOffset;
454- return AbbrvTag;
455- }
456-
457417static std::optional<dwarf::Form>
458418getFormForIdxParent (const DenseSet<OffsetAndUnitID> &IndexedOffsets,
459419 std::optional<OffsetAndUnitID> ParentOffset) {
@@ -467,26 +427,42 @@ getFormForIdxParent(const DenseSet<OffsetAndUnitID> &IndexedOffsets,
467427 return dwarf::Form::DW_FORM_flag_present;
468428}
469429
430+ void DebugNamesAbbrev::Profile (FoldingSetNodeID &ID) const {
431+ ID.AddInteger (DieTag);
432+ for (const DebugNamesAbbrev::AttributeEncoding &Enc : AttrVect) {
433+ ID.AddInteger (Enc.Index );
434+ ID.AddInteger (Enc.Form );
435+ }
436+ }
437+
470438void Dwarf5AccelTableWriter::populateAbbrevsMap () {
471439 for (auto &Bucket : Contents.getBuckets ()) {
472440 for (auto *Hash : Bucket) {
473441 for (auto *Value : Hash->getValues <DWARF5AccelTableData *>()) {
474442 std::optional<DWARF5AccelTable::UnitIndexAndEncoding> EntryRet =
475443 getIndexForEntry (*Value);
476- unsigned Tag = Value->getDieTag ();
477444 std::optional<dwarf::Form> MaybeParentForm = getFormForIdxParent (
478445 IndexedOffsets, Value->getParentDieOffsetAndUnitID ());
479- uint32_t AbbrvTag =
480- constructAbbreviationTag (Tag, EntryRet, MaybeParentForm);
481- if (Abbreviations.count (AbbrvTag) == 0 ) {
482- SmallVector<DWARF5AccelTableData::AttributeEncoding, 3 > UA;
483- if (EntryRet)
484- UA.push_back (EntryRet->Encoding );
485- UA.push_back ({dwarf::DW_IDX_die_offset, dwarf::DW_FORM_ref4});
486- if (MaybeParentForm)
487- UA.push_back ({dwarf::DW_IDX_parent, *MaybeParentForm});
488- Abbreviations.try_emplace (AbbrvTag, UA);
446+ DebugNamesAbbrev Abbrev (Value->getDieTag ());
447+ if (EntryRet)
448+ Abbrev.addAttribute (EntryRet->Encoding );
449+ Abbrev.addAttribute ({dwarf::DW_IDX_die_offset, dwarf::DW_FORM_ref4});
450+ if (MaybeParentForm)
451+ Abbrev.addAttribute ({dwarf::DW_IDX_parent, *MaybeParentForm});
452+ FoldingSetNodeID ID;
453+ Abbrev.Profile (ID);
454+ void *InsertPos;
455+ if (DebugNamesAbbrev *Existing =
456+ AbbreviationsSet.FindNodeOrInsertPos (ID, InsertPos)) {
457+ Value->setAbbrevNumber (Existing->getNumber ());
458+ continue ;
489459 }
460+ DebugNamesAbbrev *NewAbbrev =
461+ new (Alloc) DebugNamesAbbrev (std::move (Abbrev));
462+ AbbreviationsVector.push_back (NewAbbrev);
463+ NewAbbrev->setNumber (AbbreviationsVector.size ());
464+ AbbreviationsSet.InsertNode (NewAbbrev, InsertPos);
465+ Value->setAbbrevNumber (NewAbbrev->getNumber ());
490466 }
491467 }
492468 }
@@ -536,14 +512,13 @@ void Dwarf5AccelTableWriter::emitStringOffsets() const {
536512
537513void Dwarf5AccelTableWriter::emitAbbrevs () const {
538514 Asm->OutStreamer ->emitLabel (AbbrevStart);
539- for (const auto & Abbrev : Abbreviations ) {
515+ for (const DebugNamesAbbrev * Abbrev : AbbreviationsVector ) {
540516 Asm->OutStreamer ->AddComment (" Abbrev code" );
541- uint32_t Tag = getTagFromAbbreviationTag (Abbrev.first );
542- assert (Tag != 0 );
543- Asm->emitULEB128 (Abbrev.first );
544- Asm->OutStreamer ->AddComment (dwarf::TagString (Tag));
545- Asm->emitULEB128 (Tag);
546- for (const auto &AttrEnc : Abbrev.second ) {
517+ Asm->emitULEB128 (Abbrev->getNumber ());
518+ Asm->OutStreamer ->AddComment (dwarf::TagString (Abbrev->getDieTag ()));
519+ Asm->emitULEB128 (Abbrev->getDieTag ());
520+ for (const DebugNamesAbbrev::AttributeEncoding &AttrEnc :
521+ Abbrev->getAttributes ()) {
547522 Asm->emitULEB128 (AttrEnc.Index , dwarf::IndexString (AttrEnc.Index ).data ());
548523 Asm->emitULEB128 (AttrEnc.Form ,
549524 dwarf::FormEncodingString (AttrEnc.Form ).data ());
@@ -558,21 +533,15 @@ void Dwarf5AccelTableWriter::emitAbbrevs() const {
558533void Dwarf5AccelTableWriter::emitEntry (
559534 const DWARF5AccelTableData &Entry,
560535 const DenseMap<OffsetAndUnitID, MCSymbol *> &DIEOffsetToAccelEntryLabel,
561- DenseSet<MCSymbol *> &EmittedAccelEntrySymbols) const {
536+ DenseSet<MCSymbol *> &EmittedAccelEntrySymbols) {
537+ unsigned AbbrevIndex = Entry.getAbbrevNumber () - 1 ;
538+ assert (AbbrevIndex < AbbreviationsVector.size () &&
539+ " Entry abbrev index is outside of abbreviations vector range." );
540+ DebugNamesAbbrev *Abbrev = AbbreviationsVector[AbbrevIndex];
562541 std::optional<DWARF5AccelTable::UnitIndexAndEncoding> EntryRet =
563542 getIndexForEntry (Entry);
564543 std::optional<OffsetAndUnitID> MaybeParentOffset =
565544 Entry.getParentDieOffsetAndUnitID ();
566- std::optional<dwarf::Form> MaybeParentForm =
567- getFormForIdxParent (IndexedOffsets, MaybeParentOffset);
568- uint32_t AbbrvTag =
569- constructAbbreviationTag (Entry.getDieTag (), EntryRet, MaybeParentForm);
570- auto AbbrevIt = Abbreviations.find (AbbrvTag);
571- assert (AbbrevIt != Abbreviations.end () &&
572- " Why wasn't this abbrev generated?" );
573- assert (getTagFromAbbreviationTag (AbbrevIt->first ) == Entry.getDieTag () &&
574- " Invalid Tag" );
575-
576545 auto EntrySymbolIt =
577546 DIEOffsetToAccelEntryLabel.find (Entry.getDieOffsetAndUnitID ());
578547 assert (EntrySymbolIt != DIEOffsetToAccelEntryLabel.end ());
@@ -584,9 +553,10 @@ void Dwarf5AccelTableWriter::emitEntry(
584553 if (EmittedAccelEntrySymbols.insert (EntrySymbol).second )
585554 Asm->OutStreamer ->emitLabel (EntrySymbol);
586555
587- Asm->emitULEB128 (AbbrevIt-> first , " Abbreviation code" );
556+ Asm->emitULEB128 (Entry. getAbbrevNumber () , " Abbreviation code" );
588557
589- for (const auto &AttrEnc : AbbrevIt->second ) {
558+ for (const DebugNamesAbbrev::AttributeEncoding &AttrEnc :
559+ Abbrev->getAttributes ()) {
590560 Asm->OutStreamer ->AddComment (dwarf::IndexString (AttrEnc.Index ));
591561 switch (AttrEnc.Index ) {
592562 case dwarf::DW_IDX_compile_unit:
0 commit comments