13
13
#include " llvm/CodeGen/AccelTable.h"
14
14
#include " DwarfCompileUnit.h"
15
15
#include " llvm/ADT/STLExtras.h"
16
- #include " llvm/ADT/StringMap.h"
17
16
#include " llvm/ADT/Twine.h"
18
17
#include " llvm/BinaryFormat/Dwarf.h"
19
18
#include " llvm/CodeGen/AsmPrinter.h"
@@ -200,32 +199,30 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
200
199
uint32_t AugmentationStringSize = sizeof (AugmentationString);
201
200
char AugmentationString[8 ] = {' L' , ' L' , ' V' , ' M' , ' 0' , ' 7' , ' 0' , ' 0' };
202
201
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) {}
206
206
207
207
void emit (Dwarf5AccelTableWriter &Ctx);
208
208
};
209
- struct AttributeEncoding {
210
- dwarf::Index Index;
211
- dwarf::Form Form;
212
- };
213
209
214
210
Header Header;
215
- DenseMap<uint32_t , SmallVector<AttributeEncoding, 2 >> Abbreviations;
211
+ DenseMap<uint32_t , SmallVector<DWARF5AccelTableData::AttributeEncoding, 2 >>
212
+ Abbreviations;
216
213
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;
218
217
MCSymbol *ContributionEnd = nullptr ;
219
218
MCSymbol *AbbrevStart = Asm->createTempSymbol (" names_abbrev_start" );
220
219
MCSymbol *AbbrevEnd = Asm->createTempSymbol (" names_abbrev_end" );
221
220
MCSymbol *EntryPool = Asm->createTempSymbol (" names_entries" );
222
221
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 ();
227
223
228
224
void emitCUList () const ;
225
+ void emitTUList () const ;
229
226
void emitBuckets () const ;
230
227
void emitStringOffsets () const ;
231
228
void emitAbbrevs () const ;
@@ -236,7 +233,9 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
236
233
Dwarf5AccelTableWriter (
237
234
AsmPrinter *Asm, const AccelTableBase &Contents,
238
235
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);
240
239
241
240
void emit ();
242
241
};
@@ -388,31 +387,39 @@ void Dwarf5AccelTableWriter<DataT>::Header::emit(Dwarf5AccelTableWriter &Ctx) {
388
387
Asm->OutStreamer ->emitBytes ({AugmentationString, AugmentationStringSize});
389
388
}
390
389
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
+ }
391
404
template <typename DataT>
392
- DenseSet<uint32_t > Dwarf5AccelTableWriter<DataT>::getUniqueTags() const {
393
- DenseSet<uint32_t > UniqueTags;
405
+ void Dwarf5AccelTableWriter<DataT>::populateAbbrevsMap() {
394
406
for (auto &Bucket : Contents.getBuckets ()) {
395
407
for (auto *Hash : Bucket) {
396
408
for (auto *Value : Hash->Values ) {
409
+ GetIndexForEntryReturnType EntryRet =
410
+ getIndexForEntry (*static_cast <const DataT *>(Value));
397
411
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
+ }
399
420
}
400
421
}
401
422
}
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;
416
423
}
417
424
418
425
template <typename DataT>
@@ -426,6 +433,17 @@ void Dwarf5AccelTableWriter<DataT>::emitCUList() const {
426
433
}
427
434
}
428
435
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
+
429
447
template <typename DataT>
430
448
void Dwarf5AccelTableWriter<DataT>::emitBuckets() const {
431
449
uint32_t Index = 1 ;
@@ -453,10 +471,11 @@ void Dwarf5AccelTableWriter<DataT>::emitAbbrevs() const {
453
471
Asm->OutStreamer ->emitLabel (AbbrevStart);
454
472
for (const auto &Abbrev : Abbreviations) {
455
473
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 );
459
476
Asm->emitULEB128 (Abbrev.first );
477
+ Asm->OutStreamer ->AddComment (dwarf::TagString (Tag));
478
+ Asm->emitULEB128 (Tag);
460
479
for (const auto &AttrEnc : Abbrev.second ) {
461
480
Asm->emitULEB128 (AttrEnc.Index , dwarf::IndexString (AttrEnc.Index ).data ());
462
481
Asm->emitULEB128 (AttrEnc.Form ,
@@ -471,16 +490,21 @@ void Dwarf5AccelTableWriter<DataT>::emitAbbrevs() const {
471
490
472
491
template <typename DataT>
473
492
void 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);
475
496
assert (AbbrevIt != Abbreviations.end () &&
476
497
" Why wasn't this abbrev generated?" );
477
-
498
+ assert (getTagFromAbbreviationTag (AbbrevIt->first ) == Entry.getDieTag () &&
499
+ " Invalid Tag" );
478
500
Asm->emitULEB128 (AbbrevIt->first , " Abbreviation code" );
501
+
479
502
for (const auto &AttrEnc : AbbrevIt->second ) {
480
503
Asm->OutStreamer ->AddComment (dwarf::IndexString (AttrEnc.Index ));
481
504
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 );
484
508
ID.emitValue (Asm, AttrEnc.Form );
485
509
break ;
486
510
}
@@ -512,22 +536,21 @@ template <typename DataT>
512
536
Dwarf5AccelTableWriter<DataT>::Dwarf5AccelTableWriter(
513
537
AsmPrinter *Asm, const AccelTableBase &Contents,
514
538
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)
516
542
: AccelTableWriter(Asm, Contents, false ),
517
- Header (CompUnits.size(), Contents.getBucketCount(),
543
+ Header (CompUnits.size(), TypeUnits.size(), Contents.getBucketCount(),
518
544
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 ();
526
548
}
527
549
528
550
template <typename DataT> void Dwarf5AccelTableWriter<DataT>::emit() {
529
551
Header.emit (*this );
530
552
emitCUList ();
553
+ emitTUList ();
531
554
emitBuckets ();
532
555
emitHashes ();
533
556
emitStringOffsets ();
@@ -545,12 +568,17 @@ void llvm::emitAppleAccelTableImpl(AsmPrinter *Asm, AccelTableBase &Contents,
545
568
AppleAccelTableWriter (Asm, Contents, Atoms, SecBegin).emit ();
546
569
}
547
570
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) {
551
576
std::vector<std::variant<MCSymbol *, uint64_t >> CompUnits;
577
+ std::vector<std::variant<MCSymbol *, uint64_t >> TypeUnits;
552
578
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 ;
554
582
for (const auto &CU : enumerate(CUs)) {
555
583
switch (CU.value ()->getCUNode ()->getNameTableKind ()) {
556
584
case DICompileUnit::DebugNameTableKind::Default:
@@ -559,37 +587,61 @@ void llvm::emitDWARF5AccelTable(
559
587
default :
560
588
continue ;
561
589
}
562
- CUIndex[CU.index ()] = Count ++;
590
+ CUIndex[CU.index ()] = CUCount ++;
563
591
assert (CU.index () == CU.value ()->getUniqueID ());
564
592
const DwarfCompileUnit *MainCU =
565
593
DD.useSplitDwarf () ? CU.value ()->getSkeleton () : CU.value ().get ();
566
594
CompUnits.push_back (MainCU->getLabelBegin ());
567
595
}
568
596
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
+
569
609
if (CompUnits.empty ())
570
610
return ;
571
611
572
612
Asm->OutStreamer ->switchSection (
573
613
Asm->getObjFileLowering ().getDwarfDebugNamesSection ());
574
614
575
615
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 );
576
620
Dwarf5AccelTableWriter<DWARF5AccelTableData>(
577
- Asm, Contents, CompUnits,
578
- [&](const DWARF5AccelTableData &Entry) {
621
+ Asm, Contents, CompUnits, TypeUnits,
622
+ [&](const DWARF5AccelTableData &Entry) -> GetIndexForEntryReturnType {
579
623
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;
581
631
})
582
632
.emit ();
583
633
}
584
634
585
635
void llvm::emitDWARF5AccelTable (
586
636
AsmPrinter *Asm, AccelTable<DWARF5AccelTableStaticData> &Contents,
587
637
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;
590
642
Contents.finalize (Asm, " names" );
591
- Dwarf5AccelTableWriter<DWARF5AccelTableStaticData>(Asm, Contents, CUs,
592
- getCUIndexForEntry )
643
+ Dwarf5AccelTableWriter<DWARF5AccelTableStaticData>(
644
+ Asm, Contents, CUs, TypeUnits, getIndexForEntry )
593
645
.emit ();
594
646
}
595
647
0 commit comments