LLVM 24.0.0git
DebugLocEntry.h
Go to the documentation of this file.
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
9#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCENTRY_H
10#define LLVM_LIB_CODEGEN_ASMPRINTER_DEBUGLOCENTRY_H
11
12#include "DebugLocStream.h"
13#include "llvm/Config/llvm-config.h"
14#include "llvm/IR/Constants.h"
15#include "llvm/IR/DebugInfo.h"
16#include "llvm/MC/MCSymbol.h"
18#include "llvm/Support/Debug.h"
19
20namespace llvm {
21class AsmPrinter;
22class GlobalValue;
23
24/// This struct describes target specific location.
26 int Index;
27 int Offset;
28
30 TargetIndexLocation(unsigned Idx, int64_t Offset)
31 : Index(Idx), Offset(Offset) {}
32
34 return Index == Other.Index && Offset == Other.Offset;
35 }
36};
37
38/// This struct describes the address of a global, displaced by a constant.
41 int64_t Offset;
42
46
48 return GV == Other.GV && Offset == Other.Offset;
49 }
50};
51
52/// A single location or constant within a variable location description, with
53/// either a single entry (with an optional DIExpression) used for a DBG_VALUE,
54/// or a list of entries used for a DBG_VALUE_LIST.
56
57 /// Type of entry that this represents.
58 enum EntryType {
59 E_Location,
60 E_Integer,
61 E_ConstantFP,
62 E_ConstantInt,
63 E_TargetIndexLocation,
64 E_GlobalAddress
65 };
66 enum EntryType EntryKind;
67
68 /// Either a constant,
69 union {
70 int64_t Int;
73 } Constant;
74
75 union {
76 /// Or a location in the machine frame.
78 /// Or a location from target specific location.
80 /// Or the address of a global.
82 };
83
84public:
85 DbgValueLocEntry(int64_t i) : EntryKind(E_Integer) { Constant.Int = i; }
86 DbgValueLocEntry(const ConstantFP *CFP) : EntryKind(E_ConstantFP) {
87 Constant.CFP = CFP;
88 }
89 DbgValueLocEntry(const ConstantInt *CIP) : EntryKind(E_ConstantInt) {
90 Constant.CIP = CIP;
91 }
92 DbgValueLocEntry(MachineLocation Loc) : EntryKind(E_Location), Loc(Loc) {}
94 : EntryKind(E_TargetIndexLocation), TIL(Loc) {}
96 : EntryKind(E_GlobalAddress), GAL(GAL) {}
97
98 bool isLocation() const { return EntryKind == E_Location; }
99 bool isIndirectLocation() const {
100 return EntryKind == E_Location && Loc.isIndirect();
101 }
103 return EntryKind == E_TargetIndexLocation;
104 }
105 bool isInt() const { return EntryKind == E_Integer; }
106 bool isConstantFP() const { return EntryKind == E_ConstantFP; }
107 bool isConstantInt() const { return EntryKind == E_ConstantInt; }
108 bool isGlobalAddress() const { return EntryKind == E_GlobalAddress; }
109 int64_t getInt() const { return Constant.Int; }
110 const ConstantFP *getConstantFP() const { return Constant.CFP; }
111 const ConstantInt *getConstantInt() const { return Constant.CIP; }
112 const GlobalValue *getGlobalAddress() const { return GAL.GV; }
113 int64_t getGlobalOffset() const { return GAL.Offset; }
114 MachineLocation getLoc() const { return Loc; }
116 friend bool operator==(const DbgValueLocEntry &, const DbgValueLocEntry &);
117#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
118 LLVM_DUMP_METHOD void dump() const {
119 if (isLocation()) {
120 llvm::dbgs() << "Loc = { reg=" << Loc.getReg() << " ";
121 if (Loc.isIndirect())
122 llvm::dbgs() << "+0";
123 llvm::dbgs() << "} ";
124 } else if (isConstantInt())
125 Constant.CIP->dump();
126 else if (isConstantFP())
127 Constant.CFP->dump();
128 }
129#endif
130};
131
132/// The location of a single variable, composed of an expression and 0 or more
133/// DbgValueLocEntries.
135 /// Any complex address location expression for this DbgValueLoc.
136 const DIExpression *Expression;
137
138 SmallVector<DbgValueLocEntry, 2> ValueLocEntries;
139
140 bool IsVariadic;
141
142public:
144 : Expression(Expr), ValueLocEntries(Locs), IsVariadic(true) {}
145
147 bool IsVariadic)
148 : Expression(Expr), ValueLocEntries(Locs), IsVariadic(IsVariadic) {
149#ifndef NDEBUG
150 assert(Expr->isValid() ||
151 !any_of(Locs, [](auto LE) { return LE.isLocation(); }));
152 if (!IsVariadic) {
153 assert(ValueLocEntries.size() == 1);
154 }
155#endif
156 }
157
159 : Expression(Expr), ValueLocEntries(1, Loc), IsVariadic(false) {
160 assert(((Expr && Expr->isValid()) || !Loc.isLocation()) &&
161 "DBG_VALUE with a machine location must have a valid expression.");
162 }
163
164 bool isFragment() const { return getExpression()->isFragment(); }
165 bool isEntryVal() const { return getExpression()->isEntryValue(); }
166 bool isVariadic() const { return IsVariadic; }
167 bool isEquivalent(const DbgValueLoc &Other) const {
168 // Cannot be equivalent with different numbers of entries.
169 if (ValueLocEntries.size() != Other.ValueLocEntries.size())
170 return false;
171 bool ThisIsIndirect =
172 !IsVariadic && ValueLocEntries[0].isIndirectLocation();
173 bool OtherIsIndirect =
174 !Other.IsVariadic && Other.ValueLocEntries[0].isIndirectLocation();
175 // Check equivalence of DIExpressions + Directness together.
176 if (!DIExpression::isEqualExpression(Expression, ThisIsIndirect,
177 Other.Expression, OtherIsIndirect))
178 return false;
179 // Indirectness should have been accounted for in the above check, so just
180 // compare register values directly here.
181 if (ThisIsIndirect || OtherIsIndirect) {
182 DbgValueLocEntry ThisOp = ValueLocEntries[0];
183 DbgValueLocEntry OtherOp = Other.ValueLocEntries[0];
184 return ThisOp.isLocation() && OtherOp.isLocation() &&
185 ThisOp.getLoc().getReg() == OtherOp.getLoc().getReg();
186 }
187 // If neither are indirect, then just compare the loc entries directly.
188 return ValueLocEntries == Other.ValueLocEntries;
189 }
190 const DIExpression *getExpression() const { return Expression; }
191 ArrayRef<DbgValueLocEntry> getLocEntries() const { return ValueLocEntries; }
192 friend bool operator==(const DbgValueLoc &, const DbgValueLoc &);
193 friend bool operator<(const DbgValueLoc &, const DbgValueLoc &);
194#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
195 LLVM_DUMP_METHOD void dump() const {
196 for (const DbgValueLocEntry &DV : ValueLocEntries)
197 DV.dump();
198 if (Expression)
199 Expression->dump();
200 }
201#endif
202};
203
204/// This struct describes location entries emitted in the .debug_loc
205/// section.
207 /// Begin and end symbols for the address range that this location is valid.
208 const MCSymbol *Begin;
209 const MCSymbol *End;
210
211 /// A nonempty list of locations/constants belonging to this entry,
212 /// sorted by offset.
214
215public:
216 /// Create a location list entry for the range [\p Begin, \p End).
217 ///
218 /// \param Vals One or more values describing (parts of) the variable.
219 DebugLocEntry(const MCSymbol *Begin, const MCSymbol *End,
221 : Begin(Begin), End(End) {
222 addValues(Vals);
223 }
224
225 /// Attempt to merge this DebugLocEntry with Next and return
226 /// true if the merge was successful. Entries can be merged if they
227 /// share the same Loc/Constant and if Next immediately follows this
228 /// Entry.
230 // If this and Next are describing the same variable, merge them.
231 if (End != Next.Begin)
232 return false;
233 if (Values.size() != Next.Values.size())
234 return false;
235 for (unsigned EntryIdx = 0; EntryIdx < Values.size(); ++EntryIdx)
236 if (!Values[EntryIdx].isEquivalent(Next.Values[EntryIdx]))
237 return false;
238 End = Next.End;
239 return true;
240 }
241
242 const MCSymbol *getBeginSym() const { return Begin; }
243 const MCSymbol *getEndSym() const { return End; }
244 ArrayRef<DbgValueLoc> getValues() const { return Values; }
246 Values.append(Vals.begin(), Vals.end());
248 assert((Values.size() == 1 || all_of(Values, [](DbgValueLoc V) {
249 return V.isFragment();
250 })) && "must either have a single value or multiple pieces");
251 }
252
253 // Sort the pieces by offset.
254 // Remove any duplicate entries by dropping all but the first.
256 // Values is either 1 item that does not have a fragment, or many items
257 // that all do. No need to sort if the former and also prevents operator<
258 // being called on a non fragment item when _GLIBCXX_DEBUG is defined.
259 if (Values.size() == 1)
260 return;
261 llvm::sort(Values);
262 Values.erase(llvm::unique(Values,
263 [](const DbgValueLoc &A, const DbgValueLoc &B) {
264 return A.getExpression() == B.getExpression();
265 }),
266 Values.end());
267 }
268
269 /// Lower this entry into a DWARF expression.
270 void finalize(const AsmPrinter &AP,
272 const DIBasicType *BT,
273 DwarfCompileUnit &TheCU);
274};
275
276/// Compare two DbgValueLocEntries for equality.
277inline bool operator==(const DbgValueLocEntry &A, const DbgValueLocEntry &B) {
278 if (A.EntryKind != B.EntryKind)
279 return false;
280
281 switch (A.EntryKind) {
282 case DbgValueLocEntry::E_Location:
283 return A.Loc == B.Loc;
284 case DbgValueLocEntry::E_TargetIndexLocation:
285 return A.TIL == B.TIL;
286 case DbgValueLocEntry::E_Integer:
287 return A.Constant.Int == B.Constant.Int;
288 case DbgValueLocEntry::E_ConstantFP:
289 return A.Constant.CFP == B.Constant.CFP;
290 case DbgValueLocEntry::E_ConstantInt:
291 return A.Constant.CIP == B.Constant.CIP;
292 case DbgValueLocEntry::E_GlobalAddress:
293 return A.GAL == B.GAL;
294 }
295 llvm_unreachable("unhandled EntryKind");
296}
297
298/// Compare two DbgValueLocs for equality.
299inline bool operator==(const DbgValueLoc &A, const DbgValueLoc &B) {
300 return A.ValueLocEntries == B.ValueLocEntries &&
301 A.Expression == B.Expression && A.IsVariadic == B.IsVariadic;
302}
303
304/// Compare two fragments based on their offset.
305inline bool operator<(const DbgValueLoc &A,
306 const DbgValueLoc &B) {
307 return A.getExpression()->getFragmentInfo()->OffsetInBits <
308 B.getExpression()->getFragmentInfo()->OffsetInBits;
309}
310
311}
312
313#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
arc branch finalize
BitTracker BT
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:683
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
iterator end() const
Definition ArrayRef.h:130
iterator begin() const
Definition ArrayRef.h:129
This class is intended to be used as a driving class for all asm writers.
Definition AsmPrinter.h:91
ConstantFP - Floating Point Values [float, double].
Definition Constants.h:420
This is the shared class of boolean and integer constants.
Definition Constants.h:87
This is an important base class in LLVM.
Definition Constant.h:43
Basic type, like 'int' or 'float'.
DWARF expression.
LLVM_ABI bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
bool isFragment() const
Return whether this is a piece of an aggregate variable.
static LLVM_ABI bool isEqualExpression(const DIExpression *FirstExpr, bool FirstIndirect, const DIExpression *SecondExpr, bool SecondIndirect)
Determines whether two debug values should produce equivalent DWARF expressions, using their DIExpres...
LLVM_ABI bool isValid() const
A single location or constant within a variable location description, with either a single entry (wit...
bool isGlobalAddress() const
DbgValueLocEntry(const ConstantFP *CFP)
TargetIndexLocation getTargetIndexLocation() const
MachineLocation Loc
Or a location in the machine frame.
const ConstantInt * CIP
int64_t getGlobalOffset() const
const ConstantFP * getConstantFP() const
int64_t getInt() const
friend bool operator==(const DbgValueLocEntry &, const DbgValueLocEntry &)
Compare two DbgValueLocEntries for equality.
GlobalAddressLocation GAL
Or the address of a global.
DbgValueLocEntry(MachineLocation Loc)
const GlobalValue * getGlobalAddress() const
TargetIndexLocation TIL
Or a location from target specific location.
bool isIndirectLocation() const
const ConstantInt * getConstantInt() const
LLVM_DUMP_METHOD void dump() const
bool isTargetIndexLocation() const
DbgValueLocEntry(GlobalAddressLocation GAL)
MachineLocation getLoc() const
DbgValueLocEntry(const ConstantInt *CIP)
DbgValueLocEntry(TargetIndexLocation Loc)
const ConstantFP * CFP
The location of a single variable, composed of an expression and 0 or more DbgValueLocEntries.
DbgValueLoc(const DIExpression *Expr, DbgValueLocEntry Loc)
DbgValueLoc(const DIExpression *Expr, ArrayRef< DbgValueLocEntry > Locs, bool IsVariadic)
friend bool operator==(const DbgValueLoc &, const DbgValueLoc &)
Compare two DbgValueLocs for equality.
ArrayRef< DbgValueLocEntry > getLocEntries() const
DbgValueLoc(const DIExpression *Expr, ArrayRef< DbgValueLocEntry > Locs)
const DIExpression * getExpression() const
bool isFragment() const
LLVM_DUMP_METHOD void dump() const
bool isVariadic() const
bool isEquivalent(const DbgValueLoc &Other) const
friend bool operator<(const DbgValueLoc &, const DbgValueLoc &)
Compare two fragments based on their offset.
bool isEntryVal() const
DebugLocEntry(const MCSymbol *Begin, const MCSymbol *End, ArrayRef< DbgValueLoc > Vals)
Create a location list entry for the range [Begin, End).
void addValues(ArrayRef< DbgValueLoc > Vals)
ArrayRef< DbgValueLoc > getValues() const
const MCSymbol * getBeginSym() const
const MCSymbol * getEndSym() const
bool MergeRanges(const DebugLocEntry &Next)
Attempt to merge this DebugLocEntry with Next and return true if the merge was successful.
Builder for DebugLocStream lists.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
unsigned getReg() const
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
Definition APSInt.h:360
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
auto unique(Range &&R, Predicate P)
Definition STLExtras.h:2150
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
@ Other
Any other memory.
Definition ModRef.h:68
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
Definition InstrProf.h:147
This struct describes the address of a global, displaced by a constant.
bool operator==(const GlobalAddressLocation &Other) const
const GlobalValue * GV
GlobalAddressLocation(const GlobalValue *GV, int64_t Offset)
This struct describes target specific location.
bool operator==(const TargetIndexLocation &Other) const
TargetIndexLocation(unsigned Idx, int64_t Offset)