xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/LexicalScopes.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- LexicalScopes.cpp - Collecting lexical scope info ------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements LexicalScopes analysis.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric // This pass collects lexical scope information and maps machine instructions
120b57cec5SDimitry Andric // to respective lexical scopes.
130b57cec5SDimitry Andric //
140b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "llvm/CodeGen/LexicalScopes.h"
170b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
180b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
190b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
200b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
210b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
220b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
230b57cec5SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
248bcb0991SDimitry Andric #include "llvm/IR/Function.h"
250b57cec5SDimitry Andric #include "llvm/IR/Metadata.h"
260b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
270b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
280b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
290b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
300b57cec5SDimitry Andric #include <cassert>
310b57cec5SDimitry Andric #include <string>
320b57cec5SDimitry Andric #include <tuple>
330b57cec5SDimitry Andric #include <utility>
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric using namespace llvm;
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric #define DEBUG_TYPE "lexicalscopes"
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric /// reset - Reset the instance so that it's prepared for another function.
400b57cec5SDimitry Andric void LexicalScopes::reset() {
410b57cec5SDimitry Andric   MF = nullptr;
420b57cec5SDimitry Andric   CurrentFnLexicalScope = nullptr;
430b57cec5SDimitry Andric   LexicalScopeMap.clear();
440b57cec5SDimitry Andric   AbstractScopeMap.clear();
450b57cec5SDimitry Andric   InlinedLexicalScopeMap.clear();
460b57cec5SDimitry Andric   AbstractScopesList.clear();
475ffd83dbSDimitry Andric   DominatedBlocks.clear();
480b57cec5SDimitry Andric }
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric /// initialize - Scan machine function and constuct lexical scope nest.
510b57cec5SDimitry Andric void LexicalScopes::initialize(const MachineFunction &Fn) {
520b57cec5SDimitry Andric   reset();
530b57cec5SDimitry Andric   // Don't attempt any lexical scope creation for a NoDebug compile unit.
540b57cec5SDimitry Andric   if (Fn.getFunction().getSubprogram()->getUnit()->getEmissionKind() ==
550b57cec5SDimitry Andric       DICompileUnit::NoDebug)
560b57cec5SDimitry Andric     return;
570b57cec5SDimitry Andric   MF = &Fn;
580b57cec5SDimitry Andric   SmallVector<InsnRange, 4> MIRanges;
590b57cec5SDimitry Andric   DenseMap<const MachineInstr *, LexicalScope *> MI2ScopeMap;
600b57cec5SDimitry Andric   extractLexicalScopes(MIRanges, MI2ScopeMap);
610b57cec5SDimitry Andric   if (CurrentFnLexicalScope) {
620b57cec5SDimitry Andric     constructScopeNest(CurrentFnLexicalScope);
630b57cec5SDimitry Andric     assignInstructionRanges(MIRanges, MI2ScopeMap);
640b57cec5SDimitry Andric   }
650b57cec5SDimitry Andric }
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric /// extractLexicalScopes - Extract instruction ranges for each lexical scopes
680b57cec5SDimitry Andric /// for the given machine function.
690b57cec5SDimitry Andric void LexicalScopes::extractLexicalScopes(
700b57cec5SDimitry Andric     SmallVectorImpl<InsnRange> &MIRanges,
710b57cec5SDimitry Andric     DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) {
720b57cec5SDimitry Andric   // Scan each instruction and create scopes. First build working set of scopes.
730b57cec5SDimitry Andric   for (const auto &MBB : *MF) {
740b57cec5SDimitry Andric     const MachineInstr *RangeBeginMI = nullptr;
750b57cec5SDimitry Andric     const MachineInstr *PrevMI = nullptr;
760b57cec5SDimitry Andric     const DILocation *PrevDL = nullptr;
770b57cec5SDimitry Andric     for (const auto &MInsn : MBB) {
78fe6060f1SDimitry Andric       // Ignore DBG_VALUE and similar instruction that do not contribute to any
79fe6060f1SDimitry Andric       // instruction in the output.
80fe6060f1SDimitry Andric       if (MInsn.isMetaInstruction())
81fe6060f1SDimitry Andric         continue;
82fe6060f1SDimitry Andric 
830b57cec5SDimitry Andric       // Check if instruction has valid location information.
840b57cec5SDimitry Andric       const DILocation *MIDL = MInsn.getDebugLoc();
850b57cec5SDimitry Andric       if (!MIDL) {
860b57cec5SDimitry Andric         PrevMI = &MInsn;
870b57cec5SDimitry Andric         continue;
880b57cec5SDimitry Andric       }
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric       // If scope has not changed then skip this instruction.
910b57cec5SDimitry Andric       if (MIDL == PrevDL) {
920b57cec5SDimitry Andric         PrevMI = &MInsn;
930b57cec5SDimitry Andric         continue;
940b57cec5SDimitry Andric       }
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric       if (RangeBeginMI) {
970b57cec5SDimitry Andric         // If we have already seen a beginning of an instruction range and
980b57cec5SDimitry Andric         // current instruction scope does not match scope of first instruction
990b57cec5SDimitry Andric         // in this range then create a new instruction range.
1000b57cec5SDimitry Andric         InsnRange R(RangeBeginMI, PrevMI);
1010b57cec5SDimitry Andric         MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
1020b57cec5SDimitry Andric         MIRanges.push_back(R);
1030b57cec5SDimitry Andric       }
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric       // This is a beginning of a new instruction range.
1060b57cec5SDimitry Andric       RangeBeginMI = &MInsn;
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric       // Reset previous markers.
1090b57cec5SDimitry Andric       PrevMI = &MInsn;
1100b57cec5SDimitry Andric       PrevDL = MIDL;
1110b57cec5SDimitry Andric     }
1120b57cec5SDimitry Andric 
1130b57cec5SDimitry Andric     // Create last instruction range.
1140b57cec5SDimitry Andric     if (RangeBeginMI && PrevMI && PrevDL) {
1150b57cec5SDimitry Andric       InsnRange R(RangeBeginMI, PrevMI);
1160b57cec5SDimitry Andric       MIRanges.push_back(R);
1170b57cec5SDimitry Andric       MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
1180b57cec5SDimitry Andric     }
1190b57cec5SDimitry Andric   }
1200b57cec5SDimitry Andric }
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric /// findLexicalScope - Find lexical scope, either regular or inlined, for the
1230b57cec5SDimitry Andric /// given DebugLoc. Return NULL if not found.
1240b57cec5SDimitry Andric LexicalScope *LexicalScopes::findLexicalScope(const DILocation *DL) {
1250b57cec5SDimitry Andric   DILocalScope *Scope = DL->getScope();
1260b57cec5SDimitry Andric   if (!Scope)
1270b57cec5SDimitry Andric     return nullptr;
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric   // The scope that we were created with could have an extra file - which
1300b57cec5SDimitry Andric   // isn't what we care about in this case.
1310b57cec5SDimitry Andric   Scope = Scope->getNonLexicalBlockFileScope();
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric   if (auto *IA = DL->getInlinedAt()) {
1340b57cec5SDimitry Andric     auto I = InlinedLexicalScopeMap.find(std::make_pair(Scope, IA));
1350b57cec5SDimitry Andric     return I != InlinedLexicalScopeMap.end() ? &I->second : nullptr;
1360b57cec5SDimitry Andric   }
1370b57cec5SDimitry Andric   return findLexicalScope(Scope);
1380b57cec5SDimitry Andric }
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
1410b57cec5SDimitry Andric /// not available then create new lexical scope.
1420b57cec5SDimitry Andric LexicalScope *LexicalScopes::getOrCreateLexicalScope(const DILocalScope *Scope,
1430b57cec5SDimitry Andric                                                      const DILocation *IA) {
1440b57cec5SDimitry Andric   if (IA) {
1450b57cec5SDimitry Andric     // Skip scopes inlined from a NoDebug compile unit.
1460b57cec5SDimitry Andric     if (Scope->getSubprogram()->getUnit()->getEmissionKind() ==
1470b57cec5SDimitry Andric         DICompileUnit::NoDebug)
1480b57cec5SDimitry Andric       return getOrCreateLexicalScope(IA);
1490b57cec5SDimitry Andric     // Create an abstract scope for inlined function.
1500b57cec5SDimitry Andric     getOrCreateAbstractScope(Scope);
1510b57cec5SDimitry Andric     // Create an inlined scope for inlined function.
1520b57cec5SDimitry Andric     return getOrCreateInlinedScope(Scope, IA);
1530b57cec5SDimitry Andric   }
1540b57cec5SDimitry Andric 
1550b57cec5SDimitry Andric   return getOrCreateRegularScope(Scope);
1560b57cec5SDimitry Andric }
1570b57cec5SDimitry Andric 
1580b57cec5SDimitry Andric /// getOrCreateRegularScope - Find or create a regular lexical scope.
1590b57cec5SDimitry Andric LexicalScope *
1600b57cec5SDimitry Andric LexicalScopes::getOrCreateRegularScope(const DILocalScope *Scope) {
1610b57cec5SDimitry Andric   assert(Scope && "Invalid Scope encoding!");
1620b57cec5SDimitry Andric   Scope = Scope->getNonLexicalBlockFileScope();
1630b57cec5SDimitry Andric 
1640b57cec5SDimitry Andric   auto I = LexicalScopeMap.find(Scope);
1650b57cec5SDimitry Andric   if (I != LexicalScopeMap.end())
1660b57cec5SDimitry Andric     return &I->second;
1670b57cec5SDimitry Andric 
1680b57cec5SDimitry Andric   // FIXME: Should the following dyn_cast be DILexicalBlock?
1690b57cec5SDimitry Andric   LexicalScope *Parent = nullptr;
1700b57cec5SDimitry Andric   if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
1710b57cec5SDimitry Andric     Parent = getOrCreateLexicalScope(Block->getScope());
1720b57cec5SDimitry Andric   I = LexicalScopeMap.emplace(std::piecewise_construct,
1730b57cec5SDimitry Andric                               std::forward_as_tuple(Scope),
1740b57cec5SDimitry Andric                               std::forward_as_tuple(Parent, Scope, nullptr,
1750b57cec5SDimitry Andric                                                     false)).first;
1760b57cec5SDimitry Andric 
1770b57cec5SDimitry Andric   if (!Parent) {
1780b57cec5SDimitry Andric     assert(cast<DISubprogram>(Scope)->describes(&MF->getFunction()));
1790b57cec5SDimitry Andric     assert(!CurrentFnLexicalScope);
1800b57cec5SDimitry Andric     CurrentFnLexicalScope = &I->second;
1810b57cec5SDimitry Andric   }
1820b57cec5SDimitry Andric 
1830b57cec5SDimitry Andric   return &I->second;
1840b57cec5SDimitry Andric }
1850b57cec5SDimitry Andric 
1860b57cec5SDimitry Andric /// getOrCreateInlinedScope - Find or create an inlined lexical scope.
1870b57cec5SDimitry Andric LexicalScope *
1880b57cec5SDimitry Andric LexicalScopes::getOrCreateInlinedScope(const DILocalScope *Scope,
1890b57cec5SDimitry Andric                                        const DILocation *InlinedAt) {
1900b57cec5SDimitry Andric   assert(Scope && "Invalid Scope encoding!");
1910b57cec5SDimitry Andric   Scope = Scope->getNonLexicalBlockFileScope();
1920b57cec5SDimitry Andric   std::pair<const DILocalScope *, const DILocation *> P(Scope, InlinedAt);
1930b57cec5SDimitry Andric   auto I = InlinedLexicalScopeMap.find(P);
1940b57cec5SDimitry Andric   if (I != InlinedLexicalScopeMap.end())
1950b57cec5SDimitry Andric     return &I->second;
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric   LexicalScope *Parent;
1980b57cec5SDimitry Andric   if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
1990b57cec5SDimitry Andric     Parent = getOrCreateInlinedScope(Block->getScope(), InlinedAt);
2000b57cec5SDimitry Andric   else
2010b57cec5SDimitry Andric     Parent = getOrCreateLexicalScope(InlinedAt);
2020b57cec5SDimitry Andric 
2030b57cec5SDimitry Andric   I = InlinedLexicalScopeMap
2040b57cec5SDimitry Andric           .emplace(std::piecewise_construct, std::forward_as_tuple(P),
2050b57cec5SDimitry Andric                    std::forward_as_tuple(Parent, Scope, InlinedAt, false))
2060b57cec5SDimitry Andric           .first;
2070b57cec5SDimitry Andric   return &I->second;
2080b57cec5SDimitry Andric }
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric /// getOrCreateAbstractScope - Find or create an abstract lexical scope.
2110b57cec5SDimitry Andric LexicalScope *
2120b57cec5SDimitry Andric LexicalScopes::getOrCreateAbstractScope(const DILocalScope *Scope) {
2130b57cec5SDimitry Andric   assert(Scope && "Invalid Scope encoding!");
2140b57cec5SDimitry Andric   Scope = Scope->getNonLexicalBlockFileScope();
2150b57cec5SDimitry Andric   auto I = AbstractScopeMap.find(Scope);
2160b57cec5SDimitry Andric   if (I != AbstractScopeMap.end())
2170b57cec5SDimitry Andric     return &I->second;
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric   // FIXME: Should the following isa be DILexicalBlock?
2200b57cec5SDimitry Andric   LexicalScope *Parent = nullptr;
2210b57cec5SDimitry Andric   if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
2220b57cec5SDimitry Andric     Parent = getOrCreateAbstractScope(Block->getScope());
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric   I = AbstractScopeMap.emplace(std::piecewise_construct,
2250b57cec5SDimitry Andric                                std::forward_as_tuple(Scope),
2260b57cec5SDimitry Andric                                std::forward_as_tuple(Parent, Scope,
2270b57cec5SDimitry Andric                                                      nullptr, true)).first;
2280b57cec5SDimitry Andric   if (isa<DISubprogram>(Scope))
2290b57cec5SDimitry Andric     AbstractScopesList.push_back(&I->second);
2300b57cec5SDimitry Andric   return &I->second;
2310b57cec5SDimitry Andric }
2320b57cec5SDimitry Andric 
2335ffd83dbSDimitry Andric /// constructScopeNest - Traverse the Scope tree depth-first, storing
2345ffd83dbSDimitry Andric /// traversal state in WorkStack and recording the depth-first
2355ffd83dbSDimitry Andric /// numbering (setDFSIn, setDFSOut) for edge classification.
2360b57cec5SDimitry Andric void LexicalScopes::constructScopeNest(LexicalScope *Scope) {
2370b57cec5SDimitry Andric   assert(Scope && "Unable to calculate scope dominance graph!");
2385ffd83dbSDimitry Andric   SmallVector<std::pair<LexicalScope *, size_t>, 4> WorkStack;
2395ffd83dbSDimitry Andric   WorkStack.push_back(std::make_pair(Scope, 0));
2400b57cec5SDimitry Andric   unsigned Counter = 0;
2410b57cec5SDimitry Andric   while (!WorkStack.empty()) {
2425ffd83dbSDimitry Andric     auto &ScopePosition = WorkStack.back();
2435ffd83dbSDimitry Andric     LexicalScope *WS = ScopePosition.first;
2445ffd83dbSDimitry Andric     size_t ChildNum = ScopePosition.second++;
2450b57cec5SDimitry Andric     const SmallVectorImpl<LexicalScope *> &Children = WS->getChildren();
2465ffd83dbSDimitry Andric     if (ChildNum < Children.size()) {
2475ffd83dbSDimitry Andric       auto &ChildScope = Children[ChildNum];
2485ffd83dbSDimitry Andric       WorkStack.push_back(std::make_pair(ChildScope, 0));
2490b57cec5SDimitry Andric       ChildScope->setDFSIn(++Counter);
2505ffd83dbSDimitry Andric     } else {
2510b57cec5SDimitry Andric       WorkStack.pop_back();
2520b57cec5SDimitry Andric       WS->setDFSOut(++Counter);
2530b57cec5SDimitry Andric     }
2540b57cec5SDimitry Andric   }
2550b57cec5SDimitry Andric }
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric /// assignInstructionRanges - Find ranges of instructions covered by each
2580b57cec5SDimitry Andric /// lexical scope.
2590b57cec5SDimitry Andric void LexicalScopes::assignInstructionRanges(
2600b57cec5SDimitry Andric     SmallVectorImpl<InsnRange> &MIRanges,
2610b57cec5SDimitry Andric     DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) {
2620b57cec5SDimitry Andric   LexicalScope *PrevLexicalScope = nullptr;
2630b57cec5SDimitry Andric   for (const auto &R : MIRanges) {
2640b57cec5SDimitry Andric     LexicalScope *S = MI2ScopeMap.lookup(R.first);
2650b57cec5SDimitry Andric     assert(S && "Lost LexicalScope for a machine instruction!");
2660b57cec5SDimitry Andric     if (PrevLexicalScope && !PrevLexicalScope->dominates(S))
2670b57cec5SDimitry Andric       PrevLexicalScope->closeInsnRange(S);
2680b57cec5SDimitry Andric     S->openInsnRange(R.first);
2690b57cec5SDimitry Andric     S->extendInsnRange(R.second);
2700b57cec5SDimitry Andric     PrevLexicalScope = S;
2710b57cec5SDimitry Andric   }
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric   if (PrevLexicalScope)
2740b57cec5SDimitry Andric     PrevLexicalScope->closeInsnRange();
2750b57cec5SDimitry Andric }
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric /// getMachineBasicBlocks - Populate given set using machine basic blocks which
2780b57cec5SDimitry Andric /// have machine instructions that belong to lexical scope identified by
2790b57cec5SDimitry Andric /// DebugLoc.
2800b57cec5SDimitry Andric void LexicalScopes::getMachineBasicBlocks(
2810b57cec5SDimitry Andric     const DILocation *DL, SmallPtrSetImpl<const MachineBasicBlock *> &MBBs) {
2820b57cec5SDimitry Andric   assert(MF && "Method called on a uninitialized LexicalScopes object!");
2830b57cec5SDimitry Andric   MBBs.clear();
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric   LexicalScope *Scope = getOrCreateLexicalScope(DL);
2860b57cec5SDimitry Andric   if (!Scope)
2870b57cec5SDimitry Andric     return;
2880b57cec5SDimitry Andric 
2890b57cec5SDimitry Andric   if (Scope == CurrentFnLexicalScope) {
2900b57cec5SDimitry Andric     for (const auto &MBB : *MF)
2910b57cec5SDimitry Andric       MBBs.insert(&MBB);
2920b57cec5SDimitry Andric     return;
2930b57cec5SDimitry Andric   }
2940b57cec5SDimitry Andric 
2955ffd83dbSDimitry Andric   // The scope ranges can cover multiple basic blocks in each span. Iterate over
2965ffd83dbSDimitry Andric   // all blocks (in the order they are in the function) until we reach the one
2975ffd83dbSDimitry Andric   // containing the end of the span.
2980b57cec5SDimitry Andric   SmallVectorImpl<InsnRange> &InsnRanges = Scope->getRanges();
2990b57cec5SDimitry Andric   for (auto &R : InsnRanges)
3005ffd83dbSDimitry Andric     for (auto CurMBBIt = R.first->getParent()->getIterator(),
3015ffd83dbSDimitry Andric               EndBBIt = std::next(R.second->getParent()->getIterator());
3025ffd83dbSDimitry Andric          CurMBBIt != EndBBIt; CurMBBIt++)
3035ffd83dbSDimitry Andric       MBBs.insert(&*CurMBBIt);
3040b57cec5SDimitry Andric }
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric bool LexicalScopes::dominates(const DILocation *DL, MachineBasicBlock *MBB) {
3070b57cec5SDimitry Andric   assert(MF && "Unexpected uninitialized LexicalScopes object!");
3080b57cec5SDimitry Andric   LexicalScope *Scope = getOrCreateLexicalScope(DL);
3090b57cec5SDimitry Andric   if (!Scope)
3100b57cec5SDimitry Andric     return false;
3110b57cec5SDimitry Andric 
3120b57cec5SDimitry Andric   // Current function scope covers all basic blocks in the function.
3130b57cec5SDimitry Andric   if (Scope == CurrentFnLexicalScope && MBB->getParent() == MF)
3140b57cec5SDimitry Andric     return true;
3150b57cec5SDimitry Andric 
3165ffd83dbSDimitry Andric   // Fetch all the blocks in DLs scope. Because the range / block list also
3175ffd83dbSDimitry Andric   // contain any subscopes, any instruction that DL dominates can be found in
3185ffd83dbSDimitry Andric   // the block set.
3195ffd83dbSDimitry Andric   //
3205ffd83dbSDimitry Andric   // Cache the set of fetched blocks to avoid repeatedly recomputing the set in
3215ffd83dbSDimitry Andric   // the LiveDebugValues pass.
3225ffd83dbSDimitry Andric   std::unique_ptr<BlockSetT> &Set = DominatedBlocks[DL];
3235ffd83dbSDimitry Andric   if (!Set) {
3245ffd83dbSDimitry Andric     Set = std::make_unique<BlockSetT>();
3255ffd83dbSDimitry Andric     getMachineBasicBlocks(DL, *Set);
3260b57cec5SDimitry Andric   }
327e8d8bef9SDimitry Andric   return Set->contains(MBB);
3280b57cec5SDimitry Andric }
3290b57cec5SDimitry Andric 
3300b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3310b57cec5SDimitry Andric LLVM_DUMP_METHOD void LexicalScope::dump(unsigned Indent) const {
3320b57cec5SDimitry Andric   raw_ostream &err = dbgs();
3330b57cec5SDimitry Andric   err.indent(Indent);
3340b57cec5SDimitry Andric   err << "DFSIn: " << DFSIn << " DFSOut: " << DFSOut << "\n";
3350b57cec5SDimitry Andric   const MDNode *N = Desc;
3360b57cec5SDimitry Andric   err.indent(Indent);
3370b57cec5SDimitry Andric   N->dump();
3380b57cec5SDimitry Andric   if (AbstractScope)
3390b57cec5SDimitry Andric     err << std::string(Indent, ' ') << "Abstract Scope\n";
3400b57cec5SDimitry Andric 
3410b57cec5SDimitry Andric   if (!Children.empty())
3420b57cec5SDimitry Andric     err << std::string(Indent + 2, ' ') << "Children ...\n";
343*0fca6ea1SDimitry Andric   for (const LexicalScope *Child : Children)
344*0fca6ea1SDimitry Andric     if (Child != this)
345*0fca6ea1SDimitry Andric       Child->dump(Indent + 2);
3460b57cec5SDimitry Andric }
3470b57cec5SDimitry Andric #endif
348