Skip to content

Commit 98062cb

Browse files
committed
[AccelTable] Provide DWARF5AccelTableStaticData for dsymutil.
For dsymutil we want to store offsets in the accelerator table entries rather than DIE pointers. In addition, we need a way to communicate which CU a DIE belongs to. This patch provides support for both of these issues. Differential revision: https://reviews.llvm.org/D49102 llvm-svn: 337158
1 parent 3620b99 commit 98062cb

File tree

2 files changed

+115
-41
lines changed

2 files changed

+115
-41
lines changed

llvm/include/llvm/CodeGen/AccelTable.h

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ class AccelTableData {
122122
return order() < Other.order();
123123
}
124124

125-
// Subclasses should implement:
126-
// static uint32_t hash(StringRef Name);
125+
// Subclasses should implement:
126+
// static uint32_t hash(StringRef Name);
127127

128128
#ifndef NDEBUG
129129
virtual void print(raw_ostream &OS) const = 0;
@@ -261,13 +261,39 @@ class DWARF5AccelTableData : public AccelTableData {
261261
#endif
262262

263263
const DIE &getDie() const { return Die; }
264+
uint64_t getDieOffset() const { return Die.getOffset(); }
265+
unsigned getDieTag() const { return Die.getTag(); }
264266

265267
protected:
266268
const DIE &Die;
267269

268270
uint64_t order() const override { return Die.getOffset(); }
269271
};
270272

273+
class DWARF5AccelTableStaticData : public AccelTableData {
274+
public:
275+
static uint32_t hash(StringRef Name) { return caseFoldingDjbHash(Name); }
276+
277+
DWARF5AccelTableStaticData(uint64_t DieOffset, unsigned DieTag,
278+
unsigned CUIndex)
279+
: DieOffset(DieOffset), DieTag(DieTag), CUIndex(CUIndex) {}
280+
281+
#ifndef NDEBUG
282+
void print(raw_ostream &OS) const override;
283+
#endif
284+
285+
uint64_t getDieOffset() const { return DieOffset; }
286+
unsigned getDieTag() const { return DieTag; }
287+
unsigned getCUIndex() const { return CUIndex; }
288+
289+
protected:
290+
uint64_t DieOffset;
291+
unsigned DieTag;
292+
unsigned CUIndex;
293+
294+
uint64_t order() const override { return DieOffset; }
295+
};
296+
271297
void emitAppleAccelTableImpl(AsmPrinter *Asm, AccelTableBase &Contents,
272298
StringRef Prefix, const MCSymbol *SecBegin,
273299
ArrayRef<AppleAccelTableData::Atom> Atoms);
@@ -287,6 +313,12 @@ void emitDWARF5AccelTable(AsmPrinter *Asm,
287313
const DwarfDebug &DD,
288314
ArrayRef<std::unique_ptr<DwarfCompileUnit>> CUs);
289315

