Skip to content

Commit f8b29b1

Browse files
committed
[LLVM][DWARF] Change .debug_names abbrev to be an index
Based on the discussion in llvm#80229 changed implementation to align with how .debug_abbrev is handled. So that .debug_names abbrev tag is a monotonically increasing index. This allows for tools like LLDB to access it in constant time.
1 parent 78b9dd6 commit f8b29b1

File tree

4 files changed

+115
-84
lines changed

4 files changed

+115
-84
lines changed

llvm/include/llvm/CodeGen/AccelTable.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,49 @@ class DWARF5AccelTable : public AccelTable<DWARF5AccelTableData> {
360360
unsigned Index;
361361
DWARF5AccelTableData::AttributeEncoding Encoding;
362362
};
363+
union AbbrevDescriptor {
364+
struct {
365+
uint32_t CompUnit : 1;
366+
uint32_t TypeUnit : 1;
367+
uint32_t DieOffset : 1;
368+
uint32_t Parent : 2;
369+
uint32_t TypeHash : 1;
370+
uint32_t Tag : 26;
371+
} Bits;
372+
uint32_t Value = 0;
373+
};
374+
struct TagIndex {
375+
uint32_t DieTag;
376+
uint32_t Index;
377+
};
378+
struct cmpByTagIndex {
379+
bool operator()(const TagIndex &LHS, const TagIndex &RHS) const {
380+
return LHS.Index < RHS.Index;
381+
}
382+
};
383+
enum IdxParentEncoding : uint8_t {
384+
NoIndexedParent =
385+
0, /// Parent information present but parent isn't indexed.
386+
Ref4 = 1, /// Parent information present and parent is indexed.
387+
NoParent = 2, /// Parent information missing.
388+
};
389+
390+
/// Returns DW_IDX_parent abbrev encoding for the given form.
391+
static uint8_t
392+
encodeIdxParent(const std::optional<dwarf::Form> MaybeParentForm) {
393+
if (!MaybeParentForm)
394+
return NoParent;
395+
switch (*MaybeParentForm) {
396+
case dwarf::Form::DW_FORM_flag_present:
397+
return NoIndexedParent;
398+
case dwarf::Form::DW_FORM_ref4:
399+
return Ref4;
400+
default:
401+
// This is not crashing on bad input: we should only reach this if the
402+
// internal compiler logic is faulty; see getFormForIdxParent.
403+
llvm_unreachable("Bad form for IDX_parent");
404+
}
405+
}
363406
/// Returns type units that were constructed.
364407
const TUVectorTy &getTypeUnitsSymbols() { return TUSymbolsOrHashes; }
365408
/// Add a type unit start symbol.

llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp

Lines changed: 46 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,9 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
208208
};
209209

210210
Header Header;
211-
DenseMap<uint32_t, SmallVector<DWARF5AccelTableData::AttributeEncoding, 3>>
211+
std::map<DWARF5AccelTable::TagIndex,
212+
SmallVector<DWARF5AccelTableData::AttributeEncoding, 3>,
213+
DWARF5AccelTable::cmpByTagIndex>
212214
Abbreviations;
213215
ArrayRef<std::variant<MCSymbol *, uint64_t>> CompUnits;
214216
ArrayRef<std::variant<MCSymbol *, uint64_t>> TypeUnits;
@@ -223,6 +225,15 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
223225
bool IsSplitDwarf = false;
224226
/// Stores the DIE offsets which are indexed by this table.
225227
DenseSet<OffsetAndUnitID> IndexedOffsets;
228+
/// Mapping between AbbrevTag and Index.
229+
std::unordered_map<uint32_t, uint32_t> AbbrevTagToIndexMap;
230+
231+
/// Constructs and returns a unique AbbrevTag that captures what a DIE
232+
/// accesses.
233+
DWARF5AccelTable::TagIndex getAbbrevIndex(
234+
const unsigned DieTag,
235+
const std::optional<DWARF5AccelTable::UnitIndexAndEncoding> &EntryRet,
236+
const std::optional<dwarf::Form> &MaybeParentForm);
226237

227238
void populateAbbrevsMap();
228239

