summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Yermolovich <43973793+ayermolo@users.noreply.github.com>2024-02-14 12:22:53 -0800
committerGitHub <noreply@github.com>2024-02-14 12:22:53 -0800
commita78d13d0786bc81058ee9aaa7d1c854ee19cee48 (patch)
tree09194324cde4d92b94a8481d55298f984cdc44c9
parent5992b3272b29e071f6f5a4807a4e0c23e88c310d (diff)
[LLVM][DWARF] Change .debug_names abbrev to be an index (#81200)
Based on the discussion in https://github.com/llvm/llvm-project/pull/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 using array like data structure. clang-19 debug build before change
 [41] .debug_names PROGBITS 0000000000000000 8f9e0350 137fdbe0 00 0 0 4 after change [41] .debug_names PROGBITS 0000000000000000 8f9e0350 125bfdec 00 0 0 4 Reduction ~19.1MB
-rw-r--r--llvm/include/llvm/CodeGen/AccelTable.h49
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp130
-rw-r--r--llvm/test/DebugInfo/X86/debug-names-dwarf64.ll10
-rw-r--r--llvm/test/DebugInfo/X86/debug-names-types.ll42
-rw-r--r--llvm/test/tools/dsymutil/ARM/dwarf5-dwarf4-combination-macho.test8
5 files changed, 120 insertions, 119 deletions
diff --git a/llvm/include/llvm/CodeGen/AccelTable.h b/llvm/include/llvm/CodeGen/AccelTable.h
index e6a661696354..6ee817a7124d 100644
--- a/llvm/include/llvm/CodeGen/AccelTable.h
+++ b/llvm/include/llvm/CodeGen/AccelTable.h
@@ -275,11 +275,6 @@ struct DenseMapInfo<OffsetAndUnitID> : DenseMapInfo<OffsetAndUnitID::Base> {};
/// emitDWARF5AccelTable function.
class DWARF5AccelTableData : public AccelTableData {
public:
- struct AttributeEncoding {
- dwarf::Index Index;
- dwarf::Form Form;
- };
-
static uint32_t hash(StringRef Name) { return caseFoldingDjbHash(Name); }
DWARF5AccelTableData(const DIE &Die, const uint32_t UnitID,
@@ -289,7 +284,7 @@ public:
const unsigned DieTag, const unsigned UnitID,
const bool IsTU = false)
: OffsetVal(DieOffset), ParentOffset(DefiningParentOffset),
- DieTag(DieTag), UnitID(UnitID), IsTU(IsTU) {}
+ DieTag(DieTag), AbbrevNumber(0), IsTU(IsTU), UnitID(UnitID) {}
#ifndef NDEBUG
void print(raw_ostream &OS) const override;
@@ -330,6 +325,12 @@ public:
return OffsetAndUnitID(*ParentOffset, getUnitID());
}
+ /// Sets AbbrevIndex for an Entry.
+ void setAbbrevNumber(uint16_t AbbrevNum) { AbbrevNumber = AbbrevNum; }
+
+ /// Returns AbbrevIndex for an Entry.
+ uint16_t getAbbrevNumber() const { return AbbrevNumber; }
+
/// If `Die` has a non-null parent and the parent is not a declaration,
/// return its offset.
static std::optional<uint64_t> getDefiningParentDieOffset(const DIE &Die);
@@ -338,12 +339,42 @@ protected:
std::variant<const DIE *, uint64_t> OffsetVal;
std::optional<uint64_t> ParentOffset;
uint32_t DieTag : 16;
- uint32_t UnitID : 15;
+ uint32_t AbbrevNumber : 15;
uint32_t IsTU : 1;
-
+ uint32_t UnitID;
uint64_t order() const override { return getDieOffset(); }
};
+class DebugNamesAbbrev : public FoldingSetNode {
+public:
+ uint32_t DieTag;
+ uint32_t Number;
+ struct AttributeEncoding {
+ dwarf::Index Index;
+ dwarf::Form Form;
+ };
+ DebugNamesAbbrev(uint32_t DieTag) : DieTag(DieTag) {}
+ /// Add attribute encoding to an abbreviation.
+ void addAttribute(const DebugNamesAbbrev::AttributeEncoding &Attr) {
+ AttrVect.push_back(Attr);
+ }
+ /// Set abbreviation tag index.
+ void setNumber(uint32_t AbbrevNumber) { Number = AbbrevNumber; }
+ /// Get abbreviation tag index.
+ uint32_t getNumber() const { return Number; }
+ /// Get DIE Tag.
+ uint32_t getDieTag() const { return DieTag; }
+ /// Used to gather unique data for the abbreviation folding set.
+ void Profile(FoldingSetNodeID &ID) const;
+ /// Returns attributes for an abbreviation.
+ const SmallVector<AttributeEncoding, 1> &getAttributes() const {
+ return AttrVect;
+ }
+
+private:
+ SmallVector<AttributeEncoding, 1> AttrVect;
+};
+
struct TypeUnitMetaInfo {
// Symbol for start of the TU section or signature if this is SplitDwarf.
std::variant<MCSymbol *, uint64_t> LabelOrSignature;
@@ -358,7 +389,7 @@ class DWARF5AccelTable : public AccelTable<DWARF5AccelTableData> {
public:
struct UnitIndexAndEncoding {
unsigned Index;
- DWARF5AccelTableData::AttributeEncoding Encoding;
+ DebugNamesAbbrev::AttributeEncoding Encoding;
};
/// Returns type units that were constructed.
const TUVectorTy &getTypeUnitsSymbols() { return TUSymbolsOrHashes; }
diff --git a/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp b/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp
index 1024aabf2ab0..230d7add6d37 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AccelTable.cpp
@@ -208,8 +208,13 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
};
Header Header;
- DenseMap<uint32_t, SmallVector<DWARF5AccelTableData::AttributeEncoding, 3>>
- Abbreviations;
+ /// FoldingSet that uniques the abbreviations.
+ FoldingSet<DebugNamesAbbrev> AbbreviationsSet;
+ /// Vector containing DebugNames abbreviations for iteration in order.
+ SmallVector<DebugNamesAbbrev *, 5> AbbreviationsVector;
+ /// The bump allocator to use when creating DIEAbbrev objects in the uniqued
+ /// storage container.
+ BumpPtrAllocator Alloc;
ArrayRef<std::variant<MCSymbol *, uint64_t>> CompUnits;
ArrayRef<std::variant<MCSymbol *, uint64_t>> TypeUnits;
llvm::function_ref<std::optional<DWARF5AccelTable::UnitIndexAndEncoding>(
@@ -234,7 +239,7 @@ class Dwarf5AccelTableWriter : public AccelTableWriter {
void emitEntry(
const DWARF5AccelTableData &Entry,
const DenseMap<OffsetAndUnitID, MCSymbol *> &DIEOffsetToAccelEntryLabel,
- DenseSet<MCSymbol *> &EmittedAccelEntrySymbols) const;
+ DenseSet<MCSymbol *> &EmittedAccelEntrySymbols);
void emitData();
public:
@@ -370,7 +375,7 @@ void AppleAccelTableWriter::emit() const {
DWARF5AccelTableData::DWARF5AccelTableData(const DIE &Die,
const uint32_t UnitID,
const bool IsTU)
- : OffsetVal(&Die), DieTag(Die.getTag()), UnitID(UnitID), IsTU(IsTU) {}
+ : OffsetVal(&Die), DieTag(Die.getTag()), IsTU(IsTU), UnitID(UnitID) {}
void Dwarf5AccelTableWriter::Header::emit(Dwarf5AccelTableWriter &Ctx) {
assert(CompUnitCount > 0 && "Index must have at least one CU.");
@@ -409,51 +414,6 @@ DWARF5AccelTableData::getDefiningParentDieOffset(const DIE &Die) {
return {};
}
-enum IdxParentEncoding : uint8_t {
- NoIndexedParent = 0, /// Parent information present but parent isn't indexed.
- Ref4 = 1, /// Parent information present and parent is indexed.
- NoParent = 2, /// Parent information missing.
-};
-
-static uint32_t constexpr NumBitsIdxParent = 2;
-
-uint8_t encodeIdxParent(const std::optional<dwarf::Form> MaybeParentForm) {
- if (!MaybeParentForm)
- return NoParent;
- switch (*MaybeParentForm) {
- case dwarf::Form::DW_FORM_flag_present:
- return NoIndexedParent;
- case dwarf::Form::DW_FORM_ref4:
- return Ref4;
- default:
- // This is not crashing on bad input: we should only reach this if the
- // internal compiler logic is faulty; see getFormForIdxParent.
- llvm_unreachable("Bad form for IDX_parent");
- }
-}
-
-static uint32_t constexpr ParentBitOffset = dwarf::DW_IDX_type_hash;
-static uint32_t constexpr TagBitOffset = ParentBitOffset + NumBitsIdxParent;
-static uint32_t getTagFromAbbreviationTag(const uint32_t AbbrvTag) {
- return AbbrvTag >> TagBitOffset;
-}
-
-/// Constructs a unique AbbrevTag that captures what a DIE accesses.
-/// Using this tag we can emit a unique abbreviation for each DIE.
-static uint32_t constructAbbreviationTag(
- const unsigned Tag,
- const std::optional<DWARF5AccelTable::UnitIndexAndEncoding> &EntryRet,
- std::optional<dwarf::Form> MaybeParentForm) {
- uint32_t AbbrvTag = 0;
- if (EntryRet)
- AbbrvTag |= 1 << EntryRet->Encoding.Index;
- AbbrvTag |= 1 << dwarf::DW_IDX_die_offset;
- AbbrvTag |= 1 << dwarf::DW_IDX_parent;
- AbbrvTag |= encodeIdxParent(MaybeParentForm) << ParentBitOffset;
- AbbrvTag |= Tag << TagBitOffset;
- return AbbrvTag;
-}
-
static std::optional<dwarf::Form>
getFormForIdxParent(const DenseSet<OffsetAndUnitID> &IndexedOffsets,
std::optional<OffsetAndUnitID> ParentOffset) {
@@ -467,26 +427,42 @@ getFormForIdxParent(const DenseSet<OffsetAndUnitID> &IndexedOffsets,
return dwarf::Form::DW_FORM_flag_present;
}
+void DebugNamesAbbrev::Profile(FoldingSetNodeID &ID) const {
+ ID.AddInteger(DieTag);
+ for (const DebugNamesAbbrev::AttributeEncoding &Enc : AttrVect) {
+ ID.AddInteger(Enc.Index);
+ ID.AddInteger(Enc.Form);
+ }
+}
+
void Dwarf5AccelTableWriter::populateAbbrevsMap() {
for (auto &Bucket : Contents.getBuckets()) {
for (auto *Hash : Bucket) {
for (auto *Value : Hash->getValues<DWARF5AccelTableData *>()) {
std::optional<DWARF5AccelTable::UnitIndexAndEncoding> EntryRet =
getIndexForEntry(*Value);
- unsigned Tag = Value->getDieTag();
std::optional<dwarf::Form> MaybeParentForm = getFormForIdxParent(
IndexedOffsets, Value->getParentDieOffsetAndUnitID());
- uint32_t AbbrvTag =
- constructAbbreviationTag(Tag, EntryRet, MaybeParentForm);
- if (Abbreviations.count(AbbrvTag) == 0) {
- SmallVector<DWARF5AccelTableData::AttributeEncoding, 3> UA;
- if (EntryRet)
- UA.push_back(EntryRet->Encoding);
- UA.push_back({dwarf::DW_IDX_die_offset, dwarf::DW_FORM_ref4});
- if (MaybeParentForm)
- UA.push_back({dwarf::DW_IDX_parent, *MaybeParentForm});
- Abbreviations.try_emplace(AbbrvTag, UA);
+ DebugNamesAbbrev Abbrev(Value->getDieTag());
+ if (EntryRet)
+ Abbrev.addAttribute(EntryRet->Encoding);
+ Abbrev.addAttribute({dwarf::DW_IDX_die_offset, dwarf::DW_FORM_ref4});
+ if (MaybeParentForm)
+ Abbrev.addAttribute({dwarf::DW_IDX_parent, *MaybeParentForm});
+ FoldingSetNodeID ID;
+ Abbrev.Profile(ID);
+ void *InsertPos;
+ if (DebugNamesAbbrev *Existing =
+ AbbreviationsSet.FindNodeOrInsertPos(ID, InsertPos)) {
+ Value->setAbbrevNumber(Existing->getNumber());
+ continue;
}
+ DebugNamesAbbrev *NewAbbrev =
+ new (Alloc) DebugNamesAbbrev(std::move(Abbrev));
+ AbbreviationsVector.push_back(NewAbbrev);
+ NewAbbrev->setNumber(AbbreviationsVector.size());
+ AbbreviationsSet.InsertNode(NewAbbrev, InsertPos);
+ Value->setAbbrevNumber(NewAbbrev->getNumber());
}
}
}
@@ -536,14 +512,13 @@ void Dwarf5AccelTableWriter::emitStringOffsets() const {
void Dwarf5AccelTableWriter::emitAbbrevs() const {
Asm->OutStreamer->emitLabel(AbbrevStart);
- for (const auto &Abbrev : Abbreviations) {
+ for (const DebugNamesAbbrev *Abbrev : AbbreviationsVector) {
Asm->OutStreamer->AddComment("Abbrev code");
- uint32_t Tag = getTagFromAbbreviationTag(Abbrev.first);
- assert(Tag != 0);
- Asm->emitULEB128(Abbrev.first);
- Asm->OutStreamer->AddComment(dwarf::TagString(Tag));
- Asm->emitULEB128(Tag);
- for (const auto &AttrEnc : Abbrev.second) {
+ Asm->emitULEB128(Abbrev->getNumber());
+ Asm->OutStreamer->AddComment(dwarf::TagString(Abbrev->getDieTag()));
+ Asm->emitULEB128(Abbrev->getDieTag());
+ for (const DebugNamesAbbrev::AttributeEncoding &AttrEnc :
+ Abbrev->getAttributes()) {
Asm->emitULEB128(AttrEnc.Index, dwarf::IndexString(AttrEnc.Index).data());
Asm->emitULEB128(AttrEnc.Form,
dwarf::FormEncodingString(AttrEnc.Form).data());
@@ -558,21 +533,15 @@ void Dwarf5AccelTableWriter::emitAbbrevs() const {
void Dwarf5AccelTableWriter::emitEntry(
const DWARF5AccelTableData &Entry,
const DenseMap<OffsetAndUnitID, MCSymbol *> &DIEOffsetToAccelEntryLabel,
- DenseSet<MCSymbol *> &EmittedAccelEntrySymbols) const {
+ DenseSet<MCSymbol *> &EmittedAccelEntrySymbols) {
+ unsigned AbbrevIndex = Entry.getAbbrevNumber() - 1;
+ assert(AbbrevIndex < AbbreviationsVector.size() &&
+ "Entry abbrev index is outside of abbreviations vector range.");
+ DebugNamesAbbrev *Abbrev = AbbreviationsVector[AbbrevIndex];
std::optional<DWARF5AccelTable::UnitIndexAndEncoding> EntryRet =
getIndexForEntry(Entry);
std::optional<OffsetAndUnitID> MaybeParentOffset =
Entry.getParentDieOffsetAndUnitID();
- std::optional<dwarf::Form> MaybeParentForm =
- getFormForIdxParent(IndexedOffsets, MaybeParentOffset);
- uint32_t AbbrvTag =
- constructAbbreviationTag(Entry.getDieTag(), EntryRet, MaybeParentForm);
- auto AbbrevIt = Abbreviations.find(AbbrvTag);
- assert(AbbrevIt != Abbreviations.end() &&
- "Why wasn't this abbrev generated?");
- assert(getTagFromAbbreviationTag(AbbrevIt->first) == Entry.getDieTag() &&
- "Invalid Tag");
-
auto EntrySymbolIt =
DIEOffsetToAccelEntryLabel.find(Entry.getDieOffsetAndUnitID());
assert(EntrySymbolIt != DIEOffsetToAccelEntryLabel.end());
@@ -584,9 +553,10 @@ void Dwarf5AccelTableWriter::emitEntry(
if (EmittedAccelEntrySymbols.insert(EntrySymbol).second)
Asm->OutStreamer->emitLabel(EntrySymbol);
- Asm->emitULEB128(AbbrevIt->first, "Abbreviation code");
+ Asm->emitULEB128(Entry.getAbbrevNumber(), "Abbreviation code");
- for (const auto &AttrEnc : AbbrevIt->second) {
+ for (const DebugNamesAbbrev::AttributeEncoding &AttrEnc :
+ Abbrev->getAttributes()) {
Asm->OutStreamer->AddComment(dwarf::IndexString(AttrEnc.Index));
switch (AttrEnc.Index) {
case dwarf::DW_IDX_compile_unit:
diff --git a/llvm/test/DebugInfo/X86/debug-names-dwarf64.ll b/llvm/test/DebugInfo/X86/debug-names-dwarf64.ll
index c15e2ad1d56b..9a5fd0733587 100644
--- a/llvm/test/DebugInfo/X86/debug-names-dwarf64.ll
+++ b/llvm/test/DebugInfo/X86/debug-names-dwarf64.ll
@@ -30,11 +30,6 @@
; CHECK-NEXT: CU[0]: 0x00000000
; CHECK-NEXT: ]
; CHECK-NEXT: Abbreviations [
-; CHECK-NEXT: Abbreviation [[ABBREV_LABEL:0x[0-9a-f]*]] {
-; CHECK-NEXT: Tag: DW_TAG_label
-; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
-; CHECK-NEXT: DW_IDX_parent: DW_FORM_ref4
-; CHECK-NEXT: }
; CHECK-NEXT: Abbreviation [[ABBREV:0x[0-9a-f]*]] {
; CHECK-NEXT: Tag: DW_TAG_base_type
; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
@@ -50,6 +45,11 @@
; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
; CHECK-NEXT: DW_IDX_parent: DW_FORM_flag_present
; CHECK-NEXT: }
+; CHECK-NEXT: Abbreviation [[ABBREV_LABEL:0x[0-9a-f]*]] {
+; CHECK-NEXT: Tag: DW_TAG_label
+; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; CHECK-NEXT: DW_IDX_parent: DW_FORM_ref4
+; CHECK-NEXT: }
; CHECK-NEXT: ]
; CHECK-NEXT: Bucket 0 [
; CHECK-NEXT: Name 1 {
diff --git a/llvm/test/DebugInfo/X86/debug-names-types.ll b/llvm/test/DebugInfo/X86/debug-names-types.ll
index f41bb5524b9c..ff0d4d52c1f0 100644
--- a/llvm/test/DebugInfo/X86/debug-names-types.ll
+++ b/llvm/test/DebugInfo/X86/debug-names-types.ll
@@ -37,20 +37,14 @@
; CHECK-NEXT: LocalTU[0]: 0x00000000
; CHECK-NEXT: ]
; CHECK: Abbreviations [
-; CHECK-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] {
-; CHECK-NEXT: Tag: DW_TAG_structure_type
-; CHECK-NEXT: DW_IDX_type_unit: DW_FORM_data1
-; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
-; CHECK-NEXT: DW_IDX_parent: DW_FORM_flag_present
-; CHECK-NEXT: }
-; CHECK-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] {
+; CHECK-NEXT: Abbreviation [[ABBREV:0x[0-9a-f]*]] {
; CHECK-NEXT: Tag: DW_TAG_base_type
-; CHECK-NEXT: DW_IDX_type_unit: DW_FORM_data1
; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
; CHECK-NEXT: DW_IDX_parent: DW_FORM_flag_present
; CHECK-NEXT: }
-; CHECK-NEXT: Abbreviation [[ABBREV:0x[0-9a-f]*]] {
-; CHECK-NEXT: Tag: DW_TAG_base_type
+; CHECK-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] {
+; CHECK-NEXT: Tag: DW_TAG_structure_type
+; CHECK-NEXT: DW_IDX_type_unit: DW_FORM_data1
; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
; CHECK-NEXT: DW_IDX_parent: DW_FORM_flag_present
; CHECK-NEXT: }
@@ -64,6 +58,12 @@
; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
; CHECK-NEXT: DW_IDX_parent: DW_FORM_flag_present
; CHECK-NEXT: }
+; CHECK-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] {
+; CHECK-NEXT: Tag: DW_TAG_base_type
+; CHECK-NEXT: DW_IDX_type_unit: DW_FORM_data1
+; CHECK-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; CHECK-NEXT: DW_IDX_parent: DW_FORM_flag_present
+; CHECK-NEXT: }
; CHECK-NEXT: ]
; CHECK-NEXT: Bucket 0 [
; CHECK-NEXT: Name 1 {
@@ -130,7 +130,7 @@
; CHECK-SPLIT: Foreign TU count: 1
; CHECK-SPLIT-NEXT: Bucket count: 4
; CHECK-SPLIT-NEXT: Name count: 4
-; CHECK-SPLIT-NEXT: Abbreviations table size: 0x32
+; CHECK-SPLIT-NEXT: Abbreviations table size: 0x2D
; CHECK-SPLIT-NEXT: Augmentation: 'LLVM0700'
; CHECK-SPLIT-NEXT: }
; CHECK-SPLIT-NEXT: Compilation Unit offsets [
@@ -140,20 +140,14 @@
; CHECK-SPLIT-NEXT: ForeignTU[0]: 0x675d23e4f33235f2
; CHECK-SPLIT-NEXT: ]
; CHECK-SPLIT-NEXT: Abbreviations [
-; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] {
-; CHECK-SPLIT-NEXT: Tag: DW_TAG_structure_type
-; CHECK-SPLIT-NEXT: DW_IDX_type_unit: DW_FORM_data1
-; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
-; CHECK-SPLIT-NEXT: DW_IDX_parent: DW_FORM_flag_present
-; CHECK-SPLIT-NEXT: }
-; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] {
+; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] {
; CHECK-SPLIT-NEXT: Tag: DW_TAG_base_type
-; CHECK-SPLIT-NEXT: DW_IDX_type_unit: DW_FORM_data1
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
; CHECK-SPLIT-NEXT: DW_IDX_parent: DW_FORM_flag_present
; CHECK-SPLIT-NEXT: }
-; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] {
-; CHECK-SPLIT-NEXT: Tag: DW_TAG_base_type
+; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] {
+; CHECK-SPLIT-NEXT: Tag: DW_TAG_structure_type
+; CHECK-SPLIT-NEXT: DW_IDX_type_unit: DW_FORM_data1
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
; CHECK-SPLIT-NEXT: DW_IDX_parent: DW_FORM_flag_present
; CHECK-SPLIT-NEXT: }
@@ -167,6 +161,12 @@
; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
; CHECK-SPLIT-NEXT: DW_IDX_parent: DW_FORM_flag_present
; CHECK-SPLIT-NEXT: }
+; CHECK-SPLIT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] {
+; CHECK-SPLIT-NEXT: Tag: DW_TAG_base_type
+; CHECK-SPLIT-NEXT: DW_IDX_type_unit: DW_FORM_data1
+; CHECK-SPLIT-NEXT: DW_IDX_die_offset: DW_FORM_ref4
+; CHECK-SPLIT-NEXT: DW_IDX_parent: DW_FORM_flag_present
+; CHECK-SPLIT-NEXT: }
; CHECK-SPLIT-NEXT: ]
; CHECK-SPLIT-NEXT: Bucket 0 [
; CHECK-SPLIT-NEXT: Name 1 {
diff --git a/llvm/test/tools/dsymutil/ARM/dwarf5-dwarf4-combination-macho.test b/llvm/test/tools/dsymutil/ARM/dwarf5-dwarf4-combination-macho.test
index 5a37b4247b5b..fb15f46ce0b2 100644
--- a/llvm/test/tools/dsymutil/ARM/dwarf5-dwarf4-combination-macho.test
+++ b/llvm/test/tools/dsymutil/ARM/dwarf5-dwarf4-combination-macho.test
@@ -221,8 +221,8 @@ CHECK-NEXT: Name Index @ 0x0 {
CHECK-NEXT: Header {
; FIXME: when the parallel dwarf linker is able to generate DW_IDX_parent,
; these headers should be the same.
-WITH-PARENTS-NEXT: Length: 0xC8
-NO-PARENTS-NEXT: Length: 0xC4
+WITH-PARENTS-NEXT: Length: 0xC0
+NO-PARENTS-NEXT: Length: 0xBC
CHECK-NEXT: Format: DWARF32
CHECK-NEXT: Version: 5
CHECK-NEXT: CU count: 2
@@ -230,7 +230,7 @@ CHECK-NEXT: Local TU count: 0
CHECK-NEXT: Foreign TU count: 0
CHECK-NEXT: Bucket count: 5
CHECK-NEXT: Name count: 5
-WITH-PARENTS-NEXT: Abbreviations table size: 0x17
-NO-PARENTS-NEXT: Abbreviations table size: 0x13
+WITH-PARENTS-NEXT: Abbreviations table size: 0x15
+NO-PARENTS-NEXT: Abbreviations table size: 0x11
CHECK-NEXT: Augmentation: 'LLVM0700'
CHECK-NEXT: }