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