xref: /minix3/external/bsd/llvm/dist/llvm/lib/CodeGen/LexicalScopes.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===- LexicalScopes.cpp - Collecting lexical scope info ------------------===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file implements LexicalScopes analysis.
11f4a2713aSLionel Sambuc //
12f4a2713aSLionel Sambuc // This pass collects lexical scope information and maps machine instructions
13f4a2713aSLionel Sambuc // to respective lexical scopes.
14f4a2713aSLionel Sambuc //
15f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
16f4a2713aSLionel Sambuc 
17f4a2713aSLionel Sambuc #include "llvm/CodeGen/LexicalScopes.h"
18f4a2713aSLionel Sambuc #include "llvm/CodeGen/MachineFunction.h"
19f4a2713aSLionel Sambuc #include "llvm/CodeGen/MachineInstr.h"
20*0a6a1f1dSLionel Sambuc #include "llvm/IR/DebugInfo.h"
21f4a2713aSLionel Sambuc #include "llvm/IR/Function.h"
22f4a2713aSLionel Sambuc #include "llvm/Support/Debug.h"
23f4a2713aSLionel Sambuc #include "llvm/Support/ErrorHandling.h"
24f4a2713aSLionel Sambuc #include "llvm/Support/FormattedStream.h"
25f4a2713aSLionel Sambuc using namespace llvm;
26f4a2713aSLionel Sambuc 
27*0a6a1f1dSLionel Sambuc #define DEBUG_TYPE "lexicalscopes"
28f4a2713aSLionel Sambuc 
29*0a6a1f1dSLionel Sambuc /// reset - Reset the instance so that it's prepared for another function.
reset()30*0a6a1f1dSLionel Sambuc void LexicalScopes::reset() {
31*0a6a1f1dSLionel Sambuc   MF = nullptr;
32*0a6a1f1dSLionel Sambuc   CurrentFnLexicalScope = nullptr;
33*0a6a1f1dSLionel Sambuc   LexicalScopeMap.clear();
34*0a6a1f1dSLionel Sambuc   AbstractScopeMap.clear();
35f4a2713aSLionel Sambuc   InlinedLexicalScopeMap.clear();
36f4a2713aSLionel Sambuc   AbstractScopesList.clear();
37f4a2713aSLionel Sambuc }
38f4a2713aSLionel Sambuc 
39f4a2713aSLionel Sambuc /// initialize - Scan machine function and constuct lexical scope nest.
initialize(const MachineFunction & Fn)40f4a2713aSLionel Sambuc void LexicalScopes::initialize(const MachineFunction &Fn) {
41*0a6a1f1dSLionel Sambuc   reset();
42f4a2713aSLionel Sambuc   MF = &Fn;
43f4a2713aSLionel Sambuc   SmallVector<InsnRange, 4> MIRanges;
44f4a2713aSLionel Sambuc   DenseMap<const MachineInstr *, LexicalScope *> MI2ScopeMap;
45f4a2713aSLionel Sambuc   extractLexicalScopes(MIRanges, MI2ScopeMap);
46f4a2713aSLionel Sambuc   if (CurrentFnLexicalScope) {
47f4a2713aSLionel Sambuc     constructScopeNest(CurrentFnLexicalScope);
48f4a2713aSLionel Sambuc     assignInstructionRanges(MIRanges, MI2ScopeMap);
49f4a2713aSLionel Sambuc   }
50f4a2713aSLionel Sambuc }
51f4a2713aSLionel Sambuc 
52f4a2713aSLionel Sambuc /// extractLexicalScopes - Extract instruction ranges for each lexical scopes
53f4a2713aSLionel Sambuc /// for the given machine function.
extractLexicalScopes(SmallVectorImpl<InsnRange> & MIRanges,DenseMap<const MachineInstr *,LexicalScope * > & MI2ScopeMap)54*0a6a1f1dSLionel Sambuc void LexicalScopes::extractLexicalScopes(
55*0a6a1f1dSLionel Sambuc     SmallVectorImpl<InsnRange> &MIRanges,
56f4a2713aSLionel Sambuc     DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) {
57f4a2713aSLionel Sambuc 
58f4a2713aSLionel Sambuc   // Scan each instruction and create scopes. First build working set of scopes.
59*0a6a1f1dSLionel Sambuc   for (const auto &MBB : *MF) {
60*0a6a1f1dSLionel Sambuc     const MachineInstr *RangeBeginMI = nullptr;
61*0a6a1f1dSLionel Sambuc     const MachineInstr *PrevMI = nullptr;
62f4a2713aSLionel Sambuc     DebugLoc PrevDL;
63*0a6a1f1dSLionel Sambuc     for (const auto &MInsn : MBB) {
64f4a2713aSLionel Sambuc       // Check if instruction has valid location information.
65*0a6a1f1dSLionel Sambuc       const DebugLoc MIDL = MInsn.getDebugLoc();
66f4a2713aSLionel Sambuc       if (MIDL.isUnknown()) {
67*0a6a1f1dSLionel Sambuc         PrevMI = &MInsn;
68f4a2713aSLionel Sambuc         continue;
69f4a2713aSLionel Sambuc       }
70f4a2713aSLionel Sambuc 
71f4a2713aSLionel Sambuc       // If scope has not changed then skip this instruction.
72f4a2713aSLionel Sambuc       if (MIDL == PrevDL) {
73*0a6a1f1dSLionel Sambuc         PrevMI = &MInsn;
74f4a2713aSLionel Sambuc         continue;
75f4a2713aSLionel Sambuc       }
76f4a2713aSLionel Sambuc 
77f4a2713aSLionel Sambuc       // Ignore DBG_VALUE. It does not contribute to any instruction in output.
78*0a6a1f1dSLionel Sambuc       if (MInsn.isDebugValue())
79f4a2713aSLionel Sambuc         continue;
80f4a2713aSLionel Sambuc 
81f4a2713aSLionel Sambuc       if (RangeBeginMI) {
82f4a2713aSLionel Sambuc         // If we have already seen a beginning of an instruction range and
83f4a2713aSLionel Sambuc         // current instruction scope does not match scope of first instruction
84f4a2713aSLionel Sambuc         // in this range then create a new instruction range.
85f4a2713aSLionel Sambuc         InsnRange R(RangeBeginMI, PrevMI);
86f4a2713aSLionel Sambuc         MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
87f4a2713aSLionel Sambuc         MIRanges.push_back(R);
88f4a2713aSLionel Sambuc       }
89f4a2713aSLionel Sambuc 
90f4a2713aSLionel Sambuc       // This is a beginning of a new instruction range.
91*0a6a1f1dSLionel Sambuc       RangeBeginMI = &MInsn;
92f4a2713aSLionel Sambuc 
93f4a2713aSLionel Sambuc       // Reset previous markers.
94*0a6a1f1dSLionel Sambuc       PrevMI = &MInsn;
95f4a2713aSLionel Sambuc       PrevDL = MIDL;
96f4a2713aSLionel Sambuc     }
97f4a2713aSLionel Sambuc 
98f4a2713aSLionel Sambuc     // Create last instruction range.
99f4a2713aSLionel Sambuc     if (RangeBeginMI && PrevMI && !PrevDL.isUnknown()) {
100f4a2713aSLionel Sambuc       InsnRange R(RangeBeginMI, PrevMI);
101f4a2713aSLionel Sambuc       MIRanges.push_back(R);
102f4a2713aSLionel Sambuc       MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
103f4a2713aSLionel Sambuc     }
104f4a2713aSLionel Sambuc   }
105f4a2713aSLionel Sambuc }
106f4a2713aSLionel Sambuc 
findInlinedScope(DebugLoc DL)107*0a6a1f1dSLionel Sambuc LexicalScope *LexicalScopes::findInlinedScope(DebugLoc DL) {
108*0a6a1f1dSLionel Sambuc   MDNode *Scope = nullptr;
109*0a6a1f1dSLionel Sambuc   MDNode *IA = nullptr;
110*0a6a1f1dSLionel Sambuc   DL.getScopeAndInlinedAt(Scope, IA, MF->getFunction()->getContext());
111*0a6a1f1dSLionel Sambuc   auto I = InlinedLexicalScopeMap.find(std::make_pair(Scope, IA));
112*0a6a1f1dSLionel Sambuc   return I != InlinedLexicalScopeMap.end() ? &I->second : nullptr;
113*0a6a1f1dSLionel Sambuc }
114*0a6a1f1dSLionel Sambuc 
115f4a2713aSLionel Sambuc /// findLexicalScope - Find lexical scope, either regular or inlined, for the
116f4a2713aSLionel Sambuc /// given DebugLoc. Return NULL if not found.
findLexicalScope(DebugLoc DL)117f4a2713aSLionel Sambuc LexicalScope *LexicalScopes::findLexicalScope(DebugLoc DL) {
118*0a6a1f1dSLionel Sambuc   MDNode *Scope = nullptr;
119*0a6a1f1dSLionel Sambuc   MDNode *IA = nullptr;
120f4a2713aSLionel Sambuc   DL.getScopeAndInlinedAt(Scope, IA, MF->getFunction()->getContext());
121*0a6a1f1dSLionel Sambuc   if (!Scope)
122*0a6a1f1dSLionel Sambuc     return nullptr;
123f4a2713aSLionel Sambuc 
124f4a2713aSLionel Sambuc   // The scope that we were created with could have an extra file - which
125f4a2713aSLionel Sambuc   // isn't what we care about in this case.
126f4a2713aSLionel Sambuc   DIDescriptor D = DIDescriptor(Scope);
127f4a2713aSLionel Sambuc   if (D.isLexicalBlockFile())
128f4a2713aSLionel Sambuc     Scope = DILexicalBlockFile(Scope).getScope();
129f4a2713aSLionel Sambuc 
130*0a6a1f1dSLionel Sambuc   if (IA) {
131*0a6a1f1dSLionel Sambuc     auto I = InlinedLexicalScopeMap.find(std::make_pair(Scope, IA));
132*0a6a1f1dSLionel Sambuc     return I != InlinedLexicalScopeMap.end() ? &I->second : nullptr;
133*0a6a1f1dSLionel Sambuc   }
134*0a6a1f1dSLionel Sambuc   return findLexicalScope(Scope);
135f4a2713aSLionel Sambuc }
136f4a2713aSLionel Sambuc 
137f4a2713aSLionel Sambuc /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
138f4a2713aSLionel Sambuc /// not available then create new lexical scope.
getOrCreateLexicalScope(DebugLoc DL)139f4a2713aSLionel Sambuc LexicalScope *LexicalScopes::getOrCreateLexicalScope(DebugLoc DL) {
140*0a6a1f1dSLionel Sambuc   if (DL.isUnknown())
141*0a6a1f1dSLionel Sambuc     return nullptr;
142*0a6a1f1dSLionel Sambuc   MDNode *Scope = nullptr;
143*0a6a1f1dSLionel Sambuc   MDNode *InlinedAt = nullptr;
144f4a2713aSLionel Sambuc   DL.getScopeAndInlinedAt(Scope, InlinedAt, MF->getFunction()->getContext());
145f4a2713aSLionel Sambuc 
146f4a2713aSLionel Sambuc   if (InlinedAt) {
147f4a2713aSLionel Sambuc     // Create an abstract scope for inlined function.
148f4a2713aSLionel Sambuc     getOrCreateAbstractScope(Scope);
149f4a2713aSLionel Sambuc     // Create an inlined scope for inlined function.
150f4a2713aSLionel Sambuc     return getOrCreateInlinedScope(Scope, InlinedAt);
151f4a2713aSLionel Sambuc   }
152f4a2713aSLionel Sambuc 
153f4a2713aSLionel Sambuc   return getOrCreateRegularScope(Scope);
154f4a2713aSLionel Sambuc }
155f4a2713aSLionel Sambuc 
156f4a2713aSLionel Sambuc /// getOrCreateRegularScope - Find or create a regular lexical scope.
getOrCreateRegularScope(MDNode * Scope)157f4a2713aSLionel Sambuc LexicalScope *LexicalScopes::getOrCreateRegularScope(MDNode *Scope) {
158f4a2713aSLionel Sambuc   DIDescriptor D = DIDescriptor(Scope);
159f4a2713aSLionel Sambuc   if (D.isLexicalBlockFile()) {
160f4a2713aSLionel Sambuc     Scope = DILexicalBlockFile(Scope).getScope();
161f4a2713aSLionel Sambuc     D = DIDescriptor(Scope);
162f4a2713aSLionel Sambuc   }
163f4a2713aSLionel Sambuc 
164*0a6a1f1dSLionel Sambuc   auto I = LexicalScopeMap.find(Scope);
165*0a6a1f1dSLionel Sambuc   if (I != LexicalScopeMap.end())
166*0a6a1f1dSLionel Sambuc     return &I->second;
167f4a2713aSLionel Sambuc 
168*0a6a1f1dSLionel Sambuc   LexicalScope *Parent = nullptr;
169f4a2713aSLionel Sambuc   if (D.isLexicalBlock())
170f4a2713aSLionel Sambuc     Parent = getOrCreateLexicalScope(DebugLoc::getFromDILexicalBlock(Scope));
171*0a6a1f1dSLionel Sambuc   // FIXME: Use forward_as_tuple instead of make_tuple, once MSVC2012
172*0a6a1f1dSLionel Sambuc   // compatibility is no longer required.
173*0a6a1f1dSLionel Sambuc   I = LexicalScopeMap.emplace(std::piecewise_construct, std::make_tuple(Scope),
174*0a6a1f1dSLionel Sambuc                               std::make_tuple(Parent, DIDescriptor(Scope),
175*0a6a1f1dSLionel Sambuc                                               nullptr, false)).first;
176f4a2713aSLionel Sambuc 
177*0a6a1f1dSLionel Sambuc   if (!Parent) {
178*0a6a1f1dSLionel Sambuc     assert(DIDescriptor(Scope).isSubprogram());
179*0a6a1f1dSLionel Sambuc     assert(DISubprogram(Scope).describes(MF->getFunction()));
180*0a6a1f1dSLionel Sambuc     assert(!CurrentFnLexicalScope);
181*0a6a1f1dSLionel Sambuc     CurrentFnLexicalScope = &I->second;
182*0a6a1f1dSLionel Sambuc   }
183*0a6a1f1dSLionel Sambuc 
184*0a6a1f1dSLionel Sambuc   return &I->second;
185f4a2713aSLionel Sambuc }
186f4a2713aSLionel Sambuc 
187f4a2713aSLionel Sambuc /// getOrCreateInlinedScope - Find or create an inlined lexical scope.
getOrCreateInlinedScope(MDNode * ScopeNode,MDNode * InlinedAt)188*0a6a1f1dSLionel Sambuc LexicalScope *LexicalScopes::getOrCreateInlinedScope(MDNode *ScopeNode,
189f4a2713aSLionel Sambuc                                                      MDNode *InlinedAt) {
190*0a6a1f1dSLionel Sambuc   std::pair<const MDNode*, const MDNode*> P(ScopeNode, InlinedAt);
191*0a6a1f1dSLionel Sambuc   auto I = InlinedLexicalScopeMap.find(P);
192*0a6a1f1dSLionel Sambuc   if (I != InlinedLexicalScopeMap.end())
193*0a6a1f1dSLionel Sambuc     return &I->second;
194f4a2713aSLionel Sambuc 
195*0a6a1f1dSLionel Sambuc   LexicalScope *Parent;
196*0a6a1f1dSLionel Sambuc   DILexicalBlock Scope(ScopeNode);
197*0a6a1f1dSLionel Sambuc   if (Scope.isSubprogram())
198*0a6a1f1dSLionel Sambuc     Parent = getOrCreateLexicalScope(DebugLoc::getFromDILocation(InlinedAt));
199*0a6a1f1dSLionel Sambuc   else
200*0a6a1f1dSLionel Sambuc     Parent = getOrCreateInlinedScope(Scope.getContext(), InlinedAt);
201*0a6a1f1dSLionel Sambuc 
202*0a6a1f1dSLionel Sambuc   // FIXME: Use forward_as_tuple instead of make_tuple, once MSVC2012
203*0a6a1f1dSLionel Sambuc   // compatibility is no longer required.
204*0a6a1f1dSLionel Sambuc   I = InlinedLexicalScopeMap.emplace(std::piecewise_construct,
205*0a6a1f1dSLionel Sambuc                                      std::make_tuple(P),
206*0a6a1f1dSLionel Sambuc                                      std::make_tuple(Parent, Scope, InlinedAt,
207*0a6a1f1dSLionel Sambuc                                                      false)).first;
208*0a6a1f1dSLionel Sambuc   return &I->second;
209f4a2713aSLionel Sambuc }
210f4a2713aSLionel Sambuc 
211f4a2713aSLionel Sambuc /// getOrCreateAbstractScope - Find or create an abstract lexical scope.
getOrCreateAbstractScope(const MDNode * N)212f4a2713aSLionel Sambuc LexicalScope *LexicalScopes::getOrCreateAbstractScope(const MDNode *N) {
213f4a2713aSLionel Sambuc   assert(N && "Invalid Scope encoding!");
214f4a2713aSLionel Sambuc 
215f4a2713aSLionel Sambuc   DIDescriptor Scope(N);
216f4a2713aSLionel Sambuc   if (Scope.isLexicalBlockFile())
217f4a2713aSLionel Sambuc     Scope = DILexicalBlockFile(Scope).getScope();
218*0a6a1f1dSLionel Sambuc   auto I = AbstractScopeMap.find(Scope);
219*0a6a1f1dSLionel Sambuc   if (I != AbstractScopeMap.end())
220*0a6a1f1dSLionel Sambuc     return &I->second;
221f4a2713aSLionel Sambuc 
222*0a6a1f1dSLionel Sambuc   LexicalScope *Parent = nullptr;
223f4a2713aSLionel Sambuc   if (Scope.isLexicalBlock()) {
224*0a6a1f1dSLionel Sambuc     DILexicalBlock DB(Scope);
225f4a2713aSLionel Sambuc     DIDescriptor ParentDesc = DB.getContext();
226f4a2713aSLionel Sambuc     Parent = getOrCreateAbstractScope(ParentDesc);
227f4a2713aSLionel Sambuc   }
228*0a6a1f1dSLionel Sambuc   I = AbstractScopeMap.emplace(std::piecewise_construct,
229*0a6a1f1dSLionel Sambuc                                std::forward_as_tuple(Scope),
230*0a6a1f1dSLionel Sambuc                                std::forward_as_tuple(Parent, Scope,
231*0a6a1f1dSLionel Sambuc                                                      nullptr, true)).first;
232*0a6a1f1dSLionel Sambuc   if (Scope.isSubprogram())
233*0a6a1f1dSLionel Sambuc     AbstractScopesList.push_back(&I->second);
234*0a6a1f1dSLionel Sambuc   return &I->second;
235f4a2713aSLionel Sambuc }
236f4a2713aSLionel Sambuc 
237f4a2713aSLionel Sambuc /// constructScopeNest
constructScopeNest(LexicalScope * Scope)238f4a2713aSLionel Sambuc void LexicalScopes::constructScopeNest(LexicalScope *Scope) {
239f4a2713aSLionel Sambuc   assert(Scope && "Unable to calculate scope dominance graph!");
240f4a2713aSLionel Sambuc   SmallVector<LexicalScope *, 4> WorkStack;
241f4a2713aSLionel Sambuc   WorkStack.push_back(Scope);
242f4a2713aSLionel Sambuc   unsigned Counter = 0;
243f4a2713aSLionel Sambuc   while (!WorkStack.empty()) {
244f4a2713aSLionel Sambuc     LexicalScope *WS = WorkStack.back();
245f4a2713aSLionel Sambuc     const SmallVectorImpl<LexicalScope *> &Children = WS->getChildren();
246f4a2713aSLionel Sambuc     bool visitedChildren = false;
247f4a2713aSLionel Sambuc     for (SmallVectorImpl<LexicalScope *>::const_iterator SI = Children.begin(),
248*0a6a1f1dSLionel Sambuc                                                          SE = Children.end();
249*0a6a1f1dSLionel Sambuc          SI != SE; ++SI) {
250f4a2713aSLionel Sambuc       LexicalScope *ChildScope = *SI;
251f4a2713aSLionel Sambuc       if (!ChildScope->getDFSOut()) {
252f4a2713aSLionel Sambuc         WorkStack.push_back(ChildScope);
253f4a2713aSLionel Sambuc         visitedChildren = true;
254f4a2713aSLionel Sambuc         ChildScope->setDFSIn(++Counter);
255f4a2713aSLionel Sambuc         break;
256f4a2713aSLionel Sambuc       }
257f4a2713aSLionel Sambuc     }
258f4a2713aSLionel Sambuc     if (!visitedChildren) {
259f4a2713aSLionel Sambuc       WorkStack.pop_back();
260f4a2713aSLionel Sambuc       WS->setDFSOut(++Counter);
261f4a2713aSLionel Sambuc     }
262f4a2713aSLionel Sambuc   }
263f4a2713aSLionel Sambuc }
264f4a2713aSLionel Sambuc 
265f4a2713aSLionel Sambuc /// assignInstructionRanges - Find ranges of instructions covered by each
266f4a2713aSLionel Sambuc /// lexical scope.
assignInstructionRanges(SmallVectorImpl<InsnRange> & MIRanges,DenseMap<const MachineInstr *,LexicalScope * > & MI2ScopeMap)267*0a6a1f1dSLionel Sambuc void LexicalScopes::assignInstructionRanges(
268*0a6a1f1dSLionel Sambuc     SmallVectorImpl<InsnRange> &MIRanges,
269*0a6a1f1dSLionel Sambuc     DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) {
270f4a2713aSLionel Sambuc 
271*0a6a1f1dSLionel Sambuc   LexicalScope *PrevLexicalScope = nullptr;
272f4a2713aSLionel Sambuc   for (SmallVectorImpl<InsnRange>::const_iterator RI = MIRanges.begin(),
273*0a6a1f1dSLionel Sambuc                                                   RE = MIRanges.end();
274*0a6a1f1dSLionel Sambuc        RI != RE; ++RI) {
275f4a2713aSLionel Sambuc     const InsnRange &R = *RI;
276f4a2713aSLionel Sambuc     LexicalScope *S = MI2ScopeMap.lookup(R.first);
277f4a2713aSLionel Sambuc     assert(S && "Lost LexicalScope for a machine instruction!");
278f4a2713aSLionel Sambuc     if (PrevLexicalScope && !PrevLexicalScope->dominates(S))
279f4a2713aSLionel Sambuc       PrevLexicalScope->closeInsnRange(S);
280f4a2713aSLionel Sambuc     S->openInsnRange(R.first);
281f4a2713aSLionel Sambuc     S->extendInsnRange(R.second);
282f4a2713aSLionel Sambuc     PrevLexicalScope = S;
283f4a2713aSLionel Sambuc   }
284f4a2713aSLionel Sambuc 
285f4a2713aSLionel Sambuc   if (PrevLexicalScope)
286f4a2713aSLionel Sambuc     PrevLexicalScope->closeInsnRange();
287f4a2713aSLionel Sambuc }
288f4a2713aSLionel Sambuc 
289f4a2713aSLionel Sambuc /// getMachineBasicBlocks - Populate given set using machine basic blocks which
290f4a2713aSLionel Sambuc /// have machine instructions that belong to lexical scope identified by
291f4a2713aSLionel Sambuc /// DebugLoc.
getMachineBasicBlocks(DebugLoc DL,SmallPtrSetImpl<const MachineBasicBlock * > & MBBs)292*0a6a1f1dSLionel Sambuc void LexicalScopes::getMachineBasicBlocks(
293*0a6a1f1dSLionel Sambuc     DebugLoc DL, SmallPtrSetImpl<const MachineBasicBlock *> &MBBs) {
294f4a2713aSLionel Sambuc   MBBs.clear();
295f4a2713aSLionel Sambuc   LexicalScope *Scope = getOrCreateLexicalScope(DL);
296f4a2713aSLionel Sambuc   if (!Scope)
297f4a2713aSLionel Sambuc     return;
298f4a2713aSLionel Sambuc 
299f4a2713aSLionel Sambuc   if (Scope == CurrentFnLexicalScope) {
300*0a6a1f1dSLionel Sambuc     for (const auto &MBB : *MF)
301*0a6a1f1dSLionel Sambuc       MBBs.insert(&MBB);
302f4a2713aSLionel Sambuc     return;
303f4a2713aSLionel Sambuc   }
304f4a2713aSLionel Sambuc 
305f4a2713aSLionel Sambuc   SmallVectorImpl<InsnRange> &InsnRanges = Scope->getRanges();
306f4a2713aSLionel Sambuc   for (SmallVectorImpl<InsnRange>::iterator I = InsnRanges.begin(),
307*0a6a1f1dSLionel Sambuc                                             E = InsnRanges.end();
308*0a6a1f1dSLionel Sambuc        I != E; ++I) {
309f4a2713aSLionel Sambuc     InsnRange &R = *I;
310f4a2713aSLionel Sambuc     MBBs.insert(R.first->getParent());
311f4a2713aSLionel Sambuc   }
312f4a2713aSLionel Sambuc }
313f4a2713aSLionel Sambuc 
314f4a2713aSLionel Sambuc /// dominates - Return true if DebugLoc's lexical scope dominates at least one
315f4a2713aSLionel Sambuc /// machine instruction's lexical scope in a given machine basic block.
dominates(DebugLoc DL,MachineBasicBlock * MBB)316f4a2713aSLionel Sambuc bool LexicalScopes::dominates(DebugLoc DL, MachineBasicBlock *MBB) {
317f4a2713aSLionel Sambuc   LexicalScope *Scope = getOrCreateLexicalScope(DL);
318f4a2713aSLionel Sambuc   if (!Scope)
319f4a2713aSLionel Sambuc     return false;
320f4a2713aSLionel Sambuc 
321f4a2713aSLionel Sambuc   // Current function scope covers all basic blocks in the function.
322f4a2713aSLionel Sambuc   if (Scope == CurrentFnLexicalScope && MBB->getParent() == MF)
323f4a2713aSLionel Sambuc     return true;
324f4a2713aSLionel Sambuc 
325f4a2713aSLionel Sambuc   bool Result = false;
326*0a6a1f1dSLionel Sambuc   for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;
327*0a6a1f1dSLionel Sambuc        ++I) {
328f4a2713aSLionel Sambuc     DebugLoc IDL = I->getDebugLoc();
329f4a2713aSLionel Sambuc     if (IDL.isUnknown())
330f4a2713aSLionel Sambuc       continue;
331f4a2713aSLionel Sambuc     if (LexicalScope *IScope = getOrCreateLexicalScope(IDL))
332f4a2713aSLionel Sambuc       if (Scope->dominates(IScope))
333f4a2713aSLionel Sambuc         return true;
334f4a2713aSLionel Sambuc   }
335f4a2713aSLionel Sambuc   return Result;
336f4a2713aSLionel Sambuc }
337f4a2713aSLionel Sambuc 
338f4a2713aSLionel Sambuc /// dump - Print data structures.
dump(unsigned Indent) const339f4a2713aSLionel Sambuc void LexicalScope::dump(unsigned Indent) const {
340f4a2713aSLionel Sambuc #ifndef NDEBUG
341f4a2713aSLionel Sambuc   raw_ostream &err = dbgs();
342f4a2713aSLionel Sambuc   err.indent(Indent);
343f4a2713aSLionel Sambuc   err << "DFSIn: " << DFSIn << " DFSOut: " << DFSOut << "\n";
344f4a2713aSLionel Sambuc   const MDNode *N = Desc;
345f4a2713aSLionel Sambuc   err.indent(Indent);
346f4a2713aSLionel Sambuc   N->dump();
347f4a2713aSLionel Sambuc   if (AbstractScope)
348f4a2713aSLionel Sambuc     err << std::string(Indent, ' ') << "Abstract Scope\n";
349f4a2713aSLionel Sambuc 
350f4a2713aSLionel Sambuc   if (!Children.empty())
351f4a2713aSLionel Sambuc     err << std::string(Indent + 2, ' ') << "Children ...\n";
352f4a2713aSLionel Sambuc   for (unsigned i = 0, e = Children.size(); i != e; ++i)
353f4a2713aSLionel Sambuc     if (Children[i] != this)
354f4a2713aSLionel Sambuc       Children[i]->dump(Indent + 2);
355f4a2713aSLionel Sambuc #endif
356f4a2713aSLionel Sambuc }
357