DebugLocEntry.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. //===-- llvm/CodeGen/DebugLocEntry.h - Entry in debug_loc list -*- C++ -*--===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCENTRY_H
  9. #define LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCENTRY_H
  10. #include "DebugLocStream.h"
  11. #include "llvm/Config/llvm-config.h"
  12. #include "llvm/IR/Constants.h"
  13. #include "llvm/IR/DebugInfo.h"
  14. #include "llvm/MC/MCSymbol.h"
  15. #include "llvm/MC/MachineLocation.h"
  16. #include "llvm/Support/Debug.h"
  17. namespace llvm {
  18. class AsmPrinter;
  19. /// A single location or constant.
  20. class DbgValueLoc {
  21. /// Any complex address location expression for this DbgValueLoc.
  22. const DIExpression *Expression;
  23. /// Type of entry that this represents.
  24. enum EntryType { E_Location, E_Integer, E_ConstantFP, E_ConstantInt };
  25. enum EntryType EntryKind;
  26. /// Either a constant,
  27. union {
  28. int64_t Int;
  29. const ConstantFP *CFP;
  30. const ConstantInt *CIP;
  31. } Constant;
  32. /// Or a location in the machine frame.
  33. MachineLocation Loc;
  34. public:
  35. DbgValueLoc(const DIExpression *Expr, int64_t i)
  36. : Expression(Expr), EntryKind(E_Integer) {
  37. Constant.Int = i;
  38. }
  39. DbgValueLoc(const DIExpression *Expr, const ConstantFP *CFP)
  40. : Expression(Expr), EntryKind(E_ConstantFP) {
  41. Constant.CFP = CFP;
  42. }
  43. DbgValueLoc(const DIExpression *Expr, const ConstantInt *CIP)
  44. : Expression(Expr), EntryKind(E_ConstantInt) {
  45. Constant.CIP = CIP;
  46. }
  47. DbgValueLoc(const DIExpression *Expr, MachineLocation Loc)
  48. : Expression(Expr), EntryKind(E_Location), Loc(Loc) {
  49. assert(cast<DIExpression>(Expr)->isValid());
  50. }
  51. bool isLocation() const { return EntryKind == E_Location; }
  52. bool isInt() const { return EntryKind == E_Integer; }
  53. bool isConstantFP() const { return EntryKind == E_ConstantFP; }
  54. bool isConstantInt() const { return EntryKind == E_ConstantInt; }
  55. int64_t getInt() const { return Constant.Int; }
  56. const ConstantFP *getConstantFP() const { return Constant.CFP; }
  57. const ConstantInt *getConstantInt() const { return Constant.CIP; }
  58. MachineLocation getLoc() const { return Loc; }
  59. bool isFragment() const { return getExpression()->isFragment(); }
  60. bool isEntryVal() const { return getExpression()->isEntryValue(); }
  61. const DIExpression *getExpression() const { return Expression; }
  62. friend bool operator==(const DbgValueLoc &, const DbgValueLoc &);
  63. friend bool operator<(const DbgValueLoc &, const DbgValueLoc &);
  64. #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
  65. LLVM_DUMP_METHOD void dump() const {
  66. if (isLocation()) {
  67. llvm::dbgs() << "Loc = { reg=" << Loc.getReg() << " ";
  68. if (Loc.isIndirect())
  69. llvm::dbgs() << "+0";
  70. llvm::dbgs() << "} ";
  71. } else if (isConstantInt())
  72. Constant.CIP->dump();
  73. else if (isConstantFP())
  74. Constant.CFP->dump();
  75. if (Expression)
  76. Expression->dump();
  77. }
  78. #endif
  79. };
  80. /// This struct describes location entries emitted in the .debug_loc
  81. /// section.
  82. class DebugLocEntry {
  83. /// Begin and end symbols for the address range that this location is valid.
  84. const MCSymbol *Begin;
  85. const MCSymbol *End;
  86. /// A nonempty list of locations/constants belonging to this entry,
  87. /// sorted by offset.
  88. SmallVector<DbgValueLoc, 1> Values;
  89. public:
  90. /// Create a location list entry for the range [\p Begin, \p End).
  91. ///
  92. /// \param Vals One or more values describing (parts of) the variable.
  93. DebugLocEntry(const MCSymbol *Begin, const MCSymbol *End,
  94. ArrayRef<DbgValueLoc> Vals)
  95. : Begin(Begin), End(End) {
  96. addValues(Vals);
  97. }
  98. /// Attempt to merge this DebugLocEntry with Next and return
  99. /// true if the merge was successful. Entries can be merged if they
  100. /// share the same Loc/Constant and if Next immediately follows this
  101. /// Entry.
  102. bool MergeRanges(const DebugLocEntry &Next) {
  103. // If this and Next are describing the same variable, merge them.
  104. if ((End == Next.Begin && Values == Next.Values)) {
  105. End = Next.End;
  106. return true;
  107. }
  108. return false;
  109. }
  110. const MCSymbol *getBeginSym() const { return Begin; }
  111. const MCSymbol *getEndSym() const { return End; }
  112. ArrayRef<DbgValueLoc> getValues() const { return Values; }
  113. void addValues(ArrayRef<DbgValueLoc> Vals) {
  114. Values.append(Vals.begin(), Vals.end());
  115. sortUniqueValues();
  116. assert((Values.size() == 1 || all_of(Values, [](DbgValueLoc V) {
  117. return V.isFragment();
  118. })) && "must either have a single value or multiple pieces");
  119. }
  120. // Sort the pieces by offset.
  121. // Remove any duplicate entries by dropping all but the first.
  122. void sortUniqueValues() {
  123. llvm::sort(Values);
  124. Values.erase(std::unique(Values.begin(), Values.end(),
  125. [](const DbgValueLoc &A, const DbgValueLoc &B) {
  126. return A.getExpression() == B.getExpression();
  127. }),
  128. Values.end());
  129. }
  130. /// Lower this entry into a DWARF expression.
  131. void finalize(const AsmPrinter &AP,
  132. DebugLocStream::ListBuilder &List,
  133. const DIBasicType *BT,
  134. DwarfCompileUnit &TheCU);
  135. };
  136. /// Compare two DbgValueLocs for equality.
  137. inline bool operator==(const DbgValueLoc &A,
  138. const DbgValueLoc &B) {
  139. if (A.EntryKind != B.EntryKind)
  140. return false;
  141. if (A.Expression != B.Expression)
  142. return false;
  143. switch (A.EntryKind) {
  144. case DbgValueLoc::E_Location:
  145. return A.Loc == B.Loc;
  146. case DbgValueLoc::E_Integer:
  147. return A.Constant.Int == B.Constant.Int;
  148. case DbgValueLoc::E_ConstantFP:
  149. return A.Constant.CFP == B.Constant.CFP;
  150. case DbgValueLoc::E_ConstantInt:
  151. return A.Constant.CIP == B.Constant.CIP;
  152. }
  153. llvm_unreachable("unhandled EntryKind");
  154. }
  155. /// Compare two fragments based on their offset.
  156. inline bool operator<(const DbgValueLoc &A,
  157. const DbgValueLoc &B) {
  158. return A.getExpression()->getFragmentInfo()->OffsetInBits <
  159. B.getExpression()->getFragmentInfo()->OffsetInBits;
  160. }
  161. }
  162. #endif