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