@@ -208,8 +208,13 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
208
208
};
209
209
210
210
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;
213
218
ArrayRef<std::variant<MCSymbol *, uint64_t >> CompUnits;
214
219
ArrayRef<std::variant<MCSymbol *, uint64_t >> TypeUnits;
215
220
llvm::function_ref<std::optional<DWARF5AccelTable::UnitIndexAndEncoding>(
@@ -234,7 +239,7 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
234
239
void emitEntry (
235
240
const DWARF5AccelTableData &Entry,
236
241
const DenseMap<OffsetAndUnitID, MCSymbol *> &DIEOffsetToAccelEntryLabel,
237
- DenseSet<MCSymbol *> &EmittedAccelEntrySymbols) const ;
242
+ DenseSet<MCSymbol *> &EmittedAccelEntrySymbols);
238
243
void emitData ();
239
244
240
245
public:
@@ -370,7 +375,7 @@ void AppleAccelTableWriter::emit() const {
370
375
DWARF5AccelTableData::DWARF5AccelTableData (const DIE &Die,
371
376
const uint32_t UnitID,
372
377
const bool IsTU)
373
- : OffsetVal(&Die), DieTag(Die.getTag()), UnitID(UnitID ), IsTU(IsTU ) {}
378
+ : OffsetVal(&Die), DieTag(Die.getTag()), IsTU(IsTU ), UnitID(UnitID ) {}
374
379
375
380
void Dwarf5AccelTableWriter::Header::emit (Dwarf5AccelTableWriter &Ctx) {
376
381
assert (CompUnitCount > 0 && " Index must have at least one CU." );
@@ -409,51 +414,6 @@ DWARF5AccelTableData::getDefiningParentDieOffset(const DIE &Die) {
409
414
return {};
410
415
}
411
416
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
-
457
417
static std::optional<dwarf::Form>
458
418
getFormForIdxParent (const DenseSet<OffsetAndUnitID> &IndexedOffsets,
459
419
std::optional<OffsetAndUnitID> ParentOffset) {
@@ -467,26 +427,42 @@ getFormForIdxParent(const DenseSet<OffsetAndUnitID> &IndexedOffsets,
467
427
return dwarf::Form::DW_FORM_flag_present;
468
428
}
469
429
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
+
470
438
void Dwarf5AccelTableWriter::populateAbbrevsMap () {
471
439
for (auto &Bucket : Contents.getBuckets ()) {
472
440
for (auto *Hash : Bucket) {
473
441
for (auto *Value : Hash->getValues <DWARF5AccelTableData *>()) {
474
442
std::optional<DWARF5AccelTable::UnitIndexAndEncoding> EntryRet =
475
443
getIndexForEntry (*Value);
476
- unsigned Tag = Value->getDieTag ();
477
444
std::optional<dwarf::Form> MaybeParentForm = getFormForIdxParent (
478
445
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 ;
489
459
}
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 ());
490
466
}
491
467
}
492
468
}
@@ -536,14 +512,13 @@ void Dwarf5AccelTableWriter::emitStringOffsets() const {
536
512
537
513
void Dwarf5AccelTableWriter::emitAbbrevs () const {
538
514
Asm->OutStreamer ->emitLabel (AbbrevStart);
539
- for (const auto & Abbrev : Abbreviations ) {
515
+ for (const DebugNamesAbbrev * Abbrev : AbbreviationsVector ) {
540
516
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 ()) {
547
522
Asm->emitULEB128 (AttrEnc.Index , dwarf::IndexString (AttrEnc.Index ).data ());
548
523
Asm->emitULEB128 (AttrEnc.Form ,
549
524
dwarf::FormEncodingString (AttrEnc.Form ).data ());
@@ -558,21 +533,15 @@ void Dwarf5AccelTableWriter::emitAbbrevs() const {
558
533
void Dwarf5AccelTableWriter::emitEntry (
559
534
const DWARF5AccelTableData &Entry,
560
535
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];
562
541
std::optional<DWARF5AccelTable::UnitIndexAndEncoding> EntryRet =
563
542
getIndexForEntry (Entry);
564
543
std::optional<OffsetAndUnitID> MaybeParentOffset =
565
544
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
-
576
545
auto EntrySymbolIt =
577
546
DIEOffsetToAccelEntryLabel.find (Entry.getDieOffsetAndUnitID ());
578
547
assert (EntrySymbolIt != DIEOffsetToAccelEntryLabel.end ());
@@ -584,9 +553,10 @@ void Dwarf5AccelTableWriter::emitEntry(
584
553
if (EmittedAccelEntrySymbols.insert (EntrySymbol).second )
585
554
Asm->OutStreamer ->emitLabel (EntrySymbol);
586
555
587
- Asm->emitULEB128 (AbbrevIt-> first , " Abbreviation code" );
556
+ Asm->emitULEB128 (Entry. getAbbrevNumber () , " Abbreviation code" );
588
557
589
- for (const auto &AttrEnc : AbbrevIt->second ) {
558
+ for (const DebugNamesAbbrev::AttributeEncoding &AttrEnc :
559
+ Abbrev->getAttributes ()) {
590
560
Asm->OutStreamer ->AddComment (dwarf::IndexString (AttrEnc.Index ));
591
561
switch (AttrEnc.Index ) {
592
562
case dwarf::DW_IDX_compile_unit:
0 commit comments