From: Duncan P. N. Exon Smith Date: Wed, 27 May 2015 22:31:41 +0000 (+0000) Subject: AsmPrinter: Store abbreviation data directly in DIE and DIEValue X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=611a2f232296f0b3178d800af2e9403be97bc2d3;p=oota-llvm.git AsmPrinter: Store abbreviation data directly in DIE and DIEValue Stop storing a `DIEAbbrev` in `DIE`, since the data fits neatly inside the `DIEValue` list. Besides being a cleaner data structure (avoiding the parallel arrays), this gives us more freedom to rearrange the `DIEValue` list. This fixes the temporary memory regression from 845 MB up to 879 MB, and drops it further to 829 MB for a net memory decrease of around 1.9% (incremental decrease around 5.7%). (I'm looking at `llc` memory usage on `verify-uselistorder.lto.opt.bc`; see r236629 for details.) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238364 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/DIE.h b/include/llvm/CodeGen/DIE.h index 0d5348c9052..270fa5c7c8d 100644 --- a/include/llvm/CodeGen/DIE.h +++ b/include/llvm/CodeGen/DIE.h @@ -315,7 +315,9 @@ public: private: /// Ty - Type of data stored in the value. /// - Type Ty; + Type Ty = isNone; + dwarf::Attribute Attribute = (dwarf::Attribute)0; + dwarf::Form Form = (dwarf::Form)0; /// Storage for the value. /// @@ -387,20 +389,28 @@ private: } public: - DIEValue() : Ty(isNone) {} - DIEValue(const DIEValue &X) : Ty(X.Ty) { copyVal(X); } + DIEValue() = default; + DIEValue(const DIEValue &X) : Ty(X.Ty), Attribute(X.Attribute), Form(X.Form) { + copyVal(X); + } DIEValue &operator=(const DIEValue &X) { destroyVal(); Ty = X.Ty; + Attribute = X.Attribute; + Form = X.Form; copyVal(X); return *this; } ~DIEValue() { destroyVal(); } #define HANDLE_DIEVALUE_SMALL(T) \ - DIEValue(const DIE##T &V) : Ty(is##T) { construct(V); } + DIEValue(dwarf::Attribute Attribute, dwarf::Form Form, const DIE##T &V) \ + : Ty(is##T), Attribute(Attribute), Form(Form) { \ + construct(V); \ + } #define HANDLE_DIEVALUE_LARGE(T) \ - DIEValue(const DIE##T *V) : Ty(is##T) { \ + DIEValue(dwarf::Attribute Attribute, dwarf::Form Form, const DIE##T *V) \ + : Ty(is##T), Attribute(Attribute), Form(Form) { \ assert(V && "Expected valid value"); \ construct(V); \ } @@ -408,6 +418,8 @@ public: // Accessors Type getType() const { return Ty; } + dwarf::Attribute getAttribute() const { return Attribute; } + dwarf::Form getForm() const { return Form; } explicit operator bool() const { return Ty; } #define HANDLE_DIEVALUE_SMALL(T) \ @@ -449,9 +461,11 @@ protected: /// unsigned Size; - /// Abbrev - Buffer for constructing abbreviation. + unsigned AbbrevNumber = ~0u; + + /// Tag - Dwarf tag code. /// - DIEAbbrev Abbrev; + dwarf::Tag Tag = (dwarf::Tag)0; /// Children DIEs. /// @@ -470,22 +484,18 @@ protected: SmallVector Values; protected: - DIE() - : Offset(0), Size(0), Abbrev((dwarf::Tag)0, dwarf::DW_CHILDREN_no), - Parent(nullptr) {} + DIE() : Offset(0), Size(0), Parent(nullptr) {} public: explicit DIE(dwarf::Tag Tag) - : Offset(0), Size(0), Abbrev((dwarf::Tag)Tag, dwarf::DW_CHILDREN_no), - Parent(nullptr) {} + : Offset(0), Size(0), Tag(Tag), Parent(nullptr) {} // Accessors. - DIEAbbrev &getAbbrev() { return Abbrev; } - const DIEAbbrev &getAbbrev() const { return Abbrev; } - unsigned getAbbrevNumber() const { return Abbrev.getNumber(); } - dwarf::Tag getTag() const { return Abbrev.getTag(); } + unsigned getAbbrevNumber() const { return AbbrevNumber; } + dwarf::Tag getTag() const { return Tag; } unsigned getOffset() const { return Offset; } unsigned getSize() const { return Size; } + bool hasChildren() const { return !Children.empty(); } const std::vector> &getChildren() const { return Children; } @@ -495,6 +505,16 @@ public: Values[I] = New; } DIE *getParent() const { return Parent; } + + /// Generate the abbreviation for this DIE. + /// + /// Calculate the abbreviation for this, which should be uniqued and + /// eventually used to call \a setAbbrevNumber(). + DIEAbbrev generateAbbrev() const; + + /// Set the abbreviation number for this DIE. + void setAbbrevNumber(unsigned I) { AbbrevNumber = I; } + /// Climb up the parent chain to get the compile or type unit DIE this DIE /// belongs to. const DIE *getUnit() const; @@ -506,16 +526,16 @@ public: /// addValue - Add a value and attributes to a DIE. /// - void addValue(dwarf::Attribute Attribute, dwarf::Form Form, DIEValue Value) { - Abbrev.AddAttribute(Attribute, Form); - Values.push_back(Value); + void addValue(DIEValue Value) { Values.push_back(Value); } + template + void addValue(dwarf::Attribute Attribute, dwarf::Form Form, T &&Value) { + Values.emplace_back(Attribute, Form, std::forward(Value)); } /// addChild - Add a child to the DIE. /// void addChild(std::unique_ptr Child) { assert(!Child->getParent()); - Abbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes); Child->Parent = this; Children.push_back(std::move(Child)); } diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp index 42e7cf7f35c..38ebedc9939 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp @@ -254,24 +254,20 @@ void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const { } void AsmPrinter::emitDwarfDIE(const DIE &Die) const { - // Get the abbreviation for this DIE. - const DIEAbbrev &Abbrev = Die.getAbbrev(); - // Emit the code (index) for the abbreviation. if (isVerbose()) - OutStreamer->AddComment("Abbrev [" + Twine(Abbrev.getNumber()) + - "] 0x" + Twine::utohexstr(Die.getOffset()) + - ":0x" + Twine::utohexstr(Die.getSize()) + " " + - dwarf::TagString(Abbrev.getTag())); - EmitULEB128(Abbrev.getNumber()); + OutStreamer->AddComment("Abbrev [" + Twine(Die.getAbbrevNumber()) + "] 0x" + + Twine::utohexstr(Die.getOffset()) + ":0x" + + Twine::utohexstr(Die.getSize()) + " " + + dwarf::TagString(Die.getTag())); + EmitULEB128(Die.getAbbrevNumber()); const SmallVectorImpl &Values = Die.getValues(); - const SmallVectorImpl &AbbrevData = Abbrev.getData(); // Emit the DIE attribute values. for (unsigned i = 0, N = Values.size(); i < N; ++i) { - dwarf::Attribute Attr = AbbrevData[i].getAttribute(); - dwarf::Form Form = AbbrevData[i].getForm(); + dwarf::Attribute Attr = Values[i].getAttribute(); + dwarf::Form Form = Values[i].getForm(); assert(Form && "Too many attributes for DIE (check abbreviation)"); if (isVerbose()) { @@ -286,7 +282,7 @@ void AsmPrinter::emitDwarfDIE(const DIE &Die) const { } // Emit the DIE children if any. - if (Abbrev.hasChildren()) { + if (Die.hasChildren()) { for (auto &Child : Die.getChildren()) emitDwarfDIE(*Child); diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp index 4814347116e..a899e34c7ee 100644 --- a/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/lib/CodeGen/AsmPrinter/DIE.cpp @@ -107,6 +107,13 @@ void DIEAbbrev::print(raw_ostream &O) { void DIEAbbrev::dump() { print(dbgs()); } #endif +DIEAbbrev DIE::generateAbbrev() const { + DIEAbbrev Abbrev(Tag, hasChildren()); + for (const DIEValue &V : Values) + Abbrev.AddAttribute(V.getAttribute(), V.getForm()); + return Abbrev; +} + /// Climb up the parent chain to get the unit DIE to which this DIE /// belongs. const DIE *DIE::getUnit() const { @@ -130,12 +137,11 @@ const DIE *DIE::getUnitOrNull() const { DIEValue DIE::findAttribute(dwarf::Attribute Attribute) const { const SmallVectorImpl &Values = getValues(); - const DIEAbbrev &Abbrevs = getAbbrev(); // Iterate through all the attributes until we find the one we're // looking for, if we can't find it return NULL. for (size_t i = 0; i < Values.size(); ++i) - if (Abbrevs.getData()[i].getAttribute() == Attribute) + if (Values[i].getAttribute() == Attribute) return Values[i]; return DIEValue(); } @@ -143,7 +149,7 @@ DIEValue DIE::findAttribute(dwarf::Attribute Attribute) const { #ifndef NDEBUG void DIE::print(raw_ostream &O, unsigned IndentCount) const { const std::string Indent(IndentCount, ' '); - bool isBlock = Abbrev.getTag() == 0; + bool isBlock = getTag() == 0; if (!isBlock) { O << Indent @@ -153,26 +159,24 @@ void DIE::print(raw_ostream &O, unsigned IndentCount) const { << ", Size: " << Size << "\n"; O << Indent - << dwarf::TagString(Abbrev.getTag()) + << dwarf::TagString(getTag()) << " " - << dwarf::ChildrenString(Abbrev.hasChildren()) << "\n"; + << dwarf::ChildrenString(hasChildren()) << "\n"; } else { O << "Size: " << Size << "\n"; } - const SmallVectorImpl &Data = Abbrev.getData(); - IndentCount += 2; - for (unsigned i = 0, N = Data.size(); i < N; ++i) { + for (unsigned i = 0, N = Values.size(); i < N; ++i) { O << Indent; if (!isBlock) - O << dwarf::AttributeString(Data[i].getAttribute()); + O << dwarf::AttributeString(Values[i].getAttribute()); else O << "Blk[" << i << "]"; O << " " - << dwarf::FormEncodingString(Data[i].getForm()) + << dwarf::FormEncodingString(Values[i].getForm()) << " "; Values[i].print(O); O << "\n"; @@ -505,9 +509,8 @@ void DIETypeSignature::print(raw_ostream &O) const { /// unsigned DIELoc::ComputeSize(const AsmPrinter *AP) const { if (!Size) { - const SmallVectorImpl &AbbrevData = Abbrev.getData(); for (unsigned i = 0, N = Values.size(); i < N; ++i) - Size += Values[i].SizeOf(AP, AbbrevData[i].getForm()); + Size += Values[i].SizeOf(AP, Values[i].getForm()); } return Size; @@ -526,9 +529,8 @@ void DIELoc::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const { Asm->EmitULEB128(Size); break; } - const SmallVectorImpl &AbbrevData = Abbrev.getData(); for (unsigned i = 0, N = Values.size(); i < N; ++i) - Values[i].EmitValue(Asm, AbbrevData[i].getForm()); + Values[i].EmitValue(Asm, Values[i].getForm()); } /// SizeOf - Determine size of location data in bytes. @@ -560,9 +562,8 @@ void DIELoc::print(raw_ostream &O) const { /// unsigned DIEBlock::ComputeSize(const AsmPrinter *AP) const { if (!Size) { - const SmallVectorImpl &AbbrevData = Abbrev.getData(); for (unsigned i = 0, N = Values.size(); i < N; ++i) - Size += Values[i].SizeOf(AP, AbbrevData[i].getForm()); + Size += Values[i].SizeOf(AP, Values[i].getForm()); } return Size; @@ -579,9 +580,8 @@ void DIEBlock::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const { case dwarf::DW_FORM_block: Asm->EmitULEB128(Size); break; } - const SmallVectorImpl &AbbrevData = Abbrev.getData(); for (unsigned i = 0, N = Values.size(); i < N; ++i) - Values[i].EmitValue(Asm, AbbrevData[i].getForm()); + Values[i].EmitValue(Asm, Values[i].getForm()); } /// SizeOf - Determine size of block data in bytes. diff --git a/lib/CodeGen/AsmPrinter/DIEHash.cpp b/lib/CodeGen/AsmPrinter/DIEHash.cpp index 53e02fac6e3..30f38658b34 100644 --- a/lib/CodeGen/AsmPrinter/DIEHash.cpp +++ b/lib/CodeGen/AsmPrinter/DIEHash.cpp @@ -32,12 +32,11 @@ using namespace llvm; /// a reference to it. static StringRef getDIEStringAttr(const DIE &Die, uint16_t Attr) { const auto &Values = Die.getValues(); - const DIEAbbrev &Abbrevs = Die.getAbbrev(); // Iterate through all the attributes until we find the one we're // looking for, if we can't find it return an empty string. for (size_t i = 0; i < Values.size(); ++i) { - if (Abbrevs.getData()[i].getAttribute() == Attr) + if (Values[i].getAttribute() == Attr) return Values[i].getDIEString().getString(); } return StringRef(""); @@ -120,19 +119,17 @@ void DIEHash::addParentContext(const DIE &Parent) { // Collect all of the attributes for a particular DIE in single structure. void DIEHash::collectAttributes(const DIE &Die, DIEAttrs &Attrs) { const SmallVectorImpl &Values = Die.getValues(); - const DIEAbbrev &Abbrevs = Die.getAbbrev(); #define COLLECT_ATTR(NAME) \ case dwarf::NAME: \ Attrs.NAME.Val = Values[i]; \ - Attrs.NAME.Desc = &Abbrevs.getData()[i]; \ break for (size_t i = 0, e = Values.size(); i != e; ++i) { DEBUG(dbgs() << "Attribute: " - << dwarf::AttributeString(Abbrevs.getData()[i].getAttribute()) + << dwarf::AttributeString(Values[i].getAttribute()) << " added.\n"); - switch (Abbrevs.getData()[i].getAttribute()) { + switch (Values[i].getAttribute()) { COLLECT_ATTR(DW_AT_name); COLLECT_ATTR(DW_AT_accessibility); COLLECT_ATTR(DW_AT_address_class); @@ -288,8 +285,7 @@ void DIEHash::hashLocList(const DIELocList &LocList) { // the form. void DIEHash::hashAttribute(AttrEntry Attr, dwarf::Tag Tag) { const DIEValue &Value = Attr.Val; - const DIEAbbrevData *Desc = Attr.Desc; - dwarf::Attribute Attribute = Desc->getAttribute(); + dwarf::Attribute Attribute = Value.getAttribute(); // Other attribute values use the letter 'A' as the marker, and the value // consists of the form code (encoded as an unsigned LEB128 value) followed by @@ -311,7 +307,7 @@ void DIEHash::hashAttribute(AttrEntry Attr, dwarf::Tag Tag) { case DIEValue::isInteger: { addULEB128('A'); addULEB128(Attribute); - switch (Desc->getForm()) { + switch (Value.getForm()) { case dwarf::DW_FORM_data1: case dwarf::DW_FORM_data2: case dwarf::DW_FORM_data4: diff --git a/lib/CodeGen/AsmPrinter/DIEHash.h b/lib/CodeGen/AsmPrinter/DIEHash.h index f71fac21064..97b427f03f3 100644 --- a/lib/CodeGen/AsmPrinter/DIEHash.h +++ b/lib/CodeGen/AsmPrinter/DIEHash.h @@ -28,9 +28,10 @@ class CompileUnit; class DIEHash { // The entry for a particular attribute. + // + // FIXME: Remove this struct, it's pretty boring now. struct AttrEntry { DIEValue Val; - const DIEAbbrevData *Desc; }; // Collection of all attributes used in hashing a particular DIE. diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 2256200c8d0..b59fb002f72 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -51,8 +51,10 @@ void DwarfCompileUnit::addLocalLabelAddress(DIE &Die, if (Label) DD->addArangeLabel(SymbolCU(this, Label)); - Die.addValue(Attribute, dwarf::DW_FORM_addr, - Label ? DIEValue(DIELabel(Label)) : DIEValue(DIEInteger(0))); + if (Label) + Die.addValue(Attribute, dwarf::DW_FORM_addr, DIELabel(Label)); + else + Die.addValue(Attribute, dwarf::DW_FORM_addr, DIEInteger(0)); } unsigned DwarfCompileUnit::getOrCreateSourceID(StringRef FileName, @@ -253,9 +255,7 @@ void DwarfCompileUnit::initStmtList() { } void DwarfCompileUnit::applyStmtList(DIE &D) { - D.addValue(dwarf::DW_AT_stmt_list, - UnitDie.getAbbrev().getData()[stmtListIndex].getForm(), - UnitDie.getValues()[stmtListIndex]); + D.addValue(UnitDie.getValues()[stmtListIndex]); } void DwarfCompileUnit::attachLowHighPC(DIE &D, const MCSymbol *Begin, diff --git a/lib/CodeGen/AsmPrinter/DwarfFile.cpp b/lib/CodeGen/AsmPrinter/DwarfFile.cpp index 9951c1d116d..a9e9044a4d6 100644 --- a/lib/CodeGen/AsmPrinter/DwarfFile.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfFile.cpp @@ -24,21 +24,27 @@ DwarfFile::~DwarfFile() {} // Define a unique number for the abbreviation. // -void DwarfFile::assignAbbrevNumber(DIEAbbrev &Abbrev) { - // Check the set for priors. - DIEAbbrev *InSet = AbbreviationsSet.GetOrInsertNode(&Abbrev); - - // If it's newly added. - if (InSet == &Abbrev) { - // Add to abbreviation list. - Abbreviations.push_back(&Abbrev); - - // Assign the vector position + 1 as its number. - Abbrev.setNumber(Abbreviations.size()); - } else { - // Assign existing abbreviation number. - Abbrev.setNumber(InSet->getNumber()); +DIEAbbrev &DwarfFile::assignAbbrevNumber(DIE &Die) { + FoldingSetNodeID ID; + DIEAbbrev Abbrev = Die.generateAbbrev(); + Abbrev.Profile(ID); + + void *InsertPos; + if (DIEAbbrev *Existing = + AbbreviationsSet.FindNodeOrInsertPos(ID, InsertPos)) { + Die.setAbbrevNumber(Existing->getNumber()); + return *Existing; } + + // Move the abbreviation to the heap and assign a number. + DIEAbbrev *New = new (AbbrevAllocator) DIEAbbrev(std::move(Abbrev)); + Abbreviations.push_back(New); + New->setNumber(Abbreviations.size()); + Die.setAbbrevNumber(Abbreviations.size()); + + // Store it for lookup. + AbbreviationsSet.InsertNode(New, InsertPos); + return *New; } void DwarfFile::addUnit(std::unique_ptr U) { @@ -83,10 +89,7 @@ void DwarfFile::computeSizeAndOffsets() { // CU. It returns the offset after laying out the DIE. unsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) { // Record the abbreviation. - assignAbbrevNumber(Die.getAbbrev()); - - // Get the abbreviation for this DIE. - const DIEAbbrev &Abbrev = Die.getAbbrev(); + const DIEAbbrev &Abbrev = assignAbbrevNumber(Die); // Set DIE offset Die.setOffset(Offset); diff --git a/lib/CodeGen/AsmPrinter/DwarfFile.h b/lib/CodeGen/AsmPrinter/DwarfFile.h index 532ed96c268..8402027edd6 100644 --- a/lib/CodeGen/AsmPrinter/DwarfFile.h +++ b/lib/CodeGen/AsmPrinter/DwarfFile.h @@ -37,6 +37,8 @@ class DwarfFile { // Target of Dwarf emission, used for sizing of abbreviations. AsmPrinter *Asm; + BumpPtrAllocator AbbrevAllocator; + // Used to uniquely define abbreviations. FoldingSet AbbreviationsSet; @@ -72,8 +74,11 @@ public: /// \brief Compute the size and offset of all the DIEs. void computeSizeAndOffsets(); - /// \brief Define a unique number for the abbreviation. - void assignAbbrevNumber(DIEAbbrev &Abbrev); + /// Define a unique number for the abbreviation. + /// + /// Compute the abbreviation for \c Die, look up its unique number, and + /// return a reference to it in the uniquing table. + DIEAbbrev &assignAbbrevNumber(DIE &Die); /// \brief Add a unit to the list of CUs. void addUnit(std::unique_ptr U); diff --git a/tools/dsymutil/DwarfLinker.cpp b/tools/dsymutil/DwarfLinker.cpp index e5079005c00..4e5cb735122 100644 --- a/tools/dsymutil/DwarfLinker.cpp +++ b/tools/dsymutil/DwarfLinker.cpp @@ -72,8 +72,10 @@ struct PatchLocation { void set(uint64_t New) const { assert(Die); assert(Index < Die->getValues().size()); - assert(Die->getValues()[Index].getType() == DIEValue::isInteger); - Die->setValue(Index, DIEInteger(New)); + const auto &Old = Die->getValues()[Index]; + assert(Old.getType() == DIEValue::isInteger); + Die->setValue(Index, + DIEValue(Old.getAttribute(), Old.getForm(), DIEInteger(New))); } uint64_t get() const { @@ -1869,7 +1871,13 @@ unsigned DwarfLinker::cloneBlockAttribute(DIE &Die, AttributeSpec AttrSpec, DIEBlocks.push_back(Block); } Attr = Loc ? static_cast(Loc) : static_cast(Block); - Value = Loc ? DIEValue(Loc) : DIEValue(Block); + + if (Loc) + Value = DIEValue(dwarf::Attribute(AttrSpec.Attr), + dwarf::Form(AttrSpec.Form), Loc); + else + Value = DIEValue(dwarf::Attribute(AttrSpec.Attr), + dwarf::Form(AttrSpec.Form), Block); ArrayRef Bytes = *Val.getAsBlock(); for (auto Byte : Bytes) Attr->addValue(static_cast(0), dwarf::DW_FORM_data1, @@ -1883,8 +1891,7 @@ unsigned DwarfLinker::cloneBlockAttribute(DIE &Die, AttributeSpec AttrSpec, else Block->ComputeSize(&Streamer->getAsmPrinter()); } - Die.addValue(dwarf::Attribute(AttrSpec.Attr), dwarf::Form(AttrSpec.Form), - Value); + Die.addValue(Value); return AttrSize; } @@ -2183,14 +2190,15 @@ DIE *DwarfLinker::cloneDIE(const DWARFDebugInfoEntryMinimal &InputDIE, Unit.addTypeAccelerator(Die, AttrInfo.Name, AttrInfo.NameOffset); } - DIEAbbrev &NewAbbrev = Die->getAbbrev(); + DIEAbbrev NewAbbrev = Die->generateAbbrev(); // If a scope DIE is kept, we must have kept at least one child. If // it's not the case, we'll just be emitting one wasteful end of // children marker, but things won't break. if (InputDIE.hasChildren()) NewAbbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes); // Assign a permanent abbrev number - AssignAbbrev(Die->getAbbrev()); + AssignAbbrev(NewAbbrev); + Die->setAbbrevNumber(NewAbbrev.getNumber()); // Add the size of the abbreviation number to the output offset. OutOffset += getULEB128Size(Die->getAbbrevNumber()); @@ -2321,14 +2329,15 @@ void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit, // Update the cloned DW_AT_stmt_list with the correct debug_line offset. if (auto *OutputDIE = Unit.getOutputUnitDIE()) { - const auto &Abbrev = OutputDIE->getAbbrev().getData(); - auto Stmt = std::find_if( - Abbrev.begin(), Abbrev.end(), [](const DIEAbbrevData &AbbrevData) { - return AbbrevData.getAttribute() == dwarf::DW_AT_stmt_list; + const auto &Values = OutputDIE->getValues(); + auto Stmt = + std::find_if(Values.begin(), Values.end(), [](const DIEValue &Value) { + return Value.getAttribute() == dwarf::DW_AT_stmt_list; }); - assert(Stmt < Abbrev.end() && "Didn't find DW_AT_stmt_list in cloned DIE!"); - OutputDIE->setValue(Stmt - Abbrev.begin(), - DIEInteger(Streamer->getLineSectionSize())); + assert(Stmt < Values.end() && "Didn't find DW_AT_stmt_list in cloned DIE!"); + OutputDIE->setValue(Stmt - Values.begin(), + DIEValue(Stmt->getAttribute(), Stmt->getForm(), + DIEInteger(Streamer->getLineSectionSize()))); } // Parse the original line info for the unit.