diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp index 1a706f7f0d1..bb4cf660cef 100644 --- a/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/lib/CodeGen/AsmPrinter/DIE.cpp @@ -561,7 +561,7 @@ unsigned DIELocList::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { /// void DIELocList::EmitValue(const AsmPrinter *AP, dwarf::Form Form) const { DwarfDebug *DD = AP->getDwarfDebug(); - MCSymbol *Label = DD->getDebugLocEntries()[Index].Label; + MCSymbol *Label = DD->getDebugLocs().getList(Index).Label; if (AP->MAI->doesDwarfUseRelocationsAcrossSections() && !DD->useSplitDwarf()) AP->emitSectionOffset(Label); diff --git a/lib/CodeGen/AsmPrinter/DIEHash.cpp b/lib/CodeGen/AsmPrinter/DIEHash.cpp index da7252ade7d..a2e5aad9657 100644 --- a/lib/CodeGen/AsmPrinter/DIEHash.cpp +++ b/lib/CodeGen/AsmPrinter/DIEHash.cpp @@ -285,8 +285,8 @@ void DIEHash::hashBlockData(const SmallVectorImpl &Values) { void DIEHash::hashLocList(const DIELocList &LocList) { HashingByteStreamer Streamer(*this); DwarfDebug &DD = *AP->getDwarfDebug(); - for (const auto &Entry : - DD.getDebugLocEntries()[LocList.getValue()].List) + const DebugLocStream &Locs = DD.getDebugLocs(); + for (const auto &Entry : Locs.getEntries(Locs.getList(LocList.getValue()))) DD.emitDebugLocEntry(Streamer, Entry); } diff --git a/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/lib/CodeGen/AsmPrinter/DebugLocEntry.h index cd3584ecb57..a2f6ae1eb73 100644 --- a/lib/CodeGen/AsmPrinter/DebugLocEntry.h +++ b/lib/CodeGen/AsmPrinter/DebugLocEntry.h @@ -17,6 +17,7 @@ namespace llvm { class AsmPrinter; +class DebugLocStream; /// \brief This struct describes location entries emitted in the .debug_loc /// section. @@ -80,8 +81,6 @@ private: /// A nonempty list of locations/constants belonging to this entry, /// sorted by offset. SmallVector Values; - SmallString<8> DWARFBytes; - SmallVector Comments; public: DebugLocEntry(const MCSymbol *B, const MCSymbol *E, Value Val) @@ -144,12 +143,8 @@ public: } /// \brief Lower this entry into a DWARF expression. - void finalize(const AsmPrinter &AP, const MDBasicType *TypeIdentifierMap); - - /// \brief Return the lowered DWARF expression. - StringRef getDWARFBytes() const { return DWARFBytes; } - /// \brief Return the assembler comments for the lowered DWARF expression. - const SmallVectorImpl &getComments() const { return Comments; } + void finalize(const AsmPrinter &AP, DebugLocStream &Locs, + const MDBasicType *BT); }; /// \brief Compare two Values for equality. diff --git a/lib/CodeGen/AsmPrinter/DebugLocList.h b/lib/CodeGen/AsmPrinter/DebugLocList.h deleted file mode 100644 index 0f1d2edd425..00000000000 --- a/lib/CodeGen/AsmPrinter/DebugLocList.h +++ /dev/null @@ -1,25 +0,0 @@ -//===--- lib/CodeGen/DebugLocList.h - DWARF debug_loc list ------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCLIST_H -#define LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCLIST_H - -#include "DebugLocEntry.h" -#include "llvm/ADT/SmallVector.h" - -namespace llvm { -class DwarfCompileUnit; -class MCSymbol; -struct DebugLocList { - MCSymbol *Label; - DwarfCompileUnit *CU; - SmallVector List; -}; -} -#endif diff --git a/lib/CodeGen/AsmPrinter/DebugLocStream.h b/lib/CodeGen/AsmPrinter/DebugLocStream.h new file mode 100644 index 00000000000..818ea626bb2 --- /dev/null +++ b/lib/CodeGen/AsmPrinter/DebugLocStream.h @@ -0,0 +1,129 @@ +//===--- lib/CodeGen/DebugLocStream.h - DWARF debug_loc stream --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCSTREAM_H +#define LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCSTREAM_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" +#include "ByteStreamer.h" + +namespace llvm { +class DwarfCompileUnit; +class MCSymbol; + +/// \brief Byte stream of .debug_loc entries. +/// +/// Stores a unified stream of .debug_loc entries. There's \a List for each +/// variable/inlined-at pair, and an \a Entry for each \a DebugLocEntry. +/// +/// FIXME: Why do we have comments even when it's an object stream? +/// FIXME: Do we need all these temp symbols? +/// FIXME: Why not output directly to the output stream? +class DebugLocStream { +public: + struct List { + DwarfCompileUnit *CU; + MCSymbol *Label; + size_t EntryOffset; + List(DwarfCompileUnit *CU, MCSymbol *Label, size_t EntryOffset) + : CU(CU), Label(Label), EntryOffset(EntryOffset) {} + }; + struct Entry { + const MCSymbol *BeginSym; + const MCSymbol *EndSym; + size_t ByteOffset; + size_t CommentOffset; + Entry(const MCSymbol *BeginSym, const MCSymbol *EndSym, size_t ByteOffset, + size_t CommentOffset) + : BeginSym(BeginSym), EndSym(EndSym), ByteOffset(ByteOffset), + CommentOffset(CommentOffset) {} + }; + +private: + SmallVector Lists; + SmallVector Entries; + SmallString<256> DWARFBytes; + SmallVector Comments; + +public: + size_t getNumLists() const { return Lists.size(); } + const List &getList(size_t LI) const { return Lists[LI]; } + ArrayRef getLists() const { return Lists; } + + /// \brief Start a new .debug_loc entry list. + /// + /// Start a new .debug_loc entry list. Return the new list's index so it can + /// be retrieved later via \a getList(). + /// + /// Until the next call, \a startEntry() will add entries to this list. + size_t startList(DwarfCompileUnit *CU, MCSymbol *Label) { + size_t LI = Lists.size(); + Lists.emplace_back(CU, Label, Entries.size()); + return LI; + } + + /// \brief Start a new .debug_loc entry. + /// + /// Until the next call, bytes added to the stream will be added to this + /// entry. + void startEntry(const MCSymbol *BeginSym, const MCSymbol *EndSym) { + Entries.emplace_back(BeginSym, EndSym, DWARFBytes.size(), Comments.size()); + } + + BufferByteStreamer getStreamer() { + return BufferByteStreamer(DWARFBytes, Comments); + } + + ArrayRef getEntries(const List &L) const { + size_t LI = getIndex(L); + return makeArrayRef(Entries) + .slice(Lists[LI].EntryOffset, getNumEntries(LI)); + } + + ArrayRef getBytes(const Entry &E) const { + size_t EI = getIndex(E); + return makeArrayRef(DWARFBytes.begin(), DWARFBytes.end()) + .slice(Entries[EI].ByteOffset, getNumBytes(EI)); + } + ArrayRef getComments(const Entry &E) const { + size_t EI = getIndex(E); + return makeArrayRef(Comments) + .slice(Entries[EI].CommentOffset, getNumComments(EI)); + } + +private: + size_t getIndex(const List &L) const { + assert(&Lists.front() <= &L && &L <= &Lists.back() && + "Expected valid list"); + return &L - &Lists.front(); + } + size_t getIndex(const Entry &E) const { + assert(&Entries.front() <= &E && &E <= &Entries.back() && + "Expected valid entry"); + return &E - &Entries.front(); + } + size_t getNumEntries(size_t LI) const { + if (LI + 1 == Lists.size()) + return Entries.size() - Lists[LI].EntryOffset; + return Lists[LI + 1].EntryOffset - Lists[LI].EntryOffset; + } + size_t getNumBytes(size_t EI) const { + if (EI + 1 == Entries.size()) + return DWARFBytes.size() - Entries[EI].ByteOffset; + return Entries[EI + 1].ByteOffset - Entries[EI].ByteOffset; + } + size_t getNumComments(size_t EI) const { + if (EI + 1 == Entries.size()) + return Comments.size() - Entries[EI].CommentOffset; + return Entries[EI + 1].CommentOffset - Entries[EI].CommentOffset; + } +}; +} +#endif diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 75d3b68ed3f..c4409aa78a3 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -1,6 +1,7 @@ #include "DwarfCompileUnit.h" #include "DwarfExpression.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/GlobalVariable.h" @@ -480,7 +481,7 @@ DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV, // Add variable address. - unsigned Offset = DV.getDotDebugLocOffset(); + unsigned Offset = DV.getDebugLocListIndex(); if (Offset != ~0U) { addLocationList(*VariableDie, dwarf::DW_AT_location, Offset); return VariableDie; diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index e53f5743231..0336b946e85 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -14,6 +14,7 @@ #include "DwarfDebug.h" #include "ByteStreamer.h" #include "DIEHash.h" +#include "DebugLocEntry.h" #include "DwarfCompileUnit.h" #include "DwarfExpression.h" #include "DwarfUnit.h" @@ -910,15 +911,12 @@ void DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU, DISubprogram SP, continue; // Handle multiple DBG_VALUE instructions describing one variable. - RegVar->setDotDebugLocOffset(DotDebugLocEntries.size()); - - DotDebugLocEntries.resize(DotDebugLocEntries.size() + 1); - DebugLocList &LocList = DotDebugLocEntries.back(); - LocList.CU = &TheCU; - LocList.Label = Asm->createTempSymbol("debug_loc"); + RegVar->setDebugLocListIndex( + DebugLocs.startList(&TheCU, Asm->createTempSymbol("debug_loc"))); // Build the location list for this variable. - buildLocationList(LocList.List, Ranges); + SmallVector Entries; + buildLocationList(Entries, Ranges); // If the variable has an MDBasicType, extract it. Basic types cannot have // unique identifiers, so don't bother resolving the type with the @@ -927,8 +925,8 @@ void DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU, DISubprogram SP, static_cast(IV.first->getType())); // Finalize the entry by lowering it into a DWARF bytestream. - for (auto &Entry : LocList.List) - Entry.finalize(*Asm, BT); + for (auto &Entry : Entries) + Entry.finalize(*Asm, DebugLocs, BT); } // Collect info for variables that were optimized out. @@ -1465,12 +1463,12 @@ void DwarfDebug::emitDebugStr() { Holder.emitStrings(Asm->getObjFileLowering().getDwarfStrSection()); } - void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer, - const DebugLocEntry &Entry) { - auto Comment = Entry.getComments().begin(); - auto End = Entry.getComments().end(); - for (uint8_t Byte : Entry.getDWARFBytes()) + const DebugLocStream::Entry &Entry) { + auto &&Comments = DebugLocs.getComments(Entry); + auto Comment = Comments.begin(); + auto End = Comments.end(); + for (uint8_t Byte : DebugLocs.getBytes(Entry)) Streamer.EmitInt8(Byte, Comment != End ? *(Comment++) : ""); } @@ -1510,9 +1508,11 @@ static void emitDebugLocValue(const AsmPrinter &AP, const MDBasicType *BT, // FIXME: ^ } -void DebugLocEntry::finalize(const AsmPrinter &AP, const MDBasicType *BT) { - BufferByteStreamer Streamer(DWARFBytes, Comments); - const DebugLocEntry::Value Value = Values[0]; +void DebugLocEntry::finalize(const AsmPrinter &AP, DebugLocStream &Locs, + const MDBasicType *BT) { + Locs.startEntry(Begin, End); + BufferByteStreamer Streamer = Locs.getStreamer(); + const DebugLocEntry::Value &Value = Values[0]; if (Value.isBitPiece()) { // Emit all pieces that belong to the same variable and range. assert(std::all_of(Values.begin(), Values.end(), [](DebugLocEntry::Value P) { @@ -1545,8 +1545,7 @@ void DebugLocEntry::finalize(const AsmPrinter &AP, const MDBasicType *BT) { } } - -void DwarfDebug::emitDebugLocEntryLocation(const DebugLocEntry &Entry) { +void DwarfDebug::emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry) { Asm->OutStreamer.AddComment("Loc expr size"); MCSymbol *begin = Asm->OutStreamer.getContext().CreateTempSymbol(); MCSymbol *end = Asm->OutStreamer.getContext().CreateTempSymbol(); @@ -1565,19 +1564,19 @@ void DwarfDebug::emitDebugLoc() { Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfLocSection()); unsigned char Size = Asm->getDataLayout().getPointerSize(); - for (const auto &DebugLoc : DotDebugLocEntries) { - Asm->OutStreamer.EmitLabel(DebugLoc.Label); - const DwarfCompileUnit *CU = DebugLoc.CU; - for (const auto &Entry : DebugLoc.List) { + for (const auto &List : DebugLocs.getLists()) { + Asm->OutStreamer.EmitLabel(List.Label); + const DwarfCompileUnit *CU = List.CU; + for (const auto &Entry : DebugLocs.getEntries(List)) { // Set up the range. This range is relative to the entry point of the // compile unit. This is a hard coded 0 for low_pc when we're emitting // ranges, or the DW_AT_low_pc on the compile unit otherwise. if (auto *Base = CU->getBaseAddress()) { - Asm->EmitLabelDifference(Entry.getBeginSym(), Base, Size); - Asm->EmitLabelDifference(Entry.getEndSym(), Base, Size); + Asm->EmitLabelDifference(Entry.BeginSym, Base, Size); + Asm->EmitLabelDifference(Entry.EndSym, Base, Size); } else { - Asm->OutStreamer.EmitSymbolValue(Entry.getBeginSym(), Size); - Asm->OutStreamer.EmitSymbolValue(Entry.getEndSym(), Size); + Asm->OutStreamer.EmitSymbolValue(Entry.BeginSym, Size); + Asm->OutStreamer.EmitSymbolValue(Entry.EndSym, Size); } emitDebugLocEntryLocation(Entry); @@ -1590,17 +1589,17 @@ void DwarfDebug::emitDebugLoc() { void DwarfDebug::emitDebugLocDWO() { Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfLocDWOSection()); - for (const auto &DebugLoc : DotDebugLocEntries) { - Asm->OutStreamer.EmitLabel(DebugLoc.Label); - for (const auto &Entry : DebugLoc.List) { + for (const auto &List : DebugLocs.getLists()) { + Asm->OutStreamer.EmitLabel(List.Label); + for (const auto &Entry : DebugLocs.getEntries(List)) { // Just always use start_length for now - at least that's one address // rather than two. We could get fancier and try to, say, reuse an // address we know we've emitted elsewhere (the start of the function? // The start of the CU or CU subrange that encloses this range?) Asm->EmitInt8(dwarf::DW_LLE_start_length_entry); - unsigned idx = AddrPool.getIndex(Entry.getBeginSym()); + unsigned idx = AddrPool.getIndex(Entry.BeginSym); Asm->EmitULEB128(idx); - Asm->EmitLabelDifference(Entry.getEndSym(), Entry.getBeginSym(), 4); + Asm->EmitLabelDifference(Entry.EndSym, Entry.BeginSym, 4); emitDebugLocEntryLocation(Entry); } diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index 2b0ad3d8b45..4b0506f4c10 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -16,8 +16,7 @@ #include "AsmPrinterHandler.h" #include "DbgValueHistoryCalculator.h" -#include "DebugLocEntry.h" -#include "DebugLocList.h" +#include "DebugLocStream.h" #include "DwarfAccelTable.h" #include "DwarfFile.h" #include "llvm/ADT/DenseMap.h" @@ -42,6 +41,7 @@ class AsmPrinter; class ByteStreamer; class ConstantInt; class ConstantFP; +class DebugLocEntry; class DwarfCompileUnit; class DwarfDebug; class DwarfTypeUnit; @@ -69,7 +69,7 @@ public: //===----------------------------------------------------------------------===// /// \brief This class is used to track local variable information. /// -/// - Variables whose location changes over time have a DotDebugLocOffset and +/// - Variables whose location changes over time have a DebugLocListIndex and /// the other fields are not used. /// /// - Variables that are described by multiple MMI table entries have multiple @@ -79,7 +79,7 @@ class DbgVariable { DILocation IA; /// Inlined at location. SmallVector Expr; /// Complex address location expression. DIE *TheDIE; /// Variable DIE. - unsigned DotDebugLocOffset; /// Offset in DotDebugLocEntries. + unsigned DebugLocListIndex; /// Offset in DebugLocs. const MachineInstr *MInsn; /// DBG_VALUE instruction of the variable. SmallVector FrameIndex; /// Frame index of the variable. DwarfDebug *DD; @@ -88,7 +88,7 @@ public: /// Construct a DbgVariable from a DIVariable. DbgVariable(DIVariable V, DILocation IA, DIExpression E, DwarfDebug *DD, int FI = ~0) - : Var(V), IA(IA), Expr(1, E), TheDIE(nullptr), DotDebugLocOffset(~0U), + : Var(V), IA(IA), Expr(1, E), TheDIE(nullptr), DebugLocListIndex(~0U), MInsn(nullptr), DD(DD) { FrameIndex.push_back(FI); assert(!E || E->isValid()); @@ -100,7 +100,7 @@ public: : Var(DbgValue->getDebugVariable()), IA(DbgValue->getDebugLoc()->getInlinedAt()), Expr(1, DbgValue->getDebugExpression()), TheDIE(nullptr), - DotDebugLocOffset(~0U), MInsn(DbgValue), DD(DD) { + DebugLocListIndex(~0U), MInsn(DbgValue), DD(DD) { FrameIndex.push_back(~0); } @@ -110,15 +110,15 @@ public: const ArrayRef getExpression() const { return Expr; } void setDIE(DIE &D) { TheDIE = &D; } DIE *getDIE() const { return TheDIE; } - void setDotDebugLocOffset(unsigned O) { DotDebugLocOffset = O; } - unsigned getDotDebugLocOffset() const { return DotDebugLocOffset; } + void setDebugLocListIndex(unsigned O) { DebugLocListIndex = O; } + unsigned getDebugLocListIndex() const { return DebugLocListIndex; } StringRef getName() const { return Var->getName(); } const MachineInstr *getMInsn() const { return MInsn; } const ArrayRef getFrameIndex() const { return FrameIndex; } void addMMIEntry(const DbgVariable &V) { - assert( DotDebugLocOffset == ~0U && !MInsn && "not an MMI entry"); - assert(V.DotDebugLocOffset == ~0U && !V.MInsn && "not an MMI entry"); + assert(DebugLocListIndex == ~0U && !MInsn && "not an MMI entry"); + assert(V.DebugLocListIndex == ~0U && !V.MInsn && "not an MMI entry"); assert(V.Var == Var && "conflicting DIVariable"); assert(V.IA == IA && "conflicting inlined-at location"); @@ -215,7 +215,7 @@ class DwarfDebug : public AsmPrinterHandler { // Collection of DebugLocEntry. Stored in a linked list so that DIELocLists // can refer to them in spite of insertions into this list. - SmallVector DotDebugLocEntries; + DebugLocStream DebugLocs; // This is a collection of subprogram MDNodes that are processed to // create DIEs. @@ -552,18 +552,15 @@ public: void setPrevCU(const DwarfCompileUnit *PrevCU) { this->PrevCU = PrevCU; } /// Returns the entries for the .debug_loc section. - const SmallVectorImpl & - getDebugLocEntries() const { - return DotDebugLocEntries; - } + const DebugLocStream &getDebugLocs() const { return DebugLocs; } /// \brief Emit an entry for the debug loc section. This can be used to /// handle an entry that's going to be emitted into the debug loc section. void emitDebugLocEntry(ByteStreamer &Streamer, - const DebugLocEntry &Entry); + const DebugLocStream::Entry &Entry); /// Emit the location for a debug loc entry, including the size header. - void emitDebugLocEntryLocation(const DebugLocEntry &Entry); + void emitDebugLocEntryLocation(const DebugLocStream::Entry &Entry); /// Find the MDNode for the given reference. template T *resolve(TypedDebugNodeRef Ref) const {