@@ -234,7 +245,7 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
234245
void emitEntry(
235246
const DWARF5AccelTableData &Entry,
236247
const DenseMap<OffsetAndUnitID, MCSymbol *> &DIEOffsetToAccelEntryLabel,
237-
DenseSet<MCSymbol *> &EmittedAccelEntrySymbols) const;
248+
DenseSet<MCSymbol *> &EmittedAccelEntrySymbols);
238249
void emitData();
239250

240251
public:
@@ -409,49 +420,30 @@ DWARF5AccelTableData::getDefiningParentDieOffset(const DIE &Die) {
409420
return {};
410421
}
411422

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,
423+
DWARF5AccelTable::TagIndex Dwarf5AccelTableWriter::getAbbrevIndex(
424+
const unsigned DieTag,
445425
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;
426+
const std::optional<dwarf::Form> &MaybeParentForm) {
427+
DWARF5AccelTable::AbbrevDescriptor AbbrvDesc;
428+
if (EntryRet) {
429+
switch (EntryRet->Encoding.Index) {
430+
case dwarf::DW_IDX_compile_unit:
431+
AbbrvDesc.Bits.CompUnit = true;
432+
break;
433+
case dwarf::DW_IDX_type_unit:
434+
AbbrvDesc.Bits.TypeUnit = true;
435+
break;
436+
default:
437+
llvm_unreachable("Invalid encoding index");
438+
break;
439+
}
440+
}
441+
AbbrvDesc.Bits.Parent = DWARF5AccelTable::encodeIdxParent(MaybeParentForm);
442+
AbbrvDesc.Bits.DieOffset = true;
443+
AbbrvDesc.Bits.Tag = DieTag;
444+
auto Iter = AbbrevTagToIndexMap.insert(
445+
{AbbrvDesc.Value, static_cast<uint32_t>(AbbrevTagToIndexMap.size() + 1)});
446+
return {DieTag, Iter.first->second};
455447
}
456448