316+
void emitDWARF5AccelTable(
317+
AsmPrinter *Asm, AccelTable<DWARF5AccelTableStaticData> &Contents,
318+
ArrayRef<MCSymbol *> CUs,
319+
llvm::function_ref<unsigned(const DWARF5AccelTableStaticData &)>
320+
getCUIndexForEntry);
321+
290322
/// Accelerator table data implementation for simple Apple accelerator tables
291323
/// with just a DIE reference.
292324
class AppleAccelTableOffsetData : public AppleAccelTableData {

llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp

Lines changed: 81 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "llvm/CodeGen/DIE.h"
2222
#include "llvm/MC/MCExpr.h"
2323
#include "llvm/MC/MCStreamer.h"
24+
#include "llvm/MC/MCSymbol.h"
2425
#include "llvm/Support/raw_ostream.h"
2526
#include <algorithm>
2627
#include <cstddef>
@@ -180,8 +181,14 @@ class AppleAccelTableWriter : public AccelTableWriter {
180181
#endif
181182
};
182183

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>
185192
class Dwarf5AccelTableWriter : public AccelTableWriter {
186193
struct Header {
187194
uint32_t UnitLength = 0;
@@ -209,8 +216,8 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
209216

210217
Header Header;
211218
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;
214221
MCSymbol *ContributionStart = Asm->createTempSymbol("names_start");
215222
MCSymbol *ContributionEnd = Asm->createTempSymbol("names_end");
216223
MCSymbol *AbbrevStart = Asm->createTempSymbol("names_abbrev_start");
@@ -226,13 +233,14 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
226233
void emitBuckets() const;
227234
void emitStringOffsets() const;
228235
void emitAbbrevs() const;
229-
void emitEntry(const DWARF5AccelTableData &Data) const;
236+
void emitEntry(const DataT &Data) const;
230237
void emitData() const;
231238

232239
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);
236244

237245
void emit() const;
238246
};
@@ -354,7 +362,8 @@ void AppleAccelTableWriter::emit() const {
354362
emitData();
355363
}
356364

357-
void Dwarf5AccelTableWriter::Header::emit(
365+
template <typename DataT>
366+
void Dwarf5AccelTableWriter<DataT>::Header::emit(
358367
const Dwarf5AccelTableWriter &Ctx) const {
359368
assert(CompUnitCount > 0 && "Index must have at least one CU.");
360369

@@ -386,22 +395,23 @@ void Dwarf5AccelTableWriter::Header::emit(
386395
Asm->OutStreamer->EmitBytes({AugmentationString, AugmentationStringSize});
387396
}
388397

389-
DenseSet<uint32_t> Dwarf5AccelTableWriter::getUniqueTags() const {
398+
template <typename DataT>
399+
DenseSet<uint32_t> Dwarf5AccelTableWriter<DataT>::getUniqueTags() const {
390400
DenseSet<uint32_t> UniqueTags;
391401
for (auto &Bucket : Contents.getBuckets()) {
392402
for (auto *Hash : Bucket) {
393403
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);
397406
}
398407
}
399408
}
400409
return UniqueTags;
401410
}
402411

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 {
405415
SmallVector<AttributeEncoding, 2> UA;
406416
if (CompUnits.size() > 1) {
407417
size_t LargestCUIndex = CompUnits.size() - 1;
@@ -412,17 +422,16 @@ Dwarf5AccelTableWriter::getUniformAttributes() const {
412422
return UA;
413423
}
414424

415-
void Dwarf5AccelTableWriter::emitCUList() const {
425+
template <typename DataT>
426+
void Dwarf5AccelTableWriter<DataT>::emitCUList() const {
416427
for (const auto &CU : enumerate(CompUnits)) {
417-
assert(CU.index() == CU.value()->getUniqueID());
418428
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());
422430
}
423431
}
424432

425-
void Dwarf5AccelTableWriter::emitBuckets() const {
433+
template <typename DataT>
434+
void Dwarf5AccelTableWriter<DataT>::emitBuckets() const {
426435
uint32_t Index = 1;
427436
for (const auto &Bucket : enumerate(Contents.getBuckets())) {
428437
Asm->OutStreamer->AddComment("Bucket " + Twine(Bucket.index()));
@@ -431,7 +440,8 @@ void Dwarf5AccelTableWriter::emitBuckets() const {
431440
}
432441
}
433442

434-
void Dwarf5AccelTableWriter::emitStringOffsets() const {
443+
template <typename DataT>
444+
void Dwarf5AccelTableWriter<DataT>::emitStringOffsets() const {
435445
for (const auto &Bucket : enumerate(Contents.getBuckets())) {
436446
for (auto *Hash : Bucket.value()) {
437447
DwarfStringPoolEntryRef String = Hash->Name;
@@ -442,7 +452,8 @@ void Dwarf5AccelTableWriter::emitStringOffsets() const {
442452
}
443453
}
444454

445-
void Dwarf5AccelTableWriter::emitAbbrevs() const {
455+
template <typename DataT>
456+
void Dwarf5AccelTableWriter<DataT>::emitAbbrevs() const {
446457
Asm->OutStreamer->EmitLabel(AbbrevStart);
447458
for (const auto &Abbrev : Abbreviations) {
448459
Asm->OutStreamer->AddComment("Abbrev code");
@@ -462,9 +473,9 @@ void Dwarf5AccelTableWriter::emitAbbrevs() const {
462473
Asm->OutStreamer->EmitLabel(AbbrevEnd);
463474
}
464475

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());
468479
assert(AbbrevIt != Abbreviations.end() &&
469480
"Why wasn't this abbrev generated?");
470481

@@ -473,42 +484,43 @@ void Dwarf5AccelTableWriter::emitEntry(
473484
Asm->OutStreamer->AddComment(dwarf::IndexString(AttrEnc.Index));
474485
switch (AttrEnc.Index) {
475486
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));
478488
ID.EmitValue(Asm, AttrEnc.Form);
479489
break;
480490
}
481491
case dwarf::DW_IDX_die_offset:
482492
assert(AttrEnc.Form == dwarf::DW_FORM_ref4);
483-
Asm->emitInt32(Entry.getDie().getOffset());
493+
Asm->emitInt32(Entry.getDieOffset());
484494
break;
485495
default:
486496
llvm_unreachable("Unexpected index attribute!");
487497
}
488498
}
489499
}
490500

491-
void Dwarf5AccelTableWriter::emitData() const {
501+
template <typename DataT> void Dwarf5AccelTableWriter<DataT>::emitData() const {
492502
Asm->OutStreamer->EmitLabel(EntryPool);
493503
for (auto &Bucket : Contents.getBuckets()) {
494504
for (auto *Hash : Bucket) {
495505
// Remember to emit the label for our offset.
496506
Asm->OutStreamer->EmitLabel(Hash->Sym);
497507
for (const auto *Value : Hash->Values)
498-
emitEntry(*static_cast<const DWARF5AccelTableData *>(Value));
508+
emitEntry(*static_cast<const DataT *>(Value));
499509
Asm->OutStreamer->AddComment("End of list: " + Hash->Name.getString());
500510
Asm->emitInt32(0);
501511
}
502512
}
503513
}
504514

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)
508520
: AccelTableWriter(Asm, Contents, false),
509521
Header(CompUnits.size(), Contents.getBucketCount(),
510522
Contents.getUniqueNameCount()),
511-
DD(DD), CompUnits(CompUnits) {
523+
CompUnits(CompUnits), getCUIndexForEntry(std::move(getCUIndexForEntry)) {
512524
DenseSet<uint32_t> UniqueTags = getUniqueTags();
513525
SmallVector<AttributeEncoding, 2> UniformAttributes = getUniformAttributes();
514526

@@ -517,7 +529,7 @@ Dwarf5AccelTableWriter::Dwarf5AccelTableWriter(
517529
Abbreviations.try_emplace(Tag, UniformAttributes);
518530
}
519531

520-
void Dwarf5AccelTableWriter::emit() const {
532+
template <typename DataT> void Dwarf5AccelTableWriter<DataT>::emit() const {
521533
Header.emit(*this);
522534
emitCUList();
523535
emitBuckets();
@@ -540,8 +552,33 @@ void llvm::emitAppleAccelTableImpl(AsmPrinter *Asm, AccelTableBase &Contents,
540552
void llvm::emitDWARF5AccelTable(
541553
AsmPrinter *Asm, AccelTable<DWARF5AccelTableData> &Contents,
542554
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+
543563
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();
545582
}
546583

547584
void AppleAccelTableOffsetData::emit(AsmPrinter *Asm) const {
@@ -651,8 +688,13 @@ void AccelTableBase::print(raw_ostream &OS) const {
651688
}
652689

653690
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";
656698
}
657699

658700
void AppleAccelTableOffsetData::print(raw_ostream &OS) const {

0 commit comments

Comments
 (0)