21
21
#include " llvm/CodeGen/DIE.h"
22
22
#include " llvm/MC/MCExpr.h"
23
23
#include " llvm/MC/MCStreamer.h"
24
+ #include " llvm/MC/MCSymbol.h"
24
25
#include " llvm/Support/raw_ostream.h"
25
26
#include < algorithm>
26
27
#include < cstddef>
@@ -180,8 +181,14 @@ class AppleAccelTableWriter : public AccelTableWriter {
180
181
#endif
181
182
};
182
183
183
- // / Class responsible for emitting a DWARF v5 Accelerator Table. The only public
184
- // / function is emit(), which performs the actual emission.
184
+ // / Class responsible for emitting a DWARF v5 Accelerator Table. The only
185
+ // / public function is emit(), which performs the actual emission.
186
+ // /
187
+ // / The class is templated in its data type. This allows us to emit both dyamic
188
+ // / and static data entries. A callback abstract the logic to provide a CU
189
+ // / index for a given entry, which is different per data type, but identical
190
+ // / for every entry in the same table.
191
+ template <typename DataT>
185
192
class Dwarf5AccelTableWriter : public AccelTableWriter {
186
193
struct Header {
187
194
uint32_t UnitLength = 0 ;
@@ -209,8 +216,8 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
209
216
210
217
Header Header;
211
218
DenseMap<uint32_t , SmallVector<AttributeEncoding, 2 >> Abbreviations;
212
- const DwarfDebug &DD ;
213
- ArrayRef<std::unique_ptr<DwarfCompileUnit>> CompUnits ;
219
+ ArrayRef<MCSymbol *> CompUnits ;
220
+ llvm::function_ref< unsigned ( const DataT &)> getCUIndexForEntry ;
214
221
MCSymbol *ContributionStart = Asm->createTempSymbol (" names_start" );
215
222
MCSymbol *ContributionEnd = Asm->createTempSymbol (" names_end" );
216
223
MCSymbol *AbbrevStart = Asm->createTempSymbol (" names_abbrev_start" );
@@ -226,13 +233,14 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
226
233
void emitBuckets () const ;
227
234
void emitStringOffsets () const ;
228
235
void emitAbbrevs () const ;
229
- void emitEntry (const DWARF5AccelTableData &Data) const ;
236
+ void emitEntry (const DataT &Data) const ;
230
237
void emitData () const ;
231
238
232
239
public:
233
- Dwarf5AccelTableWriter (AsmPrinter *Asm, const AccelTableBase &Contents,
234
- const DwarfDebug &DD,
235
- ArrayRef<std::unique_ptr<DwarfCompileUnit>> CompUnits);
240
+ Dwarf5AccelTableWriter (
241
+ AsmPrinter *Asm, const AccelTableBase &Contents,
242
+ ArrayRef<MCSymbol *> CompUnits,
243
+ llvm::function_ref<unsigned (const DataT &)> GetCUIndexForEntry);
236
244
237
245
void emit () const ;
238
246
};
@@ -354,7 +362,8 @@ void AppleAccelTableWriter::emit() const {
354
362
emitData ();
355
363
}
356
364
357
- void Dwarf5AccelTableWriter::Header::emit (
365
+ template <typename DataT>
366
+ void Dwarf5AccelTableWriter<DataT>::Header::emit(
358
367
const Dwarf5AccelTableWriter &Ctx) const {
359
368
assert (CompUnitCount > 0 && " Index must have at least one CU." );
360
369
@@ -386,22 +395,23 @@ void Dwarf5AccelTableWriter::Header::emit(
386
395
Asm->OutStreamer ->EmitBytes ({AugmentationString, AugmentationStringSize});
387
396
}
388
397
389
- DenseSet<uint32_t > Dwarf5AccelTableWriter::getUniqueTags () const {
398
+ template <typename DataT>
399
+ DenseSet<uint32_t > Dwarf5AccelTableWriter<DataT>::getUniqueTags() const {
390
400
DenseSet<uint32_t > UniqueTags;
391
401
for (auto &Bucket : Contents.getBuckets ()) {
392
402
for (auto *Hash : Bucket) {
393
403
for (auto *Value : Hash->Values ) {
394
- const DIE &Die =
395
- static_cast <const DWARF5AccelTableData *>(Value)->getDie ();
396
- UniqueTags.insert (Die.getTag ());
404
+ unsigned Tag = static_cast <const DataT *>(Value)->getDieTag ();
405
+ UniqueTags.insert (Tag);
397
406
}
398
407
}
399
408
}
400
409
return UniqueTags;
401
410
}
402
411
403
- SmallVector<Dwarf5AccelTableWriter::AttributeEncoding, 2 >
404
- Dwarf5AccelTableWriter::getUniformAttributes () const {
412
+ template <typename DataT>
413
+ SmallVector<typename Dwarf5AccelTableWriter<DataT>::AttributeEncoding, 2 >
414
+ Dwarf5AccelTableWriter<DataT>::getUniformAttributes() const {
405
415
SmallVector<AttributeEncoding, 2 > UA;
406
416
if (CompUnits.size () > 1 ) {
407
417
size_t LargestCUIndex = CompUnits.size () - 1 ;
@@ -412,17 +422,16 @@ Dwarf5AccelTableWriter::getUniformAttributes() const {
412
422
return UA;
413
423
}
414
424
415
- void Dwarf5AccelTableWriter::emitCUList () const {
425
+ template <typename DataT>
426
+ void Dwarf5AccelTableWriter<DataT>::emitCUList() const {
416
427
for (const auto &CU : enumerate(CompUnits)) {
417
- assert (CU.index () == CU.value ()->getUniqueID ());
418
428
Asm->OutStreamer ->AddComment (" Compilation unit " + Twine (CU.index ()));
419
- const DwarfCompileUnit *MainCU =
420
- DD.useSplitDwarf () ? CU.value ()->getSkeleton () : CU.value ().get ();
421
- Asm->emitDwarfSymbolReference (MainCU->getLabelBegin ());
429
+ Asm->emitDwarfSymbolReference (CU.value ());
422
430
}
423
431
}
424
432
425
- void Dwarf5AccelTableWriter::emitBuckets () const {
433
+ template <typename DataT>
434
+ void Dwarf5AccelTableWriter<DataT>::emitBuckets() const {
426
435
uint32_t Index = 1 ;
427
436
for (const auto &Bucket : enumerate(Contents.getBuckets ())) {
428
437
Asm->OutStreamer ->AddComment (" Bucket " + Twine (Bucket.index ()));
@@ -431,7 +440,8 @@ void Dwarf5AccelTableWriter::emitBuckets() const {
431
440
}
432
441
}
433
442
434
- void Dwarf5AccelTableWriter::emitStringOffsets () const {
443
+ template <typename DataT>
444
+ void Dwarf5AccelTableWriter<DataT>::emitStringOffsets() const {
435
445
for (const auto &Bucket : enumerate(Contents.getBuckets ())) {
436
446
for (auto *Hash : Bucket.value ()) {
437
447
DwarfStringPoolEntryRef String = Hash->Name ;
@@ -442,7 +452,8 @@ void Dwarf5AccelTableWriter::emitStringOffsets() const {
442
452
}
443
453
}
444
454
445
- void Dwarf5AccelTableWriter::emitAbbrevs () const {
455
+ template <typename DataT>
456
+ void Dwarf5AccelTableWriter<DataT>::emitAbbrevs() const {
446
457
Asm->OutStreamer ->EmitLabel (AbbrevStart);
447
458
for (const auto &Abbrev : Abbreviations) {
448
459
Asm->OutStreamer ->AddComment (" Abbrev code" );
@@ -462,9 +473,9 @@ void Dwarf5AccelTableWriter::emitAbbrevs() const {
462
473
Asm->OutStreamer ->EmitLabel (AbbrevEnd);
463
474
}
464
475
465
- void Dwarf5AccelTableWriter::emitEntry (
466
- const DWARF5AccelTableData &Entry) const {
467
- auto AbbrevIt = Abbreviations.find (Entry.getDie (). getTag ());
476
+ template < typename DataT>
477
+ void Dwarf5AccelTableWriter<DataT>::emitEntry( const DataT &Entry) const {
478
+ auto AbbrevIt = Abbreviations.find (Entry.getDieTag ());
468
479
assert (AbbrevIt != Abbreviations.end () &&
469
480
" Why wasn't this abbrev generated?" );
470
481
@@ -473,42 +484,43 @@ void Dwarf5AccelTableWriter::emitEntry(
473
484
Asm->OutStreamer ->AddComment (dwarf::IndexString (AttrEnc.Index ));
474
485
switch (AttrEnc.Index ) {
475
486
case dwarf::DW_IDX_compile_unit: {
476
- const DIE *CUDie = Entry.getDie ().getUnitDie ();
477
- DIEInteger ID (DD.lookupCU (CUDie)->getUniqueID ());
487
+ DIEInteger ID (getCUIndexForEntry (Entry));
478
488
ID.EmitValue (Asm, AttrEnc.Form );
479
489
break ;
480
490
}
481
491
case dwarf::DW_IDX_die_offset:
482
492
assert (AttrEnc.Form == dwarf::DW_FORM_ref4);
483
- Asm->emitInt32 (Entry.getDie (). getOffset ());
493
+ Asm->emitInt32 (Entry.getDieOffset ());
484
494
break ;
485
495
default :
486
496
llvm_unreachable (" Unexpected index attribute!" );
487
497
}
488
498
}
489
499
}
490
500
491
- void Dwarf5AccelTableWriter::emitData () const {
501
+ template < typename DataT> void Dwarf5AccelTableWriter<DataT> ::emitData() const {
492
502
Asm->OutStreamer ->EmitLabel (EntryPool);
493
503
for (auto &Bucket : Contents.getBuckets ()) {
494
504
for (auto *Hash : Bucket) {
495
505
// Remember to emit the label for our offset.
496
506
Asm->OutStreamer ->EmitLabel (Hash->Sym );
497
507
for (const auto *Value : Hash->Values )
498
- emitEntry (*static_cast <const DWARF5AccelTableData *>(Value));
508
+ emitEntry (*static_cast <const DataT *>(Value));
499
509
Asm->OutStreamer ->AddComment (" End of list: " + Hash->Name .getString ());
500
510
Asm->emitInt32 (0 );
501
511
}
502
512
}
503
513
}
504
514
505
- Dwarf5AccelTableWriter::Dwarf5AccelTableWriter (
506
- AsmPrinter *Asm, const AccelTableBase &Contents, const DwarfDebug &DD,
507
- ArrayRef<std::unique_ptr<DwarfCompileUnit>> CompUnits)
515
+ template <typename DataT>
516
+ Dwarf5AccelTableWriter<DataT>::Dwarf5AccelTableWriter(
517
+ AsmPrinter *Asm, const AccelTableBase &Contents,
518
+ ArrayRef<MCSymbol *> CompUnits,
519
+ llvm::function_ref<unsigned (const DataT &)> getCUIndexForEntry)
508
520
: AccelTableWriter(Asm, Contents, false ),
509
521
Header (CompUnits.size(), Contents.getBucketCount(),
510
522
Contents.getUniqueNameCount()),
511
- DD(DD ), CompUnits(CompUnits ) {
523
+ CompUnits(CompUnits ), getCUIndexForEntry(std::move(getCUIndexForEntry) ) {
512
524
DenseSet<uint32_t > UniqueTags = getUniqueTags ();
513
525
SmallVector<AttributeEncoding, 2 > UniformAttributes = getUniformAttributes ();
514
526
@@ -517,7 +529,7 @@ Dwarf5AccelTableWriter::Dwarf5AccelTableWriter(
517
529
Abbreviations.try_emplace (Tag, UniformAttributes);
518
530
}
519
531
520
- void Dwarf5AccelTableWriter::emit () const {
532
+ template < typename DataT> void Dwarf5AccelTableWriter<DataT> ::emit() const {
521
533
Header.emit (*this );
522
534
emitCUList ();
523
535
emitBuckets ();
@@ -540,8 +552,33 @@ void llvm::emitAppleAccelTableImpl(AsmPrinter *Asm, AccelTableBase &Contents,
540
552
void llvm::emitDWARF5AccelTable (
541
553
AsmPrinter *Asm, AccelTable<DWARF5AccelTableData> &Contents,
542
554
const DwarfDebug &DD, ArrayRef<std::unique_ptr<DwarfCompileUnit>> CUs) {
555
+ std::vector<MCSymbol *> CompUnits;
556
+ for (const auto &CU : enumerate(CUs)) {
557
+ assert (CU.index () == CU.value ()->getUniqueID ());
558
+ const DwarfCompileUnit *MainCU =
559
+ DD.useSplitDwarf () ? CU.value ()->getSkeleton () : CU.value ().get ();
560
+ CompUnits.push_back (MainCU->getLabelBegin ());
561
+ }
562
+
543
563
Contents.finalize (Asm, " names" );
544
- Dwarf5AccelTableWriter (Asm, Contents, DD, CUs).emit ();
564
+ Dwarf5AccelTableWriter<DWARF5AccelTableData>(
565
+ Asm, Contents, CompUnits,
566
+ [&DD](const DWARF5AccelTableData &Entry) {
567
+ const DIE *CUDie = Entry.getDie ().getUnitDie ();
568
+ return DD.lookupCU (CUDie)->getUniqueID ();
569
+ })
570
+ .emit ();
571
+ }
572
+
573
+ void llvm::emitDWARF5AccelTable (
574
+ AsmPrinter *Asm, AccelTable<DWARF5AccelTableStaticData> &Contents,
575
+ ArrayRef<MCSymbol *> CUs,
576
+ llvm::function_ref<unsigned (const DWARF5AccelTableStaticData &)>
577
+ getCUIndexForEntry) {
578
+ Contents.finalize (Asm, " names" );
579
+ Dwarf5AccelTableWriter<DWARF5AccelTableStaticData>(Asm, Contents, CUs,
580
+ getCUIndexForEntry)
581
+ .emit ();
545
582
}
546
583
547
584
void AppleAccelTableOffsetData::emit (AsmPrinter *Asm) const {
@@ -651,8 +688,13 @@ void AccelTableBase::print(raw_ostream &OS) const {
651
688
}
652
689
653
690
void DWARF5AccelTableData::print (raw_ostream &OS) const {
654
- OS << " Offset: " << Die.getOffset () << " \n " ;
655
- OS << " Tag: " << dwarf::TagString (Die.getTag ()) << " \n " ;
691
+ OS << " Offset: " << getDieOffset () << " \n " ;
692
+ OS << " Tag: " << dwarf::TagString (getDieTag ()) << " \n " ;
693
+ }
694
+
695
+ void DWARF5AccelTableStaticData::print (raw_ostream &OS) const {
696
+ OS << " Offset: " << getDieOffset () << " \n " ;
697
+ OS << " Tag: " << dwarf::TagString (getDieTag ()) << " \n " ;
656
698
}
657
699
658
700
void AppleAccelTableOffsetData::print (raw_ostream &OS) const {
0 commit comments