LLVM  8.0.1
DebugLocStream.h
Go to the documentation of this file.
1 //===--- lib/CodeGen/DebugLocStream.h - DWARF debug_loc stream --*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCSTREAM_H
11 #define LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCSTREAM_H
12 
13 #include "ByteStreamer.h"
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/ADT/SmallVector.h"
16 
17 namespace llvm {
18 
19 class AsmPrinter;
20 class DbgVariable;
21 class DwarfCompileUnit;
22 class MachineInstr;
23 class MCSymbol;
24 
25 /// Byte stream of .debug_loc entries.
26 ///
27 /// Stores a unified stream of .debug_loc entries. There's \a List for each
28 /// variable/inlined-at pair, and an \a Entry for each \a DebugLocEntry.
29 ///
30 /// FIXME: Do we need all these temp symbols?
31 /// FIXME: Why not output directly to the output stream?
33 public:
34  struct List {
36  MCSymbol *Label = nullptr;
37  size_t EntryOffset;
38  List(DwarfCompileUnit *CU, size_t EntryOffset)
39  : CU(CU), EntryOffset(EntryOffset) {}
40  };
41  struct Entry {
43  const MCSymbol *EndSym;
44  size_t ByteOffset;
45  size_t CommentOffset;
46  Entry(const MCSymbol *BeginSym, const MCSymbol *EndSym, size_t ByteOffset,
47  size_t CommentOffset)
48  : BeginSym(BeginSym), EndSym(EndSym), ByteOffset(ByteOffset),
49  CommentOffset(CommentOffset) {}
50  };
51 
52 private:
54  SmallVector<Entry, 32> Entries;
55  SmallString<256> DWARFBytes;
57 
58  /// Only verbose textual output needs comments. This will be set to
59  /// true for that case, and false otherwise.
60  bool GenerateComments;
61 
62 public:
63  DebugLocStream(bool GenerateComments) : GenerateComments(GenerateComments) { }
64  size_t getNumLists() const { return Lists.size(); }
65  const List &getList(size_t LI) const { return Lists[LI]; }
66  ArrayRef<List> getLists() const { return Lists; }
67 
68  class ListBuilder;
69  class EntryBuilder;
70 
71 private:
72  /// Start a new .debug_loc entry list.
73  ///
74  /// Start a new .debug_loc entry list. Return the new list's index so it can
75  /// be retrieved later via \a getList().
76  ///
77  /// Until the next call, \a startEntry() will add entries to this list.
78  size_t startList(DwarfCompileUnit *CU) {
79  size_t LI = Lists.size();
80  Lists.emplace_back(CU, Entries.size());
81  return LI;
82  }
83 
84  /// Finalize a .debug_loc entry list.
85  ///
86  /// If there are no entries in this list, delete it outright. Otherwise,
87  /// create a label with \a Asm.
88  ///
89  /// \return false iff the list is deleted.
90  bool finalizeList(AsmPrinter &Asm);
91 
92  /// Start a new .debug_loc entry.
93  ///
94  /// Until the next call, bytes added to the stream will be added to this
95  /// entry.
96  void startEntry(const MCSymbol *BeginSym, const MCSymbol *EndSym) {
97  Entries.emplace_back(BeginSym, EndSym, DWARFBytes.size(), Comments.size());
98  }
99 
100  /// Finalize a .debug_loc entry, deleting if it's empty.
101  void finalizeEntry();
102 
103 public:
105  return BufferByteStreamer(DWARFBytes, Comments, GenerateComments);
106  }
107 
108  ArrayRef<Entry> getEntries(const List &L) const {
109  size_t LI = getIndex(L);
110  return makeArrayRef(Entries)
111  .slice(Lists[LI].EntryOffset, getNumEntries(LI));
112  }
113 
114  ArrayRef<char> getBytes(const Entry &E) const {
115  size_t EI = getIndex(E);
116  return makeArrayRef(DWARFBytes.begin(), DWARFBytes.end())
117  .slice(Entries[EI].ByteOffset, getNumBytes(EI));
118  }
120  size_t EI = getIndex(E);
121  return makeArrayRef(Comments)
122  .slice(Entries[EI].CommentOffset, getNumComments(EI));
123  }
124 
125 private:
126  size_t getIndex(const List &L) const {
127  assert(&Lists.front() <= &L && &L <= &Lists.back() &&
128  "Expected valid list");
129  return &L - &Lists.front();
130  }
131  size_t getIndex(const Entry &E) const {
132  assert(&Entries.front() <= &E && &E <= &Entries.back() &&
133  "Expected valid entry");
134  return &E - &Entries.front();
135  }
136  size_t getNumEntries(size_t LI) const {
137  if (LI + 1 == Lists.size())
138  return Entries.size() - Lists[LI].EntryOffset;
139  return Lists[LI + 1].EntryOffset - Lists[LI].EntryOffset;
140  }
141  size_t getNumBytes(size_t EI) const {
142  if (EI + 1 == Entries.size())
143  return DWARFBytes.size() - Entries[EI].ByteOffset;
144  return Entries[EI + 1].ByteOffset - Entries[EI].ByteOffset;
145  }
146  size_t getNumComments(size_t EI) const {
147  if (EI + 1 == Entries.size())
148  return Comments.size() - Entries[EI].CommentOffset;
149  return Entries[EI + 1].CommentOffset - Entries[EI].CommentOffset;
150  }
151 };
152 
153 /// Builder for DebugLocStream lists.
155  DebugLocStream &Locs;
156  AsmPrinter &Asm;
157  DbgVariable &V;
158  const MachineInstr &MI;
159  size_t ListIndex;
160 
161 public:
163  DbgVariable &V, const MachineInstr &MI)
164  : Locs(Locs), Asm(Asm), V(V), MI(MI), ListIndex(Locs.startList(&CU)) {}
165 
166  /// Finalize the list.
167  ///
168  /// If the list is empty, delete it. Otherwise, finalize it by creating a
169  /// temp symbol in \a Asm and setting up the \a DbgVariable.
170  ~ListBuilder();
171 
172  DebugLocStream &getLocs() { return Locs; }
173 };
174 
175 /// Builder for DebugLocStream entries.
177  DebugLocStream &Locs;
178 
179 public:
180  EntryBuilder(ListBuilder &List, const MCSymbol *Begin, const MCSymbol *End)
181  : Locs(List.getLocs()) {
182  Locs.startEntry(Begin, End);
183  }
184 
185  /// Finalize the entry, deleting it if it's empty.
186  ~EntryBuilder() { Locs.finalizeEntry(); }
187 
189 };
190 
191 } // namespace llvm
192 
193 #endif
Builder for DebugLocStream lists.
EntryBuilder(ListBuilder &List, const MCSymbol *Begin, const MCSymbol *End)
This class represents lattice values for constants.
Definition: AllocatorList.h:24
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
ListBuilder(DebugLocStream &Locs, DwarfCompileUnit &CU, AsmPrinter &Asm, DbgVariable &V, const MachineInstr &MI)
DebugLocStream(bool GenerateComments)
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:451
This class is used to track local variable information.
Definition: DwarfDebug.h:117
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
BufferByteStreamer getStreamer()
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
Definition: SmallVector.h:129
ArrayRef< char > getBytes(const Entry &E) const
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:79
ArrayRef< Entry > getEntries(const List &L) const
size_t size() const
Definition: SmallVector.h:53
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
~EntryBuilder()
Finalize the entry, deleting it if it&#39;s empty.
Entry(const MCSymbol *BeginSym, const MCSymbol *EndSym, size_t ByteOffset, size_t CommentOffset)
static const SCEV * getNumBytes(const SCEV *BECount, Type *IntPtr, unsigned StoreSize, Loop *CurLoop, const DataLayout *DL, ScalarEvolution *SE)
Compute the number of bytes as a SCEV from the backedge taken count.
const List & getList(size_t LI) const
ArrayRef< std::string > getComments(const Entry &E) const
DwarfCompileUnit * CU
Representation of each machine instruction.
Definition: MachineInstr.h:64
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:133
void emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:652
size_t getNumLists() const
List(DwarfCompileUnit *CU, size_t EntryOffset)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
IRTranslator LLVM IR MI
Byte stream of .debug_loc entries.
Builder for DebugLocStream entries.
ArrayRef< List > getLists() const