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);