16122f3e6SDimitry Andric //===- LexicalScopes.cpp - Collecting lexical scope info ------------------===//
26122f3e6SDimitry Andric //
36122f3e6SDimitry Andric //                     The LLVM Compiler Infrastructure
46122f3e6SDimitry Andric //
56122f3e6SDimitry Andric // This file is distributed under the University of Illinois Open Source
66122f3e6SDimitry Andric // License. See LICENSE.TXT for details.
76122f3e6SDimitry Andric //
86122f3e6SDimitry Andric //===----------------------------------------------------------------------===//
96122f3e6SDimitry Andric //
106122f3e6SDimitry Andric // This file implements LexicalScopes analysis.
116122f3e6SDimitry Andric //
126122f3e6SDimitry Andric // This pass collects lexical scope information and maps machine instructions
136122f3e6SDimitry Andric // to respective lexical scopes.
146122f3e6SDimitry Andric //
156122f3e6SDimitry Andric //===----------------------------------------------------------------------===//
166122f3e6SDimitry Andric 
17db17bf38SDimitry Andric #include "llvm/CodeGen/LexicalScopes.h"
187a7e6055SDimitry Andric #include "llvm/ADT/DenseMap.h"
197a7e6055SDimitry Andric #include "llvm/ADT/SmallVector.h"
207a7e6055SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
216122f3e6SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
226122f3e6SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
23*4ba319b5SDimitry Andric #include "llvm/Config/llvm-config.h"
247a7e6055SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
257a7e6055SDimitry Andric #include "llvm/IR/Metadata.h"
267a7e6055SDimitry Andric #include "llvm/Support/Casting.h"
277a7e6055SDimitry Andric #include "llvm/Support/Compiler.h"
286122f3e6SDimitry Andric #include "llvm/Support/Debug.h"
297a7e6055SDimitry Andric #include "llvm/Support/raw_ostream.h"
307a7e6055SDimitry Andric #include <cassert>
317a7e6055SDimitry Andric #include <string>
327a7e6055SDimitry Andric #include <tuple>
337a7e6055SDimitry Andric #include <utility>
347a7e6055SDimitry Andric 
356122f3e6SDimitry Andric using namespace llvm;
366122f3e6SDimitry Andric 
3791bc56edSDimitry Andric #define DEBUG_TYPE "lexicalscopes"
386122f3e6SDimitry Andric 
3991bc56edSDimitry Andric /// reset - Reset the instance so that it's prepared for another function.
reset()4091bc56edSDimitry Andric void LexicalScopes::reset() {
4191bc56edSDimitry Andric   MF = nullptr;
4291bc56edSDimitry Andric   CurrentFnLexicalScope = nullptr;
4391bc56edSDimitry Andric   LexicalScopeMap.clear();
4491bc56edSDimitry Andric   AbstractScopeMap.clear();
456122f3e6SDimitry Andric   InlinedLexicalScopeMap.clear();
466122f3e6SDimitry Andric   AbstractScopesList.clear();
476122f3e6SDimitry Andric }
486122f3e6SDimitry Andric 
496122f3e6SDimitry Andric /// initialize - Scan machine function and constuct lexical scope nest.
initialize(const MachineFunction & Fn)506122f3e6SDimitry Andric void LexicalScopes::initialize(const MachineFunction &Fn) {
512cab237bSDimitry Andric   reset();
527a7e6055SDimitry Andric   // Don't attempt any lexical scope creation for a NoDebug compile unit.
532cab237bSDimitry Andric   if (Fn.getFunction().getSubprogram()->getUnit()->getEmissionKind() ==
547a7e6055SDimitry Andric       DICompileUnit::NoDebug)
557a7e6055SDimitry Andric     return;
566122f3e6SDimitry Andric   MF = &Fn;
576122f3e6SDimitry Andric   SmallVector<InsnRange, 4> MIRanges;
586122f3e6SDimitry Andric   DenseMap<const MachineInstr *, LexicalScope *> MI2ScopeMap;
596122f3e6SDimitry Andric   extractLexicalScopes(MIRanges, MI2ScopeMap);
606122f3e6SDimitry Andric   if (CurrentFnLexicalScope) {
616122f3e6SDimitry Andric     constructScopeNest(CurrentFnLexicalScope);
626122f3e6SDimitry Andric     assignInstructionRanges(MIRanges, MI2ScopeMap);
636122f3e6SDimitry Andric   }
646122f3e6SDimitry Andric }
656122f3e6SDimitry Andric 
666122f3e6SDimitry Andric /// extractLexicalScopes - Extract instruction ranges for each lexical scopes
676122f3e6SDimitry Andric /// for the given machine function.
extractLexicalScopes(SmallVectorImpl<InsnRange> & MIRanges,DenseMap<const MachineInstr *,LexicalScope * > & MI2ScopeMap)6891bc56edSDimitry Andric void LexicalScopes::extractLexicalScopes(
6991bc56edSDimitry Andric     SmallVectorImpl<InsnRange> &MIRanges,
706122f3e6SDimitry Andric     DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) {
716122f3e6SDimitry Andric   // Scan each instruction and create scopes. First build working set of scopes.
7291bc56edSDimitry Andric   for (const auto &MBB : *MF) {
7391bc56edSDimitry Andric     const MachineInstr *RangeBeginMI = nullptr;
7491bc56edSDimitry Andric     const MachineInstr *PrevMI = nullptr;
75ff0cc061SDimitry Andric     const DILocation *PrevDL = nullptr;
7691bc56edSDimitry Andric     for (const auto &MInsn : MBB) {
776122f3e6SDimitry Andric       // Check if instruction has valid location information.
78ff0cc061SDimitry Andric       const DILocation *MIDL = MInsn.getDebugLoc();
79ff0cc061SDimitry Andric       if (!MIDL) {
8091bc56edSDimitry Andric         PrevMI = &MInsn;
816122f3e6SDimitry Andric         continue;
826122f3e6SDimitry Andric       }
836122f3e6SDimitry Andric 
846122f3e6SDimitry Andric       // If scope has not changed then skip this instruction.
856122f3e6SDimitry Andric       if (MIDL == PrevDL) {
8691bc56edSDimitry Andric         PrevMI = &MInsn;
876122f3e6SDimitry Andric         continue;
886122f3e6SDimitry Andric       }
896122f3e6SDimitry Andric 
90302affcbSDimitry Andric       // Ignore DBG_VALUE and similar instruction that do not contribute to any
91302affcbSDimitry Andric       // instruction in the output.
92302affcbSDimitry Andric       if (MInsn.isMetaInstruction())
936122f3e6SDimitry Andric         continue;
946122f3e6SDimitry Andric 
956122f3e6SDimitry Andric       if (RangeBeginMI) {
966122f3e6SDimitry Andric         // If we have already seen a beginning of an instruction range and
976122f3e6SDimitry Andric         // current instruction scope does not match scope of first instruction
986122f3e6SDimitry Andric         // in this range then create a new instruction range.
996122f3e6SDimitry Andric         InsnRange R(RangeBeginMI, PrevMI);
1006122f3e6SDimitry Andric         MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
1016122f3e6SDimitry Andric         MIRanges.push_back(R);
1026122f3e6SDimitry Andric       }
1036122f3e6SDimitry Andric 
1046122f3e6SDimitry Andric       // This is a beginning of a new instruction range.
10591bc56edSDimitry Andric       RangeBeginMI = &MInsn;
1066122f3e6SDimitry Andric 
1076122f3e6SDimitry Andric       // Reset previous markers.
10891bc56edSDimitry Andric       PrevMI = &MInsn;
1096122f3e6SDimitry Andric       PrevDL = MIDL;
1106122f3e6SDimitry Andric     }
1116122f3e6SDimitry Andric 
1126122f3e6SDimitry Andric     // Create last instruction range.
113ff0cc061SDimitry Andric     if (RangeBeginMI && PrevMI && PrevDL) {
1146122f3e6SDimitry Andric       InsnRange R(RangeBeginMI, PrevMI);
1156122f3e6SDimitry Andric       MIRanges.push_back(R);
1166122f3e6SDimitry Andric       MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
1176122f3e6SDimitry Andric     }
1186122f3e6SDimitry Andric   }
1196122f3e6SDimitry Andric }
1206122f3e6SDimitry Andric 
1216122f3e6SDimitry Andric /// findLexicalScope - Find lexical scope, either regular or inlined, for the
1226122f3e6SDimitry Andric /// given DebugLoc. Return NULL if not found.
findLexicalScope(const DILocation * DL)123ff0cc061SDimitry Andric LexicalScope *LexicalScopes::findLexicalScope(const DILocation *DL) {
124ff0cc061SDimitry Andric   DILocalScope *Scope = DL->getScope();
12591bc56edSDimitry Andric   if (!Scope)
12691bc56edSDimitry Andric     return nullptr;
1276122f3e6SDimitry Andric 
1286122f3e6SDimitry Andric   // The scope that we were created with could have an extra file - which
1296122f3e6SDimitry Andric   // isn't what we care about in this case.
1303ca95b02SDimitry Andric   Scope = Scope->getNonLexicalBlockFileScope();
1316122f3e6SDimitry Andric 
132ff0cc061SDimitry Andric   if (auto *IA = DL->getInlinedAt()) {
13391bc56edSDimitry Andric     auto I = InlinedLexicalScopeMap.find(std::make_pair(Scope, IA));
13491bc56edSDimitry Andric     return I != InlinedLexicalScopeMap.end() ? &I->second : nullptr;
13591bc56edSDimitry Andric   }
13691bc56edSDimitry Andric   return findLexicalScope(Scope);
1376122f3e6SDimitry Andric }
1386122f3e6SDimitry Andric 
1396122f3e6SDimitry Andric /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
1406122f3e6SDimitry Andric /// not available then create new lexical scope.
getOrCreateLexicalScope(const DILocalScope * Scope,const DILocation * IA)141ff0cc061SDimitry Andric LexicalScope *LexicalScopes::getOrCreateLexicalScope(const DILocalScope *Scope,
142ff0cc061SDimitry Andric                                                      const DILocation *IA) {
143ff0cc061SDimitry Andric   if (IA) {
1447a7e6055SDimitry Andric     // Skip scopes inlined from a NoDebug compile unit.
1457a7e6055SDimitry Andric     if (Scope->getSubprogram()->getUnit()->getEmissionKind() ==
1467a7e6055SDimitry Andric         DICompileUnit::NoDebug)
1477a7e6055SDimitry Andric       return getOrCreateLexicalScope(IA);
1486122f3e6SDimitry Andric     // Create an abstract scope for inlined function.
1496122f3e6SDimitry Andric     getOrCreateAbstractScope(Scope);
1506122f3e6SDimitry Andric     // Create an inlined scope for inlined function.
151ff0cc061SDimitry Andric     return getOrCreateInlinedScope(Scope, IA);
1526122f3e6SDimitry Andric   }
1536122f3e6SDimitry Andric 
1546122f3e6SDimitry Andric   return getOrCreateRegularScope(Scope);
1556122f3e6SDimitry Andric }
1566122f3e6SDimitry Andric 
1576122f3e6SDimitry Andric /// getOrCreateRegularScope - Find or create a regular lexical scope.
158ff0cc061SDimitry Andric LexicalScope *
getOrCreateRegularScope(const DILocalScope * Scope)159ff0cc061SDimitry Andric LexicalScopes::getOrCreateRegularScope(const DILocalScope *Scope) {
1603ca95b02SDimitry Andric   assert(Scope && "Invalid Scope encoding!");
1613ca95b02SDimitry Andric   Scope = Scope->getNonLexicalBlockFileScope();
1626122f3e6SDimitry Andric 
16391bc56edSDimitry Andric   auto I = LexicalScopeMap.find(Scope);
16491bc56edSDimitry Andric   if (I != LexicalScopeMap.end())
16591bc56edSDimitry Andric     return &I->second;
1666122f3e6SDimitry Andric 
167ff0cc061SDimitry Andric   // FIXME: Should the following dyn_cast be DILexicalBlock?
16891bc56edSDimitry Andric   LexicalScope *Parent = nullptr;
169ff0cc061SDimitry Andric   if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
170ff0cc061SDimitry Andric     Parent = getOrCreateLexicalScope(Block->getScope());
171ff0cc061SDimitry Andric   I = LexicalScopeMap.emplace(std::piecewise_construct,
172ff0cc061SDimitry Andric                               std::forward_as_tuple(Scope),
173ff0cc061SDimitry Andric                               std::forward_as_tuple(Parent, Scope, nullptr,
174ff0cc061SDimitry Andric                                                     false)).first;
1756122f3e6SDimitry Andric 
17639d628a0SDimitry Andric   if (!Parent) {
1772cab237bSDimitry Andric     assert(cast<DISubprogram>(Scope)->describes(&MF->getFunction()));
17839d628a0SDimitry Andric     assert(!CurrentFnLexicalScope);
17991bc56edSDimitry Andric     CurrentFnLexicalScope = &I->second;
18039d628a0SDimitry Andric   }
18191bc56edSDimitry Andric 
18291bc56edSDimitry Andric   return &I->second;
1836122f3e6SDimitry Andric }
1846122f3e6SDimitry Andric 
1856122f3e6SDimitry Andric /// getOrCreateInlinedScope - Find or create an inlined lexical scope.
186ff0cc061SDimitry Andric LexicalScope *
getOrCreateInlinedScope(const DILocalScope * Scope,const DILocation * InlinedAt)187ff0cc061SDimitry Andric LexicalScopes::getOrCreateInlinedScope(const DILocalScope *Scope,
188ff0cc061SDimitry Andric                                        const DILocation *InlinedAt) {
1893ca95b02SDimitry Andric   assert(Scope && "Invalid Scope encoding!");
1903ca95b02SDimitry Andric   Scope = Scope->getNonLexicalBlockFileScope();
191ff0cc061SDimitry Andric   std::pair<const DILocalScope *, const DILocation *> P(Scope, InlinedAt);
19291bc56edSDimitry Andric   auto I = InlinedLexicalScopeMap.find(P);
19391bc56edSDimitry Andric   if (I != InlinedLexicalScopeMap.end())
19491bc56edSDimitry Andric     return &I->second;
1956122f3e6SDimitry Andric 
19691bc56edSDimitry Andric   LexicalScope *Parent;
197ff0cc061SDimitry Andric   if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
198ff0cc061SDimitry Andric     Parent = getOrCreateInlinedScope(Block->getScope(), InlinedAt);
19991bc56edSDimitry Andric   else
200ff0cc061SDimitry Andric     Parent = getOrCreateLexicalScope(InlinedAt);
20191bc56edSDimitry Andric 
2027a7e6055SDimitry Andric   I = InlinedLexicalScopeMap
2037a7e6055SDimitry Andric           .emplace(std::piecewise_construct, std::forward_as_tuple(P),
2047a7e6055SDimitry Andric                    std::forward_as_tuple(Parent, Scope, InlinedAt, false))
205ff0cc061SDimitry Andric           .first;
20691bc56edSDimitry Andric   return &I->second;
2076122f3e6SDimitry Andric }
2086122f3e6SDimitry Andric 
2096122f3e6SDimitry Andric /// getOrCreateAbstractScope - Find or create an abstract lexical scope.
210ff0cc061SDimitry Andric LexicalScope *
getOrCreateAbstractScope(const DILocalScope * Scope)211ff0cc061SDimitry Andric LexicalScopes::getOrCreateAbstractScope(const DILocalScope *Scope) {
212ff0cc061SDimitry Andric   assert(Scope && "Invalid Scope encoding!");
2133ca95b02SDimitry Andric   Scope = Scope->getNonLexicalBlockFileScope();
21491bc56edSDimitry Andric   auto I = AbstractScopeMap.find(Scope);
21591bc56edSDimitry Andric   if (I != AbstractScopeMap.end())
21691bc56edSDimitry Andric     return &I->second;
2176122f3e6SDimitry Andric 
218ff0cc061SDimitry Andric   // FIXME: Should the following isa be DILexicalBlock?
21991bc56edSDimitry Andric   LexicalScope *Parent = nullptr;
220ff0cc061SDimitry Andric   if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
221ff0cc061SDimitry Andric     Parent = getOrCreateAbstractScope(Block->getScope());
222ff0cc061SDimitry Andric 
22391bc56edSDimitry Andric   I = AbstractScopeMap.emplace(std::piecewise_construct,
22491bc56edSDimitry Andric                                std::forward_as_tuple(Scope),
22591bc56edSDimitry Andric                                std::forward_as_tuple(Parent, Scope,
22691bc56edSDimitry Andric                                                      nullptr, true)).first;
227ff0cc061SDimitry Andric   if (isa<DISubprogram>(Scope))
22891bc56edSDimitry Andric     AbstractScopesList.push_back(&I->second);
22991bc56edSDimitry Andric   return &I->second;
2306122f3e6SDimitry Andric }
2316122f3e6SDimitry Andric 
2326122f3e6SDimitry Andric /// constructScopeNest
constructScopeNest(LexicalScope * Scope)2336122f3e6SDimitry Andric void LexicalScopes::constructScopeNest(LexicalScope *Scope) {
2346122f3e6SDimitry Andric   assert(Scope && "Unable to calculate scope dominance graph!");
2356122f3e6SDimitry Andric   SmallVector<LexicalScope *, 4> WorkStack;
2366122f3e6SDimitry Andric   WorkStack.push_back(Scope);
2376122f3e6SDimitry Andric   unsigned Counter = 0;
2386122f3e6SDimitry Andric   while (!WorkStack.empty()) {
2396122f3e6SDimitry Andric     LexicalScope *WS = WorkStack.back();
240f785676fSDimitry Andric     const SmallVectorImpl<LexicalScope *> &Children = WS->getChildren();
2416122f3e6SDimitry Andric     bool visitedChildren = false;
242d88c1a5aSDimitry Andric     for (auto &ChildScope : Children)
2436122f3e6SDimitry Andric       if (!ChildScope->getDFSOut()) {
2446122f3e6SDimitry Andric         WorkStack.push_back(ChildScope);
2456122f3e6SDimitry Andric         visitedChildren = true;
2466122f3e6SDimitry Andric         ChildScope->setDFSIn(++Counter);
2476122f3e6SDimitry Andric         break;
2486122f3e6SDimitry Andric       }
2496122f3e6SDimitry Andric     if (!visitedChildren) {
2506122f3e6SDimitry Andric       WorkStack.pop_back();
2516122f3e6SDimitry Andric       WS->setDFSOut(++Counter);
2526122f3e6SDimitry Andric     }
2536122f3e6SDimitry Andric   }
2546122f3e6SDimitry Andric }
2556122f3e6SDimitry Andric 
2566122f3e6SDimitry Andric /// assignInstructionRanges - Find ranges of instructions covered by each
2576122f3e6SDimitry Andric /// lexical scope.
assignInstructionRanges(SmallVectorImpl<InsnRange> & MIRanges,DenseMap<const MachineInstr *,LexicalScope * > & MI2ScopeMap)25891bc56edSDimitry Andric void LexicalScopes::assignInstructionRanges(
25991bc56edSDimitry Andric     SmallVectorImpl<InsnRange> &MIRanges,
26091bc56edSDimitry Andric     DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) {
26191bc56edSDimitry Andric   LexicalScope *PrevLexicalScope = nullptr;
262d88c1a5aSDimitry Andric   for (const auto &R : MIRanges) {
2636122f3e6SDimitry Andric     LexicalScope *S = MI2ScopeMap.lookup(R.first);
2646122f3e6SDimitry Andric     assert(S && "Lost LexicalScope for a machine instruction!");
2656122f3e6SDimitry Andric     if (PrevLexicalScope && !PrevLexicalScope->dominates(S))
2666122f3e6SDimitry Andric       PrevLexicalScope->closeInsnRange(S);
2676122f3e6SDimitry Andric     S->openInsnRange(R.first);
2686122f3e6SDimitry Andric     S->extendInsnRange(R.second);
2696122f3e6SDimitry Andric     PrevLexicalScope = S;
2706122f3e6SDimitry Andric   }
2716122f3e6SDimitry Andric 
2726122f3e6SDimitry Andric   if (PrevLexicalScope)
2736122f3e6SDimitry Andric     PrevLexicalScope->closeInsnRange();
2746122f3e6SDimitry Andric }
2756122f3e6SDimitry Andric 
2766122f3e6SDimitry Andric /// getMachineBasicBlocks - Populate given set using machine basic blocks which
2776122f3e6SDimitry Andric /// have machine instructions that belong to lexical scope identified by
2786122f3e6SDimitry Andric /// DebugLoc.
getMachineBasicBlocks(const DILocation * DL,SmallPtrSetImpl<const MachineBasicBlock * > & MBBs)27991bc56edSDimitry Andric void LexicalScopes::getMachineBasicBlocks(
280ff0cc061SDimitry Andric     const DILocation *DL, SmallPtrSetImpl<const MachineBasicBlock *> &MBBs) {
2812cab237bSDimitry Andric   assert(MF && "Method called on a uninitialized LexicalScopes object!");
2826122f3e6SDimitry Andric   MBBs.clear();
2832cab237bSDimitry Andric 
2846122f3e6SDimitry Andric   LexicalScope *Scope = getOrCreateLexicalScope(DL);
2856122f3e6SDimitry Andric   if (!Scope)
2866122f3e6SDimitry Andric     return;
2876122f3e6SDimitry Andric 
2886122f3e6SDimitry Andric   if (Scope == CurrentFnLexicalScope) {
28991bc56edSDimitry Andric     for (const auto &MBB : *MF)
29091bc56edSDimitry Andric       MBBs.insert(&MBB);
2916122f3e6SDimitry Andric     return;
2926122f3e6SDimitry Andric   }
2936122f3e6SDimitry Andric 
294f785676fSDimitry Andric   SmallVectorImpl<InsnRange> &InsnRanges = Scope->getRanges();
295d88c1a5aSDimitry Andric   for (auto &R : InsnRanges)
2966122f3e6SDimitry Andric     MBBs.insert(R.first->getParent());
2976122f3e6SDimitry Andric }
2986122f3e6SDimitry Andric 
2996122f3e6SDimitry Andric /// dominates - Return true if DebugLoc's lexical scope dominates at least one
3006122f3e6SDimitry Andric /// machine instruction's lexical scope in a given machine basic block.
dominates(const DILocation * DL,MachineBasicBlock * MBB)301ff0cc061SDimitry Andric bool LexicalScopes::dominates(const DILocation *DL, MachineBasicBlock *MBB) {
3022cab237bSDimitry Andric   assert(MF && "Unexpected uninitialized LexicalScopes object!");
3036122f3e6SDimitry Andric   LexicalScope *Scope = getOrCreateLexicalScope(DL);
3046122f3e6SDimitry Andric   if (!Scope)
3056122f3e6SDimitry Andric     return false;
3066122f3e6SDimitry Andric 
3076122f3e6SDimitry Andric   // Current function scope covers all basic blocks in the function.
3086122f3e6SDimitry Andric   if (Scope == CurrentFnLexicalScope && MBB->getParent() == MF)
3096122f3e6SDimitry Andric     return true;
3106122f3e6SDimitry Andric 
3116122f3e6SDimitry Andric   bool Result = false;
312d88c1a5aSDimitry Andric   for (auto &I : *MBB) {
313d88c1a5aSDimitry Andric     if (const DILocation *IDL = I.getDebugLoc())
3146122f3e6SDimitry Andric       if (LexicalScope *IScope = getOrCreateLexicalScope(IDL))
3156122f3e6SDimitry Andric         if (Scope->dominates(IScope))
3166122f3e6SDimitry Andric           return true;
3176122f3e6SDimitry Andric   }
3186122f3e6SDimitry Andric   return Result;
3196122f3e6SDimitry Andric }
3206122f3e6SDimitry Andric 
3217a7e6055SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump(unsigned Indent) const3227a7e6055SDimitry Andric LLVM_DUMP_METHOD void LexicalScope::dump(unsigned Indent) const {
3236122f3e6SDimitry Andric   raw_ostream &err = dbgs();
324139f7f9bSDimitry Andric   err.indent(Indent);
3256122f3e6SDimitry Andric   err << "DFSIn: " << DFSIn << " DFSOut: " << DFSOut << "\n";
3266122f3e6SDimitry Andric   const MDNode *N = Desc;
327139f7f9bSDimitry Andric   err.indent(Indent);
3286122f3e6SDimitry Andric   N->dump();
3296122f3e6SDimitry Andric   if (AbstractScope)
330139f7f9bSDimitry Andric     err << std::string(Indent, ' ') << "Abstract Scope\n";
3316122f3e6SDimitry Andric 
3326122f3e6SDimitry Andric   if (!Children.empty())
333139f7f9bSDimitry Andric     err << std::string(Indent + 2, ' ') << "Children ...\n";
3346122f3e6SDimitry Andric   for (unsigned i = 0, e = Children.size(); i != e; ++i)
3356122f3e6SDimitry Andric     if (Children[i] != this)
336139f7f9bSDimitry Andric       Children[i]->dump(Indent + 2);
3376122f3e6SDimitry Andric }
3387a7e6055SDimitry Andric #endif
339