457449
static std::optional<dwarf::Form>
@@ -476,8 +468,8 @@ void Dwarf5AccelTableWriter::populateAbbrevsMap() {
476468
unsigned Tag = Value->getDieTag();
477469
std::optional<dwarf::Form> MaybeParentForm = getFormForIdxParent(
478470
IndexedOffsets, Value->getParentDieOffsetAndUnitID());
479-
uint32_t AbbrvTag =
480-
constructAbbreviationTag(Tag, EntryRet, MaybeParentForm);
471+
const DWARF5AccelTable::TagIndex AbbrvTag =
472+
getAbbrevIndex(Tag, EntryRet, MaybeParentForm);
481473
if (Abbreviations.count(AbbrvTag) == 0) {
482474
SmallVector<DWARF5AccelTableData::AttributeEncoding, 3> UA;
483475
if (EntryRet)
@@ -538,11 +530,9 @@ void Dwarf5AccelTableWriter::emitAbbrevs() const {
538530
Asm->OutStreamer->emitLabel(AbbrevStart);
539531
for (const auto &Abbrev : Abbreviations) {
540532
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);
533+
Asm->emitULEB128(Abbrev.first.Index);
534+
Asm->OutStreamer->AddComment(dwarf::TagString(Abbrev.first.DieTag));
535+
Asm->emitULEB128(Abbrev.first.DieTag);
546536
for (const auto &AttrEnc : Abbrev.second) {
547537
Asm->emitULEB128(AttrEnc.Index, dwarf::IndexString(AttrEnc.Index).data());
548538
Asm->emitULEB128(AttrEnc.Form,
@@ -558,20 +548,18 @@ void Dwarf5AccelTableWriter::emitAbbrevs() const {
558548
void Dwarf5AccelTableWriter::emitEntry(
559549
const DWARF5AccelTableData &Entry,
560550
const DenseMap<OffsetAndUnitID, MCSymbol *> &DIEOffsetToAccelEntryLabel,
561-
DenseSet<MCSymbol *> &EmittedAccelEntrySymbols) const {
551+
DenseSet<MCSymbol *> &EmittedAccelEntrySymbols) {
562552
std::optional<DWARF5AccelTable::UnitIndexAndEncoding> EntryRet =
563553
getIndexForEntry(Entry);
564554
std::optional<OffsetAndUnitID> MaybeParentOffset =
565555
Entry.getParentDieOffsetAndUnitID();
566556
std::optional<dwarf::Form> MaybeParentForm =
567557
getFormForIdxParent(IndexedOffsets, MaybeParentOffset);
568-
uint32_t AbbrvTag =
569-
constructAbbreviationTag(Entry.getDieTag(), EntryRet, MaybeParentForm);
570-
auto AbbrevIt = Abbreviations.find(AbbrvTag);
558+
const DWARF5AccelTable::TagIndex TagIndexVal =
559+
getAbbrevIndex(Entry.getDieTag(), EntryRet, MaybeParentForm);
560+
auto AbbrevIt = Abbreviations.find(TagIndexVal);
571561
assert(AbbrevIt != Abbreviations.end() &&
572562
"Why wasn't this abbrev generated?");
573-
assert(getTagFromAbbreviationTag(AbbrevIt->first) == Entry.getDieTag() &&
574-
"Invalid Tag");
575563

576564
auto EntrySymbolIt =
577565
DIEOffsetToAccelEntryLabel.find(Entry.getDieOffsetAndUnitID());
@@ -584,7 +572,7 @@ void Dwarf5AccelTableWriter::emitEntry(
584572
if (EmittedAccelEntrySymbols.insert(EntrySymbol).second)
585573
Asm->OutStreamer->emitLabel(EntrySymbol);
586574

587-
Asm->emitULEB128(AbbrevIt->first, "Abbreviation code");
575+
Asm->emitULEB128(TagIndexVal.Index, "Abbreviation code");
588576

589577
for (const auto &AttrEnc : AbbrevIt->second) {
590578
Asm->OutStreamer->AddComment(dwarf::IndexString(AttrEnc.Index));

llvm/test/DebugInfo/X86/debug-names-dwarf64.ll

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,6 @@
3030
; CHECK-NEXT: CU[0]: 0x00000000
3131
; CHECK-NEXT: ]
3232
; CHECK-NEXT: Abbreviations [
33-
; CHECK-NEXT: Abbreviation [[ABBREV_LABEL:0x[0-9a-f]*]] {
34-
; CHECK-NEXT: Tag: DW_TAG_label
35-
; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
36-
; CHECK-NEXT: DW_IDX_parent: DW_FORM_ref4
37-
; CHECK-NEXT: }
3833
; CHECK-NEXT: Abbreviation [[ABBREV:0x[0-9a-f]*]] {
3934
; CHECK-NEXT: Tag: DW_TAG_base_type
4035
; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
@@ -50,6 +45,11 @@
5045
; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
5146
; CHECK-NEXT: DW_IDX_parent: DW_FORM_flag_present
5247
; CHECK-NEXT: }
48+
; CHECK-NEXT: Abbreviation [[ABBREV_LABEL:0x[0-9a-f]*]] {
49+
; CHECK-NEXT: Tag: DW_TAG_label
50+
; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
51+
; CHECK-NEXT: DW_IDX_parent: DW_FORM_ref4
52+
; CHECK-NEXT: }
5353
; CHECK-NEXT: ]
5454
; CHECK-NEXT: Bucket 0 [
5555
; CHECK-NEXT: Name 1 {

llvm/test/DebugInfo/X86/debug-names-types.ll

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,14 @@
3737
; CHECK-NEXT: LocalTU[0]: 0x00000000
3838
; CHECK-NEXT: ]
3939
; CHECK: Abbreviations [
40-
; CHECK-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] {
41-
; CHECK-NEXT: Tag: DW_TAG_structure_type
42-
; CHECK-NEXT: DW_IDX_type_unit: DW_FORM_data1
43-
; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
44-
; CHECK-NEXT: DW_IDX_parent: DW_FORM_flag_present
45-
; CHECK-NEXT: }
46-
; CHECK-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] {
40+
; CHECK-NEXT: Abbreviation [[ABBREV:0x[0-9a-f]*]] {
4741
; CHECK-NEXT: Tag: DW_TAG_base_type
48-
; CHECK-NEXT: DW_IDX_type_unit: DW_FORM_data1
4942
; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
5043
; CHECK-NEXT: DW_IDX_parent: DW_FORM_flag_present
5144
; CHECK-NEXT: }
52-
; CHECK-NEXT: Abbreviation [[ABBREV:0x[0-9a-f]*]] {
53-
; CHECK-NEXT: Tag: DW_TAG_base_type
45+
; CHECK-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] {
46+
; CHECK-NEXT: Tag: DW_TAG_structure_type
47+
; CHECK-NEXT: DW_IDX_type_unit: DW_FORM_data1
5448
; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
5549
; CHECK-NEXT: DW_IDX_parent: DW_FORM_flag_present
5650
; CHECK-NEXT: }
@@ -64,6 +58,12 @@
6458
; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
6559
; CHECK-NEXT: DW_IDX_parent: DW_FORM_flag_present
6660
; CHECK-NEXT: }
61+
; CHECK-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] {
62+
; CHECK-NEXT: Tag: DW_TAG_base_type
63+
; CHECK-NEXT: DW_IDX_type_unit: DW_FORM_data1
64+
; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
65+
; CHECK-NEXT: DW_IDX_parent: DW_FORM_flag_present
66+
; CHECK-NEXT: }
6767
; CHECK-NEXT: ]
6868
; CHECK-NEXT: Bucket 0 [
6969
; CHECK-NEXT: Name 1 {
@@ -130,7 +130,7 @@
130130
; CHECK-SPLIT: Foreign TU count: 1
131131
; CHECK-SPLIT-NEXT: Bucket count: 4
132132
; CHECK-SPLIT-NEXT: Name count: 4
133-
; CHECK-SPLIT-NEXT: Abbreviations table size: 0x32
133+
; CHECK-SPLIT-NEXT: Abbreviations table size: 0x2D
134134
; CHECK-SPLIT-NEXT: Augmentation: 'LLVM0700'
135135
; CHECK-SPLIT-NEXT: }
136136
; CHECK-SPLIT-NEXT: Compilation Unit offsets [
@@ -140,20 +140,14 @@
140140
; CHECK-SPLIT-NEXT: ForeignTU[0]: 0x675d23e4f33235f2
141141
; CHECK-SPLIT-NEXT: ]
142142
; CHECK-SPLIT-NEXT: Abbreviations [
143-
; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] {
144-
; CHECK-SPLIT-NEXT: Tag: DW_TAG_structure_type
145-
; CHECK-SPLIT-NEXT: DW_IDX_type_unit: DW_FORM_data1
146-
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
147-
; CHECK-SPLIT-NEXT: DW_IDX_parent: DW_FORM_flag_present
148-
; CHECK-SPLIT-NEXT: }
149-
; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] {
143+
; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] {
150144
; CHECK-SPLIT-NEXT: Tag: DW_TAG_base_type
151-
; CHECK-SPLIT-NEXT: DW_IDX_type_unit: DW_FORM_data1
152145
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
153146
; CHECK-SPLIT-NEXT: DW_IDX_parent: DW_FORM_flag_present
154147
; CHECK-SPLIT-NEXT: }
155-
; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] {
156-
; CHECK-SPLIT-NEXT: Tag: DW_TAG_base_type
148+
; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] {
149+
; CHECK-SPLIT-NEXT: Tag: DW_TAG_structure_type
150+
; CHECK-SPLIT-NEXT: DW_IDX_type_unit: DW_FORM_data1
157151
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
158152
; CHECK-SPLIT-NEXT: DW_IDX_parent: DW_FORM_flag_present
159153
; CHECK-SPLIT-NEXT: }
@@ -167,6 +161,12 @@
167161
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
168162
; CHECK-SPLIT-NEXT: DW_IDX_parent: DW_FORM_flag_present
169163
; CHECK-SPLIT-NEXT: }
164+
; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] {
165+
; CHECK-SPLIT-NEXT: Tag: DW_TAG_base_type
166+
; CHECK-SPLIT-NEXT: DW_IDX_type_unit: DW_FORM_data1
167+
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
168+
; CHECK-SPLIT-NEXT: DW_IDX_parent: DW_FORM_flag_present
169+
; CHECK-SPLIT-NEXT: }
170170
; CHECK-SPLIT-NEXT: ]
171171
; CHECK-SPLIT-NEXT: Bucket 0 [
172172
; CHECK-SPLIT-NEXT: Name 1 {

0 commit comments

Comments
 (0)