1 //===- LexicalScopes.cpp - Collecting lexical scope info ------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements LexicalScopes analysis.
11 // This pass collects lexical scope information and maps machine instructions
12 // to respective lexical scopes.
14 //===----------------------------------------------------------------------===//
16 #include "llvm/CodeGen/LexicalScopes.h"
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/CodeGen/MachineBasicBlock.h"
20 #include "llvm/CodeGen/MachineFunction.h"
21 #include "llvm/CodeGen/MachineInstr.h"
22 #include "llvm/Config/llvm-config.h"
23 #include "llvm/IR/DebugInfoMetadata.h"
24 #include "llvm/IR/Function.h"
25 #include "llvm/IR/Metadata.h"
26 #include "llvm/Support/Casting.h"
27 #include "llvm/Support/Compiler.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/raw_ostream.h"
37 #define DEBUG_TYPE "lexicalscopes"
39 /// reset - Reset the instance so that it's prepared for another function.
40 void LexicalScopes::reset() {
42 CurrentFnLexicalScope
= nullptr;
43 LexicalScopeMap
.clear();
44 AbstractScopeMap
.clear();
45 InlinedLexicalScopeMap
.clear();
46 AbstractScopesList
.clear();
47 DominatedBlocks
.clear();
50 /// initialize - Scan machine function and constuct lexical scope nest.
51 void LexicalScopes::initialize(const MachineFunction
&Fn
) {
53 // Don't attempt any lexical scope creation for a NoDebug compile unit.
54 if (Fn
.getFunction().getSubprogram()->getUnit()->getEmissionKind() ==
55 DICompileUnit::NoDebug
)
58 SmallVector
<InsnRange
, 4> MIRanges
;
59 DenseMap
<const MachineInstr
*, LexicalScope
*> MI2ScopeMap
;
60 extractLexicalScopes(MIRanges
, MI2ScopeMap
);
61 if (CurrentFnLexicalScope
) {
62 constructScopeNest(CurrentFnLexicalScope
);
63 assignInstructionRanges(MIRanges
, MI2ScopeMap
);
67 /// extractLexicalScopes - Extract instruction ranges for each lexical scopes
68 /// for the given machine function.
69 void LexicalScopes::extractLexicalScopes(
70 SmallVectorImpl
<InsnRange
> &MIRanges
,
71 DenseMap
<const MachineInstr
*, LexicalScope
*> &MI2ScopeMap
) {
72 // Scan each instruction and create scopes. First build working set of scopes.
73 for (const auto &MBB
: *MF
) {
74 const MachineInstr
*RangeBeginMI
= nullptr;
75 const MachineInstr
*PrevMI
= nullptr;
76 const DILocation
*PrevDL
= nullptr;
77 for (const auto &MInsn
: MBB
) {
78 // Ignore DBG_VALUE and similar instruction that do not contribute to any
79 // instruction in the output.
80 if (MInsn
.isMetaInstruction())
83 // Check if instruction has valid location information.
84 const DILocation
*MIDL
= MInsn
.getDebugLoc();
90 // If scope has not changed then skip this instruction.
97 // If we have already seen a beginning of an instruction range and
98 // current instruction scope does not match scope of first instruction
99 // in this range then create a new instruction range.
100 InsnRange
R(RangeBeginMI
, PrevMI
);
101 MI2ScopeMap
[RangeBeginMI
] = getOrCreateLexicalScope(PrevDL
);
102 MIRanges
.push_back(R
);
105 // This is a beginning of a new instruction range.
106 RangeBeginMI
= &MInsn
;
108 // Reset previous markers.
113 // Create last instruction range.
114 if (RangeBeginMI
&& PrevMI
&& PrevDL
) {
115 InsnRange
R(RangeBeginMI
, PrevMI
);
116 MIRanges
.push_back(R
);
117 MI2ScopeMap
[RangeBeginMI
] = getOrCreateLexicalScope(PrevDL
);
122 /// findLexicalScope - Find lexical scope, either regular or inlined, for the
123 /// given DebugLoc. Return NULL if not found.
124 LexicalScope
*LexicalScopes::findLexicalScope(const DILocation
*DL
) {
125 DILocalScope
*Scope
= DL
->getScope();
129 // The scope that we were created with could have an extra file - which
130 // isn't what we care about in this case.
131 Scope
= Scope
->getNonLexicalBlockFileScope();
133 if (auto *IA
= DL
->getInlinedAt()) {
134 auto I
= InlinedLexicalScopeMap
.find(std::make_pair(Scope
, IA
));
135 return I
!= InlinedLexicalScopeMap
.end() ? &I
->second
: nullptr;
137 return findLexicalScope(Scope
);
140 /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
141 /// not available then create new lexical scope.
142 LexicalScope
*LexicalScopes::getOrCreateLexicalScope(const DILocalScope
*Scope
,
143 const DILocation
*IA
) {
145 // Skip scopes inlined from a NoDebug compile unit.
146 if (Scope
->getSubprogram()->getUnit()->getEmissionKind() ==
147 DICompileUnit::NoDebug
)
148 return getOrCreateLexicalScope(IA
);
149 // Create an abstract scope for inlined function.
150 getOrCreateAbstractScope(Scope
);
151 // Create an inlined scope for inlined function.
152 return getOrCreateInlinedScope(Scope
, IA
);
155 return getOrCreateRegularScope(Scope
);
158 /// getOrCreateRegularScope - Find or create a regular lexical scope.
160 LexicalScopes::getOrCreateRegularScope(const DILocalScope
*Scope
) {
161 assert(Scope
&& "Invalid Scope encoding!");
162 Scope
= Scope
->getNonLexicalBlockFileScope();
164 auto I
= LexicalScopeMap
.find(Scope
);
165 if (I
!= LexicalScopeMap
.end())
168 // FIXME: Should the following dyn_cast be DILexicalBlock?
169 LexicalScope
*Parent
= nullptr;
170 if (auto *Block
= dyn_cast
<DILexicalBlockBase
>(Scope
))
171 Parent
= getOrCreateLexicalScope(Block
->getScope());
172 I
= LexicalScopeMap
.emplace(std::piecewise_construct
,
173 std::forward_as_tuple(Scope
),
174 std::forward_as_tuple(Parent
, Scope
, nullptr,
178 assert(cast
<DISubprogram
>(Scope
)->describes(&MF
->getFunction()));
179 assert(!CurrentFnLexicalScope
);
180 CurrentFnLexicalScope
= &I
->second
;
186 /// getOrCreateInlinedScope - Find or create an inlined lexical scope.
188 LexicalScopes::getOrCreateInlinedScope(const DILocalScope
*Scope
,
189 const DILocation
*InlinedAt
) {
190 assert(Scope
&& "Invalid Scope encoding!");
191 Scope
= Scope
->getNonLexicalBlockFileScope();
192 std::pair
<const DILocalScope
*, const DILocation
*> P(Scope
, InlinedAt
);
193 auto I
= InlinedLexicalScopeMap
.find(P
);
194 if (I
!= InlinedLexicalScopeMap
.end())
197 LexicalScope
*Parent
;
198 if (auto *Block
= dyn_cast
<DILexicalBlockBase
>(Scope
))
199 Parent
= getOrCreateInlinedScope(Block
->getScope(), InlinedAt
);
201 Parent
= getOrCreateLexicalScope(InlinedAt
);
203 I
= InlinedLexicalScopeMap
204 .emplace(std::piecewise_construct
, std::forward_as_tuple(P
),
205 std::forward_as_tuple(Parent
, Scope
, InlinedAt
, false))
210 /// getOrCreateAbstractScope - Find or create an abstract lexical scope.
212 LexicalScopes::getOrCreateAbstractScope(const DILocalScope
*Scope
) {
213 assert(Scope
&& "Invalid Scope encoding!");
214 Scope
= Scope
->getNonLexicalBlockFileScope();
215 auto I
= AbstractScopeMap
.find(Scope
);
216 if (I
!= AbstractScopeMap
.end())
219 // FIXME: Should the following isa be DILexicalBlock?
220 LexicalScope
*Parent
= nullptr;
221 if (auto *Block
= dyn_cast
<DILexicalBlockBase
>(Scope
))
222 Parent
= getOrCreateAbstractScope(Block
->getScope());
224 I
= AbstractScopeMap
.emplace(std::piecewise_construct
,
225 std::forward_as_tuple(Scope
),
226 std::forward_as_tuple(Parent
, Scope
,
227 nullptr, true)).first
;
228 if (isa
<DISubprogram
>(Scope
))
229 AbstractScopesList
.push_back(&I
->second
);
233 /// constructScopeNest - Traverse the Scope tree depth-first, storing
234 /// traversal state in WorkStack and recording the depth-first
235 /// numbering (setDFSIn, setDFSOut) for edge classification.
236 void LexicalScopes::constructScopeNest(LexicalScope
*Scope
) {
237 assert(Scope
&& "Unable to calculate scope dominance graph!");
238 SmallVector
<std::pair
<LexicalScope
*, size_t>, 4> WorkStack
;
239 WorkStack
.push_back(std::make_pair(Scope
, 0));
240 unsigned Counter
= 0;
241 while (!WorkStack
.empty()) {
242 auto &ScopePosition
= WorkStack
.back();
243 LexicalScope
*WS
= ScopePosition
.first
;
244 size_t ChildNum
= ScopePosition
.second
++;
245 const SmallVectorImpl
<LexicalScope
*> &Children
= WS
->getChildren();
246 if (ChildNum
< Children
.size()) {
247 auto &ChildScope
= Children
[ChildNum
];
248 WorkStack
.push_back(std::make_pair(ChildScope
, 0));
249 ChildScope
->setDFSIn(++Counter
);
251 WorkStack
.pop_back();
252 WS
->setDFSOut(++Counter
);
257 /// assignInstructionRanges - Find ranges of instructions covered by each
259 void LexicalScopes::assignInstructionRanges(
260 SmallVectorImpl
<InsnRange
> &MIRanges
,
261 DenseMap
<const MachineInstr
*, LexicalScope
*> &MI2ScopeMap
) {
262 LexicalScope
*PrevLexicalScope
= nullptr;
263 for (const auto &R
: MIRanges
) {
264 LexicalScope
*S
= MI2ScopeMap
.lookup(R
.first
);
265 assert(S
&& "Lost LexicalScope for a machine instruction!");
266 if (PrevLexicalScope
&& !PrevLexicalScope
->dominates(S
))
267 PrevLexicalScope
->closeInsnRange(S
);
268 S
->openInsnRange(R
.first
);
269 S
->extendInsnRange(R
.second
);
270 PrevLexicalScope
= S
;
273 if (PrevLexicalScope
)
274 PrevLexicalScope
->closeInsnRange();
277 /// getMachineBasicBlocks - Populate given set using machine basic blocks which
278 /// have machine instructions that belong to lexical scope identified by
280 void LexicalScopes::getMachineBasicBlocks(
281 const DILocation
*DL
, SmallPtrSetImpl
<const MachineBasicBlock
*> &MBBs
) {
282 assert(MF
&& "Method called on a uninitialized LexicalScopes object!");
285 LexicalScope
*Scope
= getOrCreateLexicalScope(DL
);
289 if (Scope
== CurrentFnLexicalScope
) {
290 for (const auto &MBB
: *MF
)
295 // The scope ranges can cover multiple basic blocks in each span. Iterate over
296 // all blocks (in the order they are in the function) until we reach the one
297 // containing the end of the span.
298 SmallVectorImpl
<InsnRange
> &InsnRanges
= Scope
->getRanges();
299 for (auto &R
: InsnRanges
)
300 for (auto CurMBBIt
= R
.first
->getParent()->getIterator(),
301 EndBBIt
= std::next(R
.second
->getParent()->getIterator());
302 CurMBBIt
!= EndBBIt
; CurMBBIt
++)
303 MBBs
.insert(&*CurMBBIt
);
306 bool LexicalScopes::dominates(const DILocation
*DL
, MachineBasicBlock
*MBB
) {
307 assert(MF
&& "Unexpected uninitialized LexicalScopes object!");
308 LexicalScope
*Scope
= getOrCreateLexicalScope(DL
);
312 // Current function scope covers all basic blocks in the function.
313 if (Scope
== CurrentFnLexicalScope
&& MBB
->getParent() == MF
)
316 // Fetch all the blocks in DLs scope. Because the range / block list also
317 // contain any subscopes, any instruction that DL dominates can be found in
320 // Cache the set of fetched blocks to avoid repeatedly recomputing the set in
321 // the LiveDebugValues pass.
322 std::unique_ptr
<BlockSetT
> &Set
= DominatedBlocks
[DL
];
324 Set
= std::make_unique
<BlockSetT
>();
325 getMachineBasicBlocks(DL
, *Set
);
327 return Set
->contains(MBB
);
330 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
331 LLVM_DUMP_METHOD
void LexicalScope::dump(unsigned Indent
) const {
332 raw_ostream
&err
= dbgs();
334 err
<< "DFSIn: " << DFSIn
<< " DFSOut: " << DFSOut
<< "\n";
335 const MDNode
*N
= Desc
;
339 err
<< std::string(Indent
, ' ') << "Abstract Scope\n";
341 if (!Children
.empty())
342 err
<< std::string(Indent
+ 2, ' ') << "Children ...\n";
343 for (unsigned i
= 0, e
= Children
.size(); i
!= e
; ++i
)
344 if (Children
[i
] != this)
345 Children
[i
]->dump(Indent
+ 2);