Newer
Older
Devang Patel
committed
//===- LexicalScopes.cpp - Collecting lexical scope info ------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements LexicalScopes analysis.
//
// This pass collects lexical scope information and maps machine instructions
// to respective lexical scopes.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "lexicalscopes"
#include "llvm/CodeGen/LexicalScopes.h"
#include "llvm/DebugInfo.h"
Devang Patel
committed
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include "llvm/Function.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
using namespace llvm;
LexicalScopes::~LexicalScopes() {
releaseMemory();
}
/// releaseMemory - release memory.
void LexicalScopes::releaseMemory() {
MF = NULL;
CurrentFnLexicalScope = NULL;
DeleteContainerSeconds(LexicalScopeMap);
DeleteContainerSeconds(AbstractScopeMap);
InlinedLexicalScopeMap.clear();
AbstractScopesList.clear();
}
/// initialize - Scan machine function and constuct lexical scope nest.
void LexicalScopes::initialize(const MachineFunction &Fn) {
releaseMemory();
MF = &Fn;
SmallVector<InsnRange, 4> MIRanges;
DenseMap<const MachineInstr *, LexicalScope *> MI2ScopeMap;
extractLexicalScopes(MIRanges, MI2ScopeMap);
if (CurrentFnLexicalScope) {
constructScopeNest(CurrentFnLexicalScope);
assignInstructionRanges(MIRanges, MI2ScopeMap);
}
}
/// extractLexicalScopes - Extract instruction ranges for each lexical scopes
/// for the given machine function.
void LexicalScopes::
extractLexicalScopes(SmallVectorImpl<InsnRange> &MIRanges,
DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) {
// Scan each instruction and create scopes. First build working set of scopes.
for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
I != E; ++I) {
const MachineInstr *RangeBeginMI = NULL;
const MachineInstr *PrevMI = NULL;
DebugLoc PrevDL;
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
II != IE; ++II) {
const MachineInstr *MInsn = II;
// Check if instruction has valid location information.
const DebugLoc MIDL = MInsn->getDebugLoc();
if (MIDL.isUnknown()) {
PrevMI = MInsn;
continue;
}
// If scope has not changed then skip this instruction.
if (MIDL == PrevDL) {
PrevMI = MInsn;
continue;
}
// Ignore DBG_VALUE. It does not contribute to any instruction in output.
if (MInsn->isDebugValue())
continue;
if (RangeBeginMI) {
// If we have already seen a beginning of an instruction range and
// current instruction scope does not match scope of first instruction
// in this range then create a new instruction range.
InsnRange R(RangeBeginMI, PrevMI);
MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
MIRanges.push_back(R);
}
// This is a beginning of a new instruction range.
RangeBeginMI = MInsn;
// Reset previous markers.
PrevMI = MInsn;
PrevDL = MIDL;
}
// Create last instruction range.
if (RangeBeginMI && PrevMI && !PrevDL.isUnknown()) {
InsnRange R(RangeBeginMI, PrevMI);
MIRanges.push_back(R);
MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
}
}
}
/// findLexicalScope - Find lexical scope, either regular or inlined, for the
/// given DebugLoc. Return NULL if not found.
LexicalScope *LexicalScopes::findLexicalScope(DebugLoc DL) {
MDNode *Scope = NULL;
MDNode *IA = NULL;
DL.getScopeAndInlinedAt(Scope, IA, MF->getFunction()->getContext());
if (!Scope) return NULL;
// The scope that we were created with could have an extra file - which
// isn't what we care about in this case.
DIDescriptor D = DIDescriptor(Scope);
if (D.isLexicalBlockFile())
Scope = DILexicalBlockFile(Scope).getScope();
Devang Patel
committed
if (IA)
return InlinedLexicalScopeMap.lookup(DebugLoc::getFromDILocation(IA));
return LexicalScopeMap.lookup(Scope);
Devang Patel
committed
}
/// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
/// not available then create new lexical scope.
LexicalScope *LexicalScopes::getOrCreateLexicalScope(DebugLoc DL) {
MDNode *Scope = NULL;
MDNode *InlinedAt = NULL;
DL.getScopeAndInlinedAt(Scope, InlinedAt, MF->getFunction()->getContext());
Devang Patel
committed
if (InlinedAt) {
// Create an abstract scope for inlined function.
getOrCreateAbstractScope(Scope);
// Create an inlined scope for inlined function.
return getOrCreateInlinedScope(Scope, InlinedAt);
}
return getOrCreateRegularScope(Scope);
}
/// getOrCreateRegularScope - Find or create a regular lexical scope.
LexicalScope *LexicalScopes::getOrCreateRegularScope(MDNode *Scope) {
DIDescriptor D = DIDescriptor(Scope);
if (D.isLexicalBlockFile()) {
Scope = DILexicalBlockFile(Scope).getScope();
D = DIDescriptor(Scope);
}
Devang Patel
committed
LexicalScope *WScope = LexicalScopeMap.lookup(Scope);
if (WScope)
return WScope;
LexicalScope *Parent = NULL;
if (D.isLexicalBlock())
Devang Patel
committed
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
Parent = getOrCreateLexicalScope(DebugLoc::getFromDILexicalBlock(Scope));
WScope = new LexicalScope(Parent, DIDescriptor(Scope), NULL, false);
LexicalScopeMap.insert(std::make_pair(Scope, WScope));
if (!Parent && DIDescriptor(Scope).isSubprogram()
&& DISubprogram(Scope).describes(MF->getFunction()))
CurrentFnLexicalScope = WScope;
return WScope;
}
/// getOrCreateInlinedScope - Find or create an inlined lexical scope.
LexicalScope *LexicalScopes::getOrCreateInlinedScope(MDNode *Scope,
MDNode *InlinedAt) {
LexicalScope *InlinedScope = LexicalScopeMap.lookup(InlinedAt);
if (InlinedScope)
return InlinedScope;
DebugLoc InlinedLoc = DebugLoc::getFromDILocation(InlinedAt);
InlinedScope = new LexicalScope(getOrCreateLexicalScope(InlinedLoc),
DIDescriptor(Scope), InlinedAt, false);
InlinedLexicalScopeMap[InlinedLoc] = InlinedScope;
LexicalScopeMap[InlinedAt] = InlinedScope;
return InlinedScope;
}
/// getOrCreateAbstractScope - Find or create an abstract lexical scope.
LexicalScope *LexicalScopes::getOrCreateAbstractScope(const MDNode *N) {
assert(N && "Invalid Scope encoding!");
DIDescriptor Scope(N);
if (Scope.isLexicalBlockFile())
Scope = DILexicalBlockFile(Scope).getScope();
Devang Patel
committed
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
LexicalScope *AScope = AbstractScopeMap.lookup(N);
if (AScope)
return AScope;
LexicalScope *Parent = NULL;
if (Scope.isLexicalBlock()) {
DILexicalBlock DB(N);
DIDescriptor ParentDesc = DB.getContext();
Parent = getOrCreateAbstractScope(ParentDesc);
}
AScope = new LexicalScope(Parent, DIDescriptor(N), NULL, true);
AbstractScopeMap[N] = AScope;
if (DIDescriptor(N).isSubprogram())
AbstractScopesList.push_back(AScope);
return AScope;
}
/// constructScopeNest
void LexicalScopes::constructScopeNest(LexicalScope *Scope) {
assert (Scope && "Unable to calculate scop edominance graph!");
SmallVector<LexicalScope *, 4> WorkStack;
WorkStack.push_back(Scope);
unsigned Counter = 0;
while (!WorkStack.empty()) {
LexicalScope *WS = WorkStack.back();
const SmallVector<LexicalScope *, 4> &Children = WS->getChildren();
bool visitedChildren = false;
for (SmallVector<LexicalScope *, 4>::const_iterator SI = Children.begin(),
SE = Children.end(); SI != SE; ++SI) {
LexicalScope *ChildScope = *SI;
if (!ChildScope->getDFSOut()) {
WorkStack.push_back(ChildScope);
visitedChildren = true;
ChildScope->setDFSIn(++Counter);
break;
}
}
if (!visitedChildren) {
WorkStack.pop_back();
WS->setDFSOut(++Counter);
}
}
}
/// assignInstructionRanges - Find ranges of instructions covered by each
/// lexical scope.
Devang Patel
committed
void LexicalScopes::
assignInstructionRanges(SmallVectorImpl<InsnRange> &MIRanges,
DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap)
{
Devang Patel
committed
LexicalScope *PrevLexicalScope = NULL;
for (SmallVectorImpl<InsnRange>::const_iterator RI = MIRanges.begin(),
RE = MIRanges.end(); RI != RE; ++RI) {
const InsnRange &R = *RI;
LexicalScope *S = MI2ScopeMap.lookup(R.first);
assert (S && "Lost LexicalScope for a machine instruction!");
if (PrevLexicalScope && !PrevLexicalScope->dominates(S))
PrevLexicalScope->closeInsnRange(S);
S->openInsnRange(R.first);
S->extendInsnRange(R.second);
PrevLexicalScope = S;
}
if (PrevLexicalScope)
PrevLexicalScope->closeInsnRange();
}
/// getMachineBasicBlocks - Populate given set using machine basic blocks which
/// have machine instructions that belong to lexical scope identified by
/// DebugLoc.
void LexicalScopes::
getMachineBasicBlocks(DebugLoc DL,
SmallPtrSet<const MachineBasicBlock*, 4> &MBBs) {
Devang Patel
committed
MBBs.clear();
LexicalScope *Scope = getOrCreateLexicalScope(DL);
if (!Scope)
return;
if (Scope == CurrentFnLexicalScope) {
for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
I != E; ++I)
MBBs.insert(I);
return;
}
Devang Patel
committed
SmallVector<InsnRange, 4> &InsnRanges = Scope->getRanges();
for (SmallVector<InsnRange, 4>::iterator I = InsnRanges.begin(),
E = InsnRanges.end(); I != E; ++I) {
InsnRange &R = *I;
MBBs.insert(R.first->getParent());
}
}
/// dominates - Return true if DebugLoc's lexical scope dominates at least one
/// machine instruction's lexical scope in a given machine basic block.
bool LexicalScopes::dominates(DebugLoc DL, MachineBasicBlock *MBB) {
LexicalScope *Scope = getOrCreateLexicalScope(DL);
if (!Scope)
return false;
// Current function scope covers all basic blocks in the function.
if (Scope == CurrentFnLexicalScope && MBB->getParent() == MF)
return true;
Devang Patel
committed
bool Result = false;
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
I != E; ++I) {
DebugLoc IDL = I->getDebugLoc();
if (IDL.isUnknown())
continue;
if (LexicalScope *IScope = getOrCreateLexicalScope(IDL))
if (Scope->dominates(IScope))
return true;
}
return Result;
}
David Blaikie
committed
void LexicalScope::anchor() { }
Devang Patel
committed
/// dump - Print data structures.
void LexicalScope::dump() const {
#ifndef NDEBUG
raw_ostream &err = dbgs();
err.indent(IndentLevel);
err << "DFSIn: " << DFSIn << " DFSOut: " << DFSOut << "\n";
const MDNode *N = Desc;
N->dump();
if (AbstractScope)
err << "Abstract Scope\n";
IndentLevel += 2;
if (!Children.empty())
err << "Children ...\n";
for (unsigned i = 0, e = Children.size(); i != e; ++i)
if (Children[i] != this)
Children[i]->dump();
IndentLevel -= 2;
#endif
}