LLVM 20.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"
12using namespace llvm;
13
14//===----------------------------------------------------------------------===//
15// DebugLoc Implementation
16//===----------------------------------------------------------------------===//
17DebugLoc::DebugLoc(const DILocation *L) : Loc(const_cast<DILocation *>(L)) {}
18DebugLoc::DebugLoc(const MDNode *L) : Loc(const_cast<MDNode *>(L)) {}
19
21 return cast_or_null<DILocation>(Loc.get());
22}
23
24unsigned DebugLoc::getLine() const {
25 assert(get() && "Expected valid DebugLoc");
26 return get()->getLine();
27}
28
29unsigned DebugLoc::getCol() const {
30 assert(get() && "Expected valid DebugLoc");
31 return get()->getColumn();
32}
33
35 assert(get() && "Expected valid DebugLoc");
36 return get()->getScope();
37}
38
40 assert(get() && "Expected valid DebugLoc");
41 return get()->getInlinedAt();
42}
43
45 return cast<DILocation>(Loc)->getInlinedAtScope();
46}
47
49 // FIXME: Add a method on \a DILocation that does this work.
50 const MDNode *Scope = getInlinedAtScope();
51 if (auto *SP = getDISubprogram(Scope))
52 return DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
53
54 return DebugLoc();
55}
56
58 if (DILocation *Loc = get()) {
59 return Loc->isImplicitCode();
60 }
61 return true;
62}
63
64void DebugLoc::setImplicitCode(bool ImplicitCode) {
65 if (DILocation *Loc = get()) {
66 Loc->setImplicitCode(ImplicitCode);
67 }
68}
69
71 const DebugLoc &RootLoc, DISubprogram &NewSP, LLVMContext &Ctx,
74 DILocation *CachedResult = nullptr;
75
76 // Collect the inline chain, stopping if we find a location that has already
77 // been processed.
78 for (DILocation *Loc = RootLoc; Loc; Loc = Loc->getInlinedAt()) {
79 if (auto It = Cache.find(Loc); It != Cache.end()) {
80 CachedResult = cast<DILocation>(It->second);
81 break;
82 }
83 LocChain.push_back(Loc);
84 }
85
86 DILocation *UpdatedLoc = CachedResult;
87 if (!UpdatedLoc) {
88 // If no cache hits, then back() is the end of the inline chain, that is,
89 // the DILocation whose scope ends in the Subprogram to be replaced.
90 DILocation *LocToUpdate = LocChain.pop_back_val();
92 *LocToUpdate->getScope(), NewSP, Ctx, Cache);
93 UpdatedLoc = DILocation::get(Ctx, LocToUpdate->getLine(),
94 LocToUpdate->getColumn(), NewScope);
95 Cache[LocToUpdate] = UpdatedLoc;
96 }
97
98 // Recreate the location chain, bottom-up, starting at the new scope (or a
99 // cached result).
100 for (const DILocation *LocToUpdate : reverse(LocChain)) {
101 UpdatedLoc =
102 DILocation::get(Ctx, LocToUpdate->getLine(), LocToUpdate->getColumn(),
103 LocToUpdate->getScope(), UpdatedLoc);
104 Cache[LocToUpdate] = UpdatedLoc;
105 }
106
107 return UpdatedLoc;
108}
109
111 LLVMContext &Ctx,
113 SmallVector<DILocation *, 3> InlinedAtLocations;
114 DILocation *Last = InlinedAt;
115 DILocation *CurInlinedAt = DL;
116
117 // Gather all the inlined-at nodes.
118 while (DILocation *IA = CurInlinedAt->getInlinedAt()) {
119 // Skip any we've already built nodes for.
120 if (auto *Found = Cache[IA]) {
121 Last = cast<DILocation>(Found);
122 break;
123 }
124
125 InlinedAtLocations.push_back(IA);
126 CurInlinedAt = IA;
127 }
128
129 // Starting from the top, rebuild the nodes to point to the new inlined-at
130 // location (then rebuilding the rest of the chain behind it) and update the
131 // map of already-constructed inlined-at nodes.
132 for (const DILocation *MD : reverse(InlinedAtLocations))
133 Cache[MD] = Last = DILocation::getDistinct(
134 Ctx, MD->getLine(), MD->getColumn(), MD->getScope(), Last);
135
136 return Last;
137}
138
139#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
141#endif
142
144 if (!Loc)
145 return;
146
147 // Print source line info.
148 auto *Scope = cast<DIScope>(getScope());
149 OS << Scope->getFilename();
150 OS << ':' << getLine();
151 if (getCol() != 0)
152 OS << ':' << getCol();
153
154 if (DebugLoc InlinedAtDL = getInlinedAt()) {
155 OS << " @[ ";
156 InlinedAtDL.print(OS);
157 OS << " ]";
158 }
159}
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:533
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
static 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 "...
Debug location.
Base class for scope-like contexts.
Subprogram description.
A debug info location.
Definition: DebugLoc.h:33
void setImplicitCode(bool ImplicitCode)
Definition: DebugLoc.cpp:64
DebugLoc()=default
unsigned getLine() const
Definition: DebugLoc.cpp:24
DebugLoc getFnDebugLoc() const
Find the debug info location for the start of the function.
Definition: DebugLoc.cpp:48
DILocation * get() const
Get the underlying DILocation.
Definition: DebugLoc.cpp:20
MDNode * getScope() const
Definition: DebugLoc.cpp:34
static 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:110
void print(raw_ostream &OS) const
prints source location /path/to/file.exe:line:col @[inlined at]
Definition: DebugLoc.cpp:143
unsigned getCol() const
Definition: DebugLoc.cpp:29
static 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:70
bool isImplicitCode() const
Check if the DebugLoc corresponds to an implicit code.
Definition: DebugLoc.cpp:57
void dump() const
Definition: DebugLoc.cpp:140
DILocation * getInlinedAt() const
Definition: DebugLoc.cpp:39
MDNode * getInlinedAtScope() const
Get the fully inlined-at scope for a DebugLoc.
Definition: DebugLoc.cpp:44
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:155
iterator end()
Definition: DenseMap.h:84
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
Metadata node.
Definition: Metadata.h:1069
static MDTuple * getDistinct(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1550
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1542
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:419
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
DISubprogram * getDISubprogram(const MDNode *Scope)
Find subprogram that is enclosing this scope.
Definition: DebugInfo.cpp:152