1e1649c31SDevang Patel //===- LexicalScopes.cpp - Collecting lexical scope info ------------------===//
2e1649c31SDevang Patel //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e1649c31SDevang Patel //
7e1649c31SDevang Patel //===----------------------------------------------------------------------===//
8e1649c31SDevang Patel //
9e1649c31SDevang Patel // This file implements LexicalScopes analysis.
10e1649c31SDevang Patel //
11e1649c31SDevang Patel // This pass collects lexical scope information and maps machine instructions
12e1649c31SDevang Patel // to respective lexical scopes.
13e1649c31SDevang Patel //
14e1649c31SDevang Patel //===----------------------------------------------------------------------===//
15e1649c31SDevang Patel 
166bda14b3SChandler Carruth #include "llvm/CodeGen/LexicalScopes.h"
175db84df7SEugene Zelenko #include "llvm/ADT/DenseMap.h"
185db84df7SEugene Zelenko #include "llvm/ADT/SmallVector.h"
195db84df7SEugene Zelenko #include "llvm/CodeGen/MachineBasicBlock.h"
20e1649c31SDevang Patel #include "llvm/CodeGen/MachineFunction.h"
21e1649c31SDevang Patel #include "llvm/CodeGen/MachineInstr.h"
22432a3883SNico Weber #include "llvm/Config/llvm-config.h"
235db84df7SEugene Zelenko #include "llvm/IR/DebugInfoMetadata.h"
241d7b4136SReid Kleckner #include "llvm/IR/Function.h"
255db84df7SEugene Zelenko #include "llvm/IR/Metadata.h"
265db84df7SEugene Zelenko #include "llvm/Support/Casting.h"
275db84df7SEugene Zelenko #include "llvm/Support/Compiler.h"
28e1649c31SDevang Patel #include "llvm/Support/Debug.h"
295db84df7SEugene Zelenko #include "llvm/Support/raw_ostream.h"
305db84df7SEugene Zelenko #include <cassert>
315db84df7SEugene Zelenko #include <string>
325db84df7SEugene Zelenko #include <tuple>
335db84df7SEugene Zelenko #include <utility>
345db84df7SEugene Zelenko 
35e1649c31SDevang Patel using namespace llvm;
36e1649c31SDevang Patel 
371b9dde08SChandler Carruth #define DEBUG_TYPE "lexicalscopes"
381b9dde08SChandler Carruth 
39b7dee8a6SEric Christopher /// reset - Reset the instance so that it's prepared for another function.
reset()40b7dee8a6SEric Christopher void LexicalScopes::reset() {
41c0196b1bSCraig Topper   MF = nullptr;
42c0196b1bSCraig Topper   CurrentFnLexicalScope = nullptr;
432f143e0cSDavid Blaikie   LexicalScopeMap.clear();
442f143e0cSDavid Blaikie   AbstractScopeMap.clear();
45e1649c31SDevang Patel   InlinedLexicalScopeMap.clear();
46e1649c31SDevang Patel   AbstractScopesList.clear();
4719876268SVedant Kumar   DominatedBlocks.clear();
48e1649c31SDevang Patel }
49e1649c31SDevang Patel 
50e1649c31SDevang Patel /// initialize - Scan machine function and constuct lexical scope nest.
initialize(const MachineFunction & Fn)51e1649c31SDevang Patel void LexicalScopes::initialize(const MachineFunction &Fn) {
52e018bbd8SWolfgang Pieb   reset();
5376b5b749STeresa Johnson   // Don't attempt any lexical scope creation for a NoDebug compile unit.
54f1caa283SMatthias Braun   if (Fn.getFunction().getSubprogram()->getUnit()->getEmissionKind() ==
5576b5b749STeresa Johnson       DICompileUnit::NoDebug)
5676b5b749STeresa Johnson     return;
57e1649c31SDevang Patel   MF = &Fn;
58e1649c31SDevang Patel   SmallVector<InsnRange, 4> MIRanges;
59e1649c31SDevang Patel   DenseMap<const MachineInstr *, LexicalScope *> MI2ScopeMap;
60e1649c31SDevang Patel   extractLexicalScopes(MIRanges, MI2ScopeMap);
61e1649c31SDevang Patel   if (CurrentFnLexicalScope) {
62e1649c31SDevang Patel     constructScopeNest(CurrentFnLexicalScope);
63e1649c31SDevang Patel     assignInstructionRanges(MIRanges, MI2ScopeMap);
64e1649c31SDevang Patel   }
65e1649c31SDevang Patel }
66e1649c31SDevang Patel 
67e1649c31SDevang Patel /// extractLexicalScopes - Extract instruction ranges for each lexical scopes
68e1649c31SDevang Patel /// for the given machine function.
extractLexicalScopes(SmallVectorImpl<InsnRange> & MIRanges,DenseMap<const MachineInstr *,LexicalScope * > & MI2ScopeMap)696211e4b9SEric Christopher void LexicalScopes::extractLexicalScopes(
706211e4b9SEric Christopher     SmallVectorImpl<InsnRange> &MIRanges,
71e1649c31SDevang Patel     DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) {
72e1649c31SDevang Patel   // Scan each instruction and create scopes. First build working set of scopes.
7341b977dfSAlexey Samsonov   for (const auto &MBB : *MF) {
74c0196b1bSCraig Topper     const MachineInstr *RangeBeginMI = nullptr;
75c0196b1bSCraig Topper     const MachineInstr *PrevMI = nullptr;
76a9308c49SDuncan P. N. Exon Smith     const DILocation *PrevDL = nullptr;
77f74bde67SAlexey Samsonov     for (const auto &MInsn : MBB) {
78*b98807dfSHongtao Yu       // Ignore DBG_VALUE and similar instruction that do not contribute to any
79*b98807dfSHongtao Yu       // instruction in the output.
80*b98807dfSHongtao Yu       if (MInsn.isMetaInstruction())
81*b98807dfSHongtao Yu         continue;
82*b98807dfSHongtao Yu 
83e1649c31SDevang Patel       // Check if instruction has valid location information.
84a9308c49SDuncan P. N. Exon Smith       const DILocation *MIDL = MInsn.getDebugLoc();
859dffcd04SDuncan P. N. Exon Smith       if (!MIDL) {
86f74bde67SAlexey Samsonov         PrevMI = &MInsn;
87e1649c31SDevang Patel         continue;
88e1649c31SDevang Patel       }
89e1649c31SDevang Patel 
90e1649c31SDevang Patel       // If scope has not changed then skip this instruction.
91e1649c31SDevang Patel       if (MIDL == PrevDL) {
92f74bde67SAlexey Samsonov         PrevMI = &MInsn;
93e1649c31SDevang Patel         continue;
94e1649c31SDevang Patel       }
95e1649c31SDevang Patel 
96e1649c31SDevang Patel       if (RangeBeginMI) {
97e1649c31SDevang Patel         // If we have already seen a beginning of an instruction range and
98e1649c31SDevang Patel         // current instruction scope does not match scope of first instruction
99e1649c31SDevang Patel         // in this range then create a new instruction range.
100e1649c31SDevang Patel         InsnRange R(RangeBeginMI, PrevMI);
101e1649c31SDevang Patel         MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
102e1649c31SDevang Patel         MIRanges.push_back(R);
103e1649c31SDevang Patel       }
104e1649c31SDevang Patel 
105e1649c31SDevang Patel       // This is a beginning of a new instruction range.
106f74bde67SAlexey Samsonov       RangeBeginMI = &MInsn;
107e1649c31SDevang Patel 
108e1649c31SDevang Patel       // Reset previous markers.
109f74bde67SAlexey Samsonov       PrevMI = &MInsn;
110e1649c31SDevang Patel       PrevDL = MIDL;
111e1649c31SDevang Patel     }
112e1649c31SDevang Patel 
113e1649c31SDevang Patel     // Create last instruction range.
1149dffcd04SDuncan P. N. Exon Smith     if (RangeBeginMI && PrevMI && PrevDL) {
115e1649c31SDevang Patel       InsnRange R(RangeBeginMI, PrevMI);
116e1649c31SDevang Patel       MIRanges.push_back(R);
117e1649c31SDevang Patel       MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
118e1649c31SDevang Patel     }
119e1649c31SDevang Patel   }
120e1649c31SDevang Patel }
121e1649c31SDevang Patel 
122e1649c31SDevang Patel /// findLexicalScope - Find lexical scope, either regular or inlined, for the
123e1649c31SDevang Patel /// given DebugLoc. Return NULL if not found.
findLexicalScope(const DILocation * DL)124a9308c49SDuncan P. N. Exon Smith LexicalScope *LexicalScopes::findLexicalScope(const DILocation *DL) {
125a9308c49SDuncan P. N. Exon Smith   DILocalScope *Scope = DL->getScope();
1266211e4b9SEric Christopher   if (!Scope)
127c0196b1bSCraig Topper     return nullptr;
1286647b830SEric Christopher 
1296647b830SEric Christopher   // The scope that we were created with could have an extra file - which
1306647b830SEric Christopher   // isn't what we care about in this case.
131a5ba9914SAmjad Aboud   Scope = Scope->getNonLexicalBlockFileScope();
1326647b830SEric Christopher 
1335a227fffSDuncan P. N. Exon Smith   if (auto *IA = DL->getInlinedAt()) {
1349b8c8cdaSDavid Blaikie     auto I = InlinedLexicalScopeMap.find(std::make_pair(Scope, IA));
1359b8c8cdaSDavid Blaikie     return I != InlinedLexicalScopeMap.end() ? &I->second : nullptr;
1369b8c8cdaSDavid Blaikie   }
1372f143e0cSDavid Blaikie   return findLexicalScope(Scope);
138e1649c31SDevang Patel }
139e1649c31SDevang Patel 
140e1649c31SDevang Patel /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
141e1649c31SDevang Patel /// not available then create new lexical scope.
getOrCreateLexicalScope(const DILocalScope * Scope,const DILocation * IA)142a9308c49SDuncan P. N. Exon Smith LexicalScope *LexicalScopes::getOrCreateLexicalScope(const DILocalScope *Scope,
143a9308c49SDuncan P. N. Exon Smith                                                      const DILocation *IA) {
14482eba746SDuncan P. N. Exon Smith   if (IA) {
14576b5b749STeresa Johnson     // Skip scopes inlined from a NoDebug compile unit.
14676b5b749STeresa Johnson     if (Scope->getSubprogram()->getUnit()->getEmissionKind() ==
14776b5b749STeresa Johnson         DICompileUnit::NoDebug)
14876b5b749STeresa Johnson       return getOrCreateLexicalScope(IA);
149e1649c31SDevang Patel     // Create an abstract scope for inlined function.
150e1649c31SDevang Patel     getOrCreateAbstractScope(Scope);
151e1649c31SDevang Patel     // Create an inlined scope for inlined function.
15282eba746SDuncan P. N. Exon Smith     return getOrCreateInlinedScope(Scope, IA);
153e1649c31SDevang Patel   }
154e1649c31SDevang Patel 
155e1649c31SDevang Patel   return getOrCreateRegularScope(Scope);
156e1649c31SDevang Patel }
157e1649c31SDevang Patel 
158e1649c31SDevang Patel /// getOrCreateRegularScope - Find or create a regular lexical scope.
15933af7a8fSDuncan P. N. Exon Smith LexicalScope *
getOrCreateRegularScope(const DILocalScope * Scope)160a9308c49SDuncan P. N. Exon Smith LexicalScopes::getOrCreateRegularScope(const DILocalScope *Scope) {
161a5ba9914SAmjad Aboud   assert(Scope && "Invalid Scope encoding!");
162a5ba9914SAmjad Aboud   Scope = Scope->getNonLexicalBlockFileScope();
1636647b830SEric Christopher 
1642f143e0cSDavid Blaikie   auto I = LexicalScopeMap.find(Scope);
1652f143e0cSDavid Blaikie   if (I != LexicalScopeMap.end())
1662f143e0cSDavid Blaikie     return &I->second;
167e1649c31SDevang Patel 
168a9308c49SDuncan P. N. Exon Smith   // FIXME: Should the following dyn_cast be DILexicalBlock?
169c0196b1bSCraig Topper   LexicalScope *Parent = nullptr;
170a9308c49SDuncan P. N. Exon Smith   if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
17182eba746SDuncan P. N. Exon Smith     Parent = getOrCreateLexicalScope(Block->getScope());
172f17583eeSAaron Ballman   I = LexicalScopeMap.emplace(std::piecewise_construct,
173f17583eeSAaron Ballman                               std::forward_as_tuple(Scope),
17433af7a8fSDuncan P. N. Exon Smith                               std::forward_as_tuple(Parent, Scope, nullptr,
17533af7a8fSDuncan P. N. Exon Smith                                                     false)).first;
1762f143e0cSDavid Blaikie 
1773dfe4788SDavid Blaikie   if (!Parent) {
178f1caa283SMatthias Braun     assert(cast<DISubprogram>(Scope)->describes(&MF->getFunction()));
1793dfe4788SDavid Blaikie     assert(!CurrentFnLexicalScope);
1802f143e0cSDavid Blaikie     CurrentFnLexicalScope = &I->second;
1813dfe4788SDavid Blaikie   }
182e1649c31SDevang Patel 
1832f143e0cSDavid Blaikie   return &I->second;
184e1649c31SDevang Patel }
185e1649c31SDevang Patel 
186e1649c31SDevang Patel /// getOrCreateInlinedScope - Find or create an inlined lexical scope.
18733af7a8fSDuncan P. N. Exon Smith LexicalScope *
getOrCreateInlinedScope(const DILocalScope * Scope,const DILocation * InlinedAt)188a9308c49SDuncan P. N. Exon Smith LexicalScopes::getOrCreateInlinedScope(const DILocalScope *Scope,
189a9308c49SDuncan P. N. Exon Smith                                        const DILocation *InlinedAt) {
190a5ba9914SAmjad Aboud   assert(Scope && "Invalid Scope encoding!");
191a5ba9914SAmjad Aboud   Scope = Scope->getNonLexicalBlockFileScope();
192a9308c49SDuncan P. N. Exon Smith   std::pair<const DILocalScope *, const DILocation *> P(Scope, InlinedAt);
1939b8c8cdaSDavid Blaikie   auto I = InlinedLexicalScopeMap.find(P);
1949b8c8cdaSDavid Blaikie   if (I != InlinedLexicalScopeMap.end())
1952f143e0cSDavid Blaikie     return &I->second;
196e1649c31SDevang Patel 
1979b8c8cdaSDavid Blaikie   LexicalScope *Parent;
198a9308c49SDuncan P. N. Exon Smith   if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
19933af7a8fSDuncan P. N. Exon Smith     Parent = getOrCreateInlinedScope(Block->getScope(), InlinedAt);
2009b8c8cdaSDavid Blaikie   else
20133af7a8fSDuncan P. N. Exon Smith     Parent = getOrCreateLexicalScope(InlinedAt);
2029b8c8cdaSDavid Blaikie 
20314303d18SEric Christopher   I = InlinedLexicalScopeMap
20414303d18SEric Christopher           .emplace(std::piecewise_construct, std::forward_as_tuple(P),
20514303d18SEric Christopher                    std::forward_as_tuple(Parent, Scope, InlinedAt, false))
206f17583eeSAaron Ballman           .first;
2072f143e0cSDavid Blaikie   return &I->second;
208e1649c31SDevang Patel }
209e1649c31SDevang Patel 
210e1649c31SDevang Patel /// getOrCreateAbstractScope - Find or create an abstract lexical scope.
21133af7a8fSDuncan P. N. Exon Smith LexicalScope *
getOrCreateAbstractScope(const DILocalScope * Scope)212a9308c49SDuncan P. N. Exon Smith LexicalScopes::getOrCreateAbstractScope(const DILocalScope *Scope) {
21333af7a8fSDuncan P. N. Exon Smith   assert(Scope && "Invalid Scope encoding!");
214a5ba9914SAmjad Aboud   Scope = Scope->getNonLexicalBlockFileScope();
215ea862267SDavid Blaikie   auto I = AbstractScopeMap.find(Scope);
2162f143e0cSDavid Blaikie   if (I != AbstractScopeMap.end())
2172f143e0cSDavid Blaikie     return &I->second;
218e1649c31SDevang Patel 
219a9308c49SDuncan P. N. Exon Smith   // FIXME: Should the following isa be DILexicalBlock?
220c0196b1bSCraig Topper   LexicalScope *Parent = nullptr;
221a9308c49SDuncan P. N. Exon Smith   if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
22233af7a8fSDuncan P. N. Exon Smith     Parent = getOrCreateAbstractScope(Block->getScope());
22333af7a8fSDuncan P. N. Exon Smith 
2242f143e0cSDavid Blaikie   I = AbstractScopeMap.emplace(std::piecewise_construct,
225ea862267SDavid Blaikie                                std::forward_as_tuple(Scope),
226ea862267SDavid Blaikie                                std::forward_as_tuple(Parent, Scope,
2272f143e0cSDavid Blaikie                                                      nullptr, true)).first;
228a9308c49SDuncan P. N. Exon Smith   if (isa<DISubprogram>(Scope))
2292f143e0cSDavid Blaikie     AbstractScopesList.push_back(&I->second);
2302f143e0cSDavid Blaikie   return &I->second;
231e1649c31SDevang Patel }
232e1649c31SDevang Patel 
2333610d31eSJan-Willem Maessen /// constructScopeNest - Traverse the Scope tree depth-first, storing
2343610d31eSJan-Willem Maessen /// traversal state in WorkStack and recording the depth-first
2353610d31eSJan-Willem Maessen /// numbering (setDFSIn, setDFSOut) for edge classification.
constructScopeNest(LexicalScope * Scope)236e1649c31SDevang Patel void LexicalScopes::constructScopeNest(LexicalScope *Scope) {
237e1649c31SDevang Patel   assert(Scope && "Unable to calculate scope dominance graph!");
2383610d31eSJan-Willem Maessen   SmallVector<std::pair<LexicalScope *, size_t>, 4> WorkStack;
2393610d31eSJan-Willem Maessen   WorkStack.push_back(std::make_pair(Scope, 0));
240e1649c31SDevang Patel   unsigned Counter = 0;
241e1649c31SDevang Patel   while (!WorkStack.empty()) {
2423610d31eSJan-Willem Maessen     auto &ScopePosition = WorkStack.back();
2433610d31eSJan-Willem Maessen     LexicalScope *WS = ScopePosition.first;
2443610d31eSJan-Willem Maessen     size_t ChildNum = ScopePosition.second++;
24580170e54SCraig Topper     const SmallVectorImpl<LexicalScope *> &Children = WS->getChildren();
2463610d31eSJan-Willem Maessen     if (ChildNum < Children.size()) {
2473610d31eSJan-Willem Maessen       auto &ChildScope = Children[ChildNum];
2483610d31eSJan-Willem Maessen       WorkStack.push_back(std::make_pair(ChildScope, 0));
249e1649c31SDevang Patel       ChildScope->setDFSIn(++Counter);
2503610d31eSJan-Willem Maessen     } else {
251e1649c31SDevang Patel       WorkStack.pop_back();
252e1649c31SDevang Patel       WS->setDFSOut(++Counter);
253e1649c31SDevang Patel     }
254e1649c31SDevang Patel   }
255e1649c31SDevang Patel }
256e1649c31SDevang Patel 
257784077ebSDevang Patel /// assignInstructionRanges - Find ranges of instructions covered by each
258784077ebSDevang Patel /// lexical scope.
assignInstructionRanges(SmallVectorImpl<InsnRange> & MIRanges,DenseMap<const MachineInstr *,LexicalScope * > & MI2ScopeMap)2596211e4b9SEric Christopher void LexicalScopes::assignInstructionRanges(
2606211e4b9SEric Christopher     SmallVectorImpl<InsnRange> &MIRanges,
2616211e4b9SEric Christopher     DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) {
262c0196b1bSCraig Topper   LexicalScope *PrevLexicalScope = nullptr;
26316b2ace0SAdrian Prantl   for (const auto &R : MIRanges) {
264e1649c31SDevang Patel     LexicalScope *S = MI2ScopeMap.lookup(R.first);
265e1649c31SDevang Patel     assert(S && "Lost LexicalScope for a machine instruction!");
266e1649c31SDevang Patel     if (PrevLexicalScope && !PrevLexicalScope->dominates(S))
267e1649c31SDevang Patel       PrevLexicalScope->closeInsnRange(S);
268e1649c31SDevang Patel     S->openInsnRange(R.first);
269e1649c31SDevang Patel     S->extendInsnRange(R.second);
270e1649c31SDevang Patel     PrevLexicalScope = S;
271e1649c31SDevang Patel   }
272e1649c31SDevang Patel 
273e1649c31SDevang Patel   if (PrevLexicalScope)
274e1649c31SDevang Patel     PrevLexicalScope->closeInsnRange();
275e1649c31SDevang Patel }
276e1649c31SDevang Patel 
277e1649c31SDevang Patel /// getMachineBasicBlocks - Populate given set using machine basic blocks which
278e1649c31SDevang Patel /// have machine instructions that belong to lexical scope identified by
279e1649c31SDevang Patel /// DebugLoc.
getMachineBasicBlocks(const DILocation * DL,SmallPtrSetImpl<const MachineBasicBlock * > & MBBs)2806211e4b9SEric Christopher void LexicalScopes::getMachineBasicBlocks(
281a9308c49SDuncan P. N. Exon Smith     const DILocation *DL, SmallPtrSetImpl<const MachineBasicBlock *> &MBBs) {
282e018bbd8SWolfgang Pieb   assert(MF && "Method called on a uninitialized LexicalScopes object!");
283e1649c31SDevang Patel   MBBs.clear();
284e018bbd8SWolfgang Pieb 
285e1649c31SDevang Patel   LexicalScope *Scope = getOrCreateLexicalScope(DL);
286e1649c31SDevang Patel   if (!Scope)
287e1649c31SDevang Patel     return;
288e1649c31SDevang Patel 
289db4374a2SDevang Patel   if (Scope == CurrentFnLexicalScope) {
29041b977dfSAlexey Samsonov     for (const auto &MBB : *MF)
29141b977dfSAlexey Samsonov       MBBs.insert(&MBB);
292db4374a2SDevang Patel     return;
293db4374a2SDevang Patel   }
294db4374a2SDevang Patel 
2956af859dcSJeremy Morse   // The scope ranges can cover multiple basic blocks in each span. Iterate over
2966af859dcSJeremy Morse   // all blocks (in the order they are in the function) until we reach the one
2976af859dcSJeremy Morse   // containing the end of the span.
29880170e54SCraig Topper   SmallVectorImpl<InsnRange> &InsnRanges = Scope->getRanges();
29916b2ace0SAdrian Prantl   for (auto &R : InsnRanges)
3006af859dcSJeremy Morse     for (auto CurMBBIt = R.first->getParent()->getIterator(),
3016af859dcSJeremy Morse               EndBBIt = std::next(R.second->getParent()->getIterator());
3026af859dcSJeremy Morse          CurMBBIt != EndBBIt; CurMBBIt++)
3036af859dcSJeremy Morse       MBBs.insert(&*CurMBBIt);
304e1649c31SDevang Patel }
305e1649c31SDevang Patel 
dominates(const DILocation * DL,MachineBasicBlock * MBB)306a9308c49SDuncan P. N. Exon Smith bool LexicalScopes::dominates(const DILocation *DL, MachineBasicBlock *MBB) {
307e018bbd8SWolfgang Pieb   assert(MF && "Unexpected uninitialized LexicalScopes object!");
308e1649c31SDevang Patel   LexicalScope *Scope = getOrCreateLexicalScope(DL);
309e1649c31SDevang Patel   if (!Scope)
310e1649c31SDevang Patel     return false;
311db4374a2SDevang Patel 
312db4374a2SDevang Patel   // Current function scope covers all basic blocks in the function.
313db4374a2SDevang Patel   if (Scope == CurrentFnLexicalScope && MBB->getParent() == MF)
314db4374a2SDevang Patel     return true;
315db4374a2SDevang Patel 
3166af859dcSJeremy Morse   // Fetch all the blocks in DLs scope. Because the range / block list also
31719876268SVedant Kumar   // contain any subscopes, any instruction that DL dominates can be found in
31819876268SVedant Kumar   // the block set.
31919876268SVedant Kumar   //
32019876268SVedant Kumar   // Cache the set of fetched blocks to avoid repeatedly recomputing the set in
32119876268SVedant Kumar   // the LiveDebugValues pass.
32219876268SVedant Kumar   std::unique_ptr<BlockSetT> &Set = DominatedBlocks[DL];
32319876268SVedant Kumar   if (!Set) {
32419876268SVedant Kumar     Set = std::make_unique<BlockSetT>();
32519876268SVedant Kumar     getMachineBasicBlocks(DL, *Set);
32619876268SVedant Kumar   }
327b7c5e0b0SKazu Hirata   return Set->contains(MBB);
328e1649c31SDevang Patel }
329e1649c31SDevang Patel 
330615eb470SAaron Ballman #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump(unsigned Indent) const3318c209aa8SMatthias Braun LLVM_DUMP_METHOD void LexicalScope::dump(unsigned Indent) const {
332e1649c31SDevang Patel   raw_ostream &err = dbgs();
333e498b25bSManman Ren   err.indent(Indent);
334e1649c31SDevang Patel   err << "DFSIn: " << DFSIn << " DFSOut: " << DFSOut << "\n";
335e1649c31SDevang Patel   const MDNode *N = Desc;
336e498b25bSManman Ren   err.indent(Indent);
337e1649c31SDevang Patel   N->dump();
338e1649c31SDevang Patel   if (AbstractScope)
339e498b25bSManman Ren     err << std::string(Indent, ' ') << "Abstract Scope\n";
340e1649c31SDevang Patel 
341e1649c31SDevang Patel   if (!Children.empty())
342e498b25bSManman Ren     err << std::string(Indent + 2, ' ') << "Children ...\n";
343e1649c31SDevang Patel   for (unsigned i = 0, e = Children.size(); i != e; ++i)
344e1649c31SDevang Patel     if (Children[i] != this)
345e498b25bSManman Ren       Children[i]->dump(Indent + 2);
346e1649c31SDevang Patel }
3478c209aa8SMatthias Braun #endif
348