LLVM 23.0.0git
DebugLoc.cpp
Go to the documentation of this file.
1//===-- DebugLoc.cpp - Implement DebugLoc class ---------------------------===//
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#include "llvm/IR/DebugLoc.h"
10#include "llvm/Config/llvm-config.h"
11#include "llvm/IR/DebugInfo.h"
12
13using namespace llvm;
14
15#if LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
17
18DbgLocOrigin::DbgLocOrigin(bool ShouldCollectTrace) {
19 if (!ShouldCollectTrace)
20 return;
21 auto &[Depth, StackTrace] = StackTraces.emplace_back();
22 Depth = sys::getStackTrace(StackTrace);
23}
24void DbgLocOrigin::addTrace() {
25 // We only want to add new stacktraces if we already have one: addTrace exists
26 // to provide more context to how missing DebugLocs have propagated through
27 // the program, but by design if there is no existing stacktrace then we have
28 // decided not to track this DebugLoc as being "missing".
29 if (StackTraces.empty())
30 return;
31 auto &[Depth, StackTrace] = StackTraces.emplace_back();
32 Depth = sys::getStackTrace(StackTrace);
33}
34#endif // LLVM_ENABLE_DEBUGLOC_TRACKING_ORIGIN
35
36//===----------------------------------------------------------------------===//
37// DebugLoc Implementation
38//===----------------------------------------------------------------------===//
39
40unsigned DebugLoc::getLine() const {
41 assert(get() && "Expected valid DebugLoc");
42 return get()->getLine();
43}
44
45unsigned DebugLoc::getCol() const {
46 assert(get() && "Expected valid DebugLoc");
47 return get()->getColumn();
48}
49
51 assert(get() && "Expected valid DebugLoc");
52 return get()->getScope();
53}
54
56 assert(get() && "Expected valid DebugLoc");
57 return get()->getInlinedAt();
58}
59
61 return cast<DILocation>(Loc)->getInlinedAtScope();
62}
63
65 // FIXME: Add a method on \a DILocation that does this work.
66 const MDNode *Scope = getInlinedAtScope();
67 if (auto *SP = getDISubprogram(Scope))
68 return DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
69
70 return DebugLoc();
71}
72
73MDNode *DebugLoc::getAsMDNode() const { return Loc; }
74
76 if (DILocation *Loc = get())
77 return Loc->isImplicitCode();
78 return true;
79}
80
81void DebugLoc::setImplicitCode(bool ImplicitCode) {
82 if (DILocation *Loc = get())
83 Loc->setImplicitCode(ImplicitCode);
84}
85
87 const DebugLoc &RootLoc, DISubprogram &NewSP, LLVMContext &Ctx,
90 DILocation *CachedResult = nullptr;
91
92 // Collect the inline chain, stopping if we find a location that has already
93 // been processed.
94 for (DILocation *Loc = RootLoc; Loc; Loc = Loc->getInlinedAt()) {
95 if (auto It = Cache.find(Loc); It != Cache.end()) {
96 CachedResult = cast<DILocation>(It->second);
97 break;
98 }
99 LocChain.push_back(Loc);
100 }
101
102 DILocation *UpdatedLoc = CachedResult;
103 if (!UpdatedLoc) {
104 // If no cache hits, then back() is the end of the inline chain, that is,
105 // the DILocation whose scope ends in the Subprogram to be replaced.
106 DILocation *LocToUpdate = LocChain.pop_back_val();
108 *LocToUpdate->getScope(), NewSP, Ctx, Cache);
109 UpdatedLoc = DILocation::get(Ctx, LocToUpdate->getLine(),
110 LocToUpdate->getColumn(), NewScope);
111 Cache[LocToUpdate] = UpdatedLoc;
112 }
113
114 // Recreate the location chain, bottom-up, starting at the new scope (or a
115 // cached result).
116 for (const DILocation *LocToUpdate : reverse(LocChain)) {
117 UpdatedLoc =
118 DILocation::get(Ctx, LocToUpdate->getLine(), LocToUpdate->getColumn(),
119 LocToUpdate->getScope(), UpdatedLoc);
120 Cache[LocToUpdate] = UpdatedLoc;
121 }
122
123 return UpdatedLoc;
124}
125
127 LLVMContext &Ctx,
129 SmallVector<DILocation *, 3> InlinedAtLocations;
130 DILocation *Last = InlinedAt;
131 DILocation *CurInlinedAt = DL;
132
133 // Gather all the inlined-at nodes.
134 while (DILocation *IA = CurInlinedAt->getInlinedAt()) {
135 // Skip any we've already built nodes for.
136 if (auto *Found = Cache[IA]) {
137 Last = cast<DILocation>(Found);
138 break;
139 }
140
141 InlinedAtLocations.push_back(IA);
142 CurInlinedAt = IA;
143 }
144
145 // Starting from the top, rebuild the nodes to point to the new inlined-at
146 // location (then rebuilding the rest of the chain behind it) and update the
147 // map of already-constructed inlined-at nodes.
148 // Key Instructions: InlinedAt fields don't need atom info.
149 for (const DILocation *MD : reverse(InlinedAtLocations))
150 Cache[MD] = Last = DILocation::getDistinct(
151 Ctx, MD->getLine(), MD->getColumn(), MD->getScope(), Last);
152
153 return Last;
154}
155
157 if (Locs.empty())
158 return DebugLoc();
159 if (Locs.size() == 1)
160 return Locs[0];
161 DebugLoc Merged = Locs[0];
162 for (const DebugLoc &DL : llvm::drop_begin(Locs)) {
163 Merged = getMergedLocation(Merged, DL);
164 if (!Merged)
165 break;
166 }
167 return Merged;
168}
170 if (!LocA || !LocB) {
171 // If coverage tracking is enabled, prioritize returning empty non-annotated
172 // locations to empty annotated locations.
173#if LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
174 if (!LocA && LocA.getKind() == DebugLocKind::Normal)
175 return LocA;
176 if (!LocB && LocB.getKind() == DebugLocKind::Normal)
177 return LocB;
178#endif // LLVM_ENABLE_DEBUGLOC_TRACKING_COVERAGE
179 if (!LocA)
180 return LocA;
181 return LocB;
182 }
183 return DILocation::getMergedLocation(LocA, LocB);
184}
185
186#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
188#endif
189
191 if (!Loc)
192 return;
193
194 // Print source line info.
195 auto *Scope = cast<DIScope>(getScope());
196 OS << Scope->getFilename();
197 OS << ':' << getLine();
198 if (getCol() != 0)
199 OS << ':' << getCol();
200
201 if (DebugLoc InlinedAtDL = getInlinedAt()) {
202 OS << " @[ ";
203 InlinedAtDL.print(OS);
204 OS << " ]";
205 }
206}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:661
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
static LLVM_ABI DILocalScope * cloneScopeForSubprogram(DILocalScope &RootScope, DISubprogram &NewSP, LLVMContext &Ctx, DenseMap< const MDNode *, MDNode * > &Cache)
Traverses the scope chain rooted at RootScope until it hits a Subprogram, recreating the chain with "...
static LLVM_ABI DILocation * getMergedLocation(DILocation *LocA, DILocation *LocB)
Attempts to merge LocA and LocB into a single location; see DebugLoc::getMergedLocation for more deta...
Base class for scope-like contexts.
Subprogram description. Uses SubclassData1.
LLVM_ABI void setImplicitCode(bool ImplicitCode)
Definition DebugLoc.cpp:81
LLVM_ABI unsigned getLine() const
Definition DebugLoc.cpp:40
DILocation * get() const
Get the underlying DILocation.
Definition DebugLoc.h:218
LLVM_ABI DebugLoc getFnDebugLoc() const
Find the debug info location for the start of the function.
Definition DebugLoc.cpp:64
LLVM_ABI MDNode * getScope() const
Definition DebugLoc.cpp:50
LLVM_ABI MDNode * getAsMDNode() const
Return this as a bar MDNode.
Definition DebugLoc.cpp:73
DebugLoc(const DILocation *L=nullptr)
Construct from an DILocation.
Definition DebugLoc.h:129
static LLVM_ABI DebugLoc appendInlinedAt(const DebugLoc &DL, DILocation *InlinedAt, LLVMContext &Ctx, DenseMap< const MDNode *, MDNode * > &Cache)
Rebuild the entire inlined-at chain for this instruction so that the top of the chain now is inlined-...
Definition DebugLoc.cpp:126
static LLVM_ABI DebugLoc getMergedLocation(DebugLoc LocA, DebugLoc LocB)
When two instructions are combined into a single instruction we also need to combine the original loc...
Definition DebugLoc.cpp:169
LLVM_ABI void print(raw_ostream &OS) const
prints source location /path/to/file.exe:line:col @[inlined at]
Definition DebugLoc.cpp:190
static LLVM_ABI DebugLoc getMergedLocations(ArrayRef< DebugLoc > Locs)
Try to combine the vector of locations passed as input in a single one.
Definition DebugLoc.cpp:156
LLVM_ABI unsigned getCol() const
Definition DebugLoc.cpp:45
static LLVM_ABI DebugLoc replaceInlinedAtSubprogram(const DebugLoc &DL, DISubprogram &NewSP, LLVMContext &Ctx, DenseMap< const MDNode *, MDNode * > &Cache)
Rebuild the entire inline-at chain by replacing the subprogram at the end of the chain with NewSP.
Definition DebugLoc.cpp:86
LLVM_ABI bool isImplicitCode() const
Check if the DebugLoc corresponds to an implicit code.
Definition DebugLoc.cpp:75
LLVM_ABI void dump() const
Definition DebugLoc.cpp:187
LLVM_ABI DILocation * getInlinedAt() const
Definition DebugLoc.cpp:55
LLVM_ABI MDNode * getInlinedAtScope() const
Get the fully inlined-at scope for a DebugLoc.
Definition DebugLoc.cpp:60
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
Metadata node.
Definition Metadata.h:1075
static MDTuple * getDistinct(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1575
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1567
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:315
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI DISubprogram * getDISubprogram(const MDNode *Scope)
Find subprogram that is enclosing this scope.