1 //===- LexicalScopes.cpp - Collecting lexical scope info ------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements LexicalScopes analysis.
12 // This pass collects lexical scope information and maps machine instructions
13 // to respective lexical scopes.
15 //===----------------------------------------------------------------------===//
17 #include "llvm/CodeGen/LexicalScopes.h"
18 #include "llvm/CodeGen/MachineFunction.h"
19 #include "llvm/CodeGen/MachineInstr.h"
20 #include "llvm/IR/DebugInfo.h"
21 #include "llvm/IR/Function.h"
22 #include "llvm/Support/Debug.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/FormattedStream.h"
27 #define DEBUG_TYPE "lexicalscopes"
29 /// reset - Reset the instance so that it's prepared for another function.
30 void LexicalScopes::reset() {
32 CurrentFnLexicalScope
= nullptr;
33 LexicalScopeMap
.clear();
34 AbstractScopeMap
.clear();
35 InlinedLexicalScopeMap
.clear();
36 AbstractScopesList
.clear();
39 /// initialize - Scan machine function and constuct lexical scope nest.
40 void LexicalScopes::initialize(const MachineFunction
&Fn
) {
43 SmallVector
<InsnRange
, 4> MIRanges
;
44 DenseMap
<const MachineInstr
*, LexicalScope
*> MI2ScopeMap
;
45 extractLexicalScopes(MIRanges
, MI2ScopeMap
);
46 if (CurrentFnLexicalScope
) {
47 constructScopeNest(CurrentFnLexicalScope
);
48 assignInstructionRanges(MIRanges
, MI2ScopeMap
);
52 /// extractLexicalScopes - Extract instruction ranges for each lexical scopes
53 /// for the given machine function.
54 void LexicalScopes::extractLexicalScopes(
55 SmallVectorImpl
<InsnRange
> &MIRanges
,
56 DenseMap
<const MachineInstr
*, LexicalScope
*> &MI2ScopeMap
) {
58 // Scan each instruction and create scopes. First build working set of scopes.
59 for (const auto &MBB
: *MF
) {
60 const MachineInstr
*RangeBeginMI
= nullptr;
61 const MachineInstr
*PrevMI
= nullptr;
62 const DILocation
*PrevDL
= nullptr;
63 for (const auto &MInsn
: MBB
) {
64 // Check if instruction has valid location information.
65 const DILocation
*MIDL
= MInsn
.getDebugLoc();
71 // If scope has not changed then skip this instruction.
77 // Ignore DBG_VALUE. It does not contribute to any instruction in output.
78 if (MInsn
.isDebugValue())
82 // If we have already seen a beginning of an instruction range and
83 // current instruction scope does not match scope of first instruction
84 // in this range then create a new instruction range.
85 InsnRange
R(RangeBeginMI
, PrevMI
);
86 MI2ScopeMap
[RangeBeginMI
] = getOrCreateLexicalScope(PrevDL
);
87 MIRanges
.push_back(R
);
90 // This is a beginning of a new instruction range.
91 RangeBeginMI
= &MInsn
;
93 // Reset previous markers.
98 // Create last instruction range.
99 if (RangeBeginMI
&& PrevMI
&& PrevDL
) {
100 InsnRange
R(RangeBeginMI
, PrevMI
);
101 MIRanges
.push_back(R
);
102 MI2ScopeMap
[RangeBeginMI
] = getOrCreateLexicalScope(PrevDL
);
107 /// findLexicalScope - Find lexical scope, either regular or inlined, for the
108 /// given DebugLoc. Return NULL if not found.
109 LexicalScope
*LexicalScopes::findLexicalScope(const DILocation
*DL
) {
110 DILocalScope
*Scope
= DL
->getScope();
114 // The scope that we were created with could have an extra file - which
115 // isn't what we care about in this case.
116 if (auto *File
= dyn_cast
<DILexicalBlockFile
>(Scope
))
117 Scope
= File
->getScope();
119 if (auto *IA
= DL
->getInlinedAt()) {
120 auto I
= InlinedLexicalScopeMap
.find(std::make_pair(Scope
, IA
));
121 return I
!= InlinedLexicalScopeMap
.end() ? &I
->second
: nullptr;
123 return findLexicalScope(Scope
);
126 /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
127 /// not available then create new lexical scope.
128 LexicalScope
*LexicalScopes::getOrCreateLexicalScope(const DILocalScope
*Scope
,
129 const DILocation
*IA
) {
131 // Create an abstract scope for inlined function.
132 getOrCreateAbstractScope(Scope
);
133 // Create an inlined scope for inlined function.
134 return getOrCreateInlinedScope(Scope
, IA
);
137 return getOrCreateRegularScope(Scope
);
140 /// getOrCreateRegularScope - Find or create a regular lexical scope.
142 LexicalScopes::getOrCreateRegularScope(const DILocalScope
*Scope
) {
143 if (auto *File
= dyn_cast
<DILexicalBlockFile
>(Scope
))
144 Scope
= File
->getScope();
146 auto I
= LexicalScopeMap
.find(Scope
);
147 if (I
!= LexicalScopeMap
.end())
150 // FIXME: Should the following dyn_cast be DILexicalBlock?
151 LexicalScope
*Parent
= nullptr;
152 if (auto *Block
= dyn_cast
<DILexicalBlockBase
>(Scope
))
153 Parent
= getOrCreateLexicalScope(Block
->getScope());
154 I
= LexicalScopeMap
.emplace(std::piecewise_construct
,
155 std::forward_as_tuple(Scope
),
156 std::forward_as_tuple(Parent
, Scope
, nullptr,
160 assert(cast
<DISubprogram
>(Scope
)->describes(MF
->getFunction()));
161 assert(!CurrentFnLexicalScope
);
162 CurrentFnLexicalScope
= &I
->second
;
168 /// getOrCreateInlinedScope - Find or create an inlined lexical scope.
170 LexicalScopes::getOrCreateInlinedScope(const DILocalScope
*Scope
,
171 const DILocation
*InlinedAt
) {
172 std::pair
<const DILocalScope
*, const DILocation
*> P(Scope
, InlinedAt
);
173 auto I
= InlinedLexicalScopeMap
.find(P
);
174 if (I
!= InlinedLexicalScopeMap
.end())
177 LexicalScope
*Parent
;
178 if (auto *Block
= dyn_cast
<DILexicalBlockBase
>(Scope
))
179 Parent
= getOrCreateInlinedScope(Block
->getScope(), InlinedAt
);
181 Parent
= getOrCreateLexicalScope(InlinedAt
);
183 I
= InlinedLexicalScopeMap
.emplace(std::piecewise_construct
,
184 std::forward_as_tuple(P
),
185 std::forward_as_tuple(Parent
, Scope
,
191 /// getOrCreateAbstractScope - Find or create an abstract lexical scope.
193 LexicalScopes::getOrCreateAbstractScope(const DILocalScope
*Scope
) {
194 assert(Scope
&& "Invalid Scope encoding!");
196 if (auto *File
= dyn_cast
<DILexicalBlockFile
>(Scope
))
197 Scope
= File
->getScope();
198 auto I
= AbstractScopeMap
.find(Scope
);
199 if (I
!= AbstractScopeMap
.end())
202 // FIXME: Should the following isa be DILexicalBlock?
203 LexicalScope
*Parent
= nullptr;
204 if (auto *Block
= dyn_cast
<DILexicalBlockBase
>(Scope
))
205 Parent
= getOrCreateAbstractScope(Block
->getScope());
207 I
= AbstractScopeMap
.emplace(std::piecewise_construct
,
208 std::forward_as_tuple(Scope
),
209 std::forward_as_tuple(Parent
, Scope
,
210 nullptr, true)).first
;
211 if (isa
<DISubprogram
>(Scope
))
212 AbstractScopesList
.push_back(&I
->second
);
216 /// constructScopeNest
217 void LexicalScopes::constructScopeNest(LexicalScope
*Scope
) {
218 assert(Scope
&& "Unable to calculate scope dominance graph!");
219 SmallVector
<LexicalScope
*, 4> WorkStack
;
220 WorkStack
.push_back(Scope
);
221 unsigned Counter
= 0;
222 while (!WorkStack
.empty()) {
223 LexicalScope
*WS
= WorkStack
.back();
224 const SmallVectorImpl
<LexicalScope
*> &Children
= WS
->getChildren();
225 bool visitedChildren
= false;
226 for (SmallVectorImpl
<LexicalScope
*>::const_iterator SI
= Children
.begin(),
229 LexicalScope
*ChildScope
= *SI
;
230 if (!ChildScope
->getDFSOut()) {
231 WorkStack
.push_back(ChildScope
);
232 visitedChildren
= true;
233 ChildScope
->setDFSIn(++Counter
);
237 if (!visitedChildren
) {
238 WorkStack
.pop_back();
239 WS
->setDFSOut(++Counter
);
244 /// assignInstructionRanges - Find ranges of instructions covered by each
246 void LexicalScopes::assignInstructionRanges(
247 SmallVectorImpl
<InsnRange
> &MIRanges
,
248 DenseMap
<const MachineInstr
*, LexicalScope
*> &MI2ScopeMap
) {
250 LexicalScope
*PrevLexicalScope
= nullptr;
251 for (SmallVectorImpl
<InsnRange
>::const_iterator RI
= MIRanges
.begin(),
254 const InsnRange
&R
= *RI
;
255 LexicalScope
*S
= MI2ScopeMap
.lookup(R
.first
);
256 assert(S
&& "Lost LexicalScope for a machine instruction!");
257 if (PrevLexicalScope
&& !PrevLexicalScope
->dominates(S
))
258 PrevLexicalScope
->closeInsnRange(S
);
259 S
->openInsnRange(R
.first
);
260 S
->extendInsnRange(R
.second
);
261 PrevLexicalScope
= S
;
264 if (PrevLexicalScope
)
265 PrevLexicalScope
->closeInsnRange();
268 /// getMachineBasicBlocks - Populate given set using machine basic blocks which
269 /// have machine instructions that belong to lexical scope identified by
271 void LexicalScopes::getMachineBasicBlocks(
272 const DILocation
*DL
, SmallPtrSetImpl
<const MachineBasicBlock
*> &MBBs
) {
274 LexicalScope
*Scope
= getOrCreateLexicalScope(DL
);
278 if (Scope
== CurrentFnLexicalScope
) {
279 for (const auto &MBB
: *MF
)
284 SmallVectorImpl
<InsnRange
> &InsnRanges
= Scope
->getRanges();
285 for (SmallVectorImpl
<InsnRange
>::iterator I
= InsnRanges
.begin(),
286 E
= InsnRanges
.end();
289 MBBs
.insert(R
.first
->getParent());
293 /// dominates - Return true if DebugLoc's lexical scope dominates at least one
294 /// machine instruction's lexical scope in a given machine basic block.
295 bool LexicalScopes::dominates(const DILocation
*DL
, MachineBasicBlock
*MBB
) {
296 LexicalScope
*Scope
= getOrCreateLexicalScope(DL
);
300 // Current function scope covers all basic blocks in the function.
301 if (Scope
== CurrentFnLexicalScope
&& MBB
->getParent() == MF
)
305 for (MachineBasicBlock::iterator I
= MBB
->begin(), E
= MBB
->end(); I
!= E
;
307 if (const DILocation
*IDL
= I
->getDebugLoc())
308 if (LexicalScope
*IScope
= getOrCreateLexicalScope(IDL
))
309 if (Scope
->dominates(IScope
))
315 /// dump - Print data structures.
316 void LexicalScope::dump(unsigned Indent
) const {
318 raw_ostream
&err
= dbgs();
320 err
<< "DFSIn: " << DFSIn
<< " DFSOut: " << DFSOut
<< "\n";
321 const MDNode
*N
= Desc
;
325 err
<< std::string(Indent
, ' ') << "Abstract Scope\n";
327 if (!Children
.empty())
328 err
<< std::string(Indent
+ 2, ' ') << "Children ...\n";
329 for (unsigned i
= 0, e
= Children
.size(); i
!= e
; ++i
)
330 if (Children
[i
] != this)
331 Children
[i
]->dump(Indent
+ 2);