LLVM  3.7.0
LexicalScopes.cpp
Go to the documentation of this file.
1 //===- LexicalScopes.cpp - Collecting lexical scope info ------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements LexicalScopes analysis.
11 //
12 // This pass collects lexical scope information and maps machine instructions
13 // to respective lexical scopes.
14 //
15 //===----------------------------------------------------------------------===//
16 
20 #include "llvm/IR/DebugInfo.h"
21 #include "llvm/IR/Function.h"
22 #include "llvm/Support/Debug.h"
25 using namespace llvm;
26 
27 #define DEBUG_TYPE "lexicalscopes"
28 
29 /// reset - Reset the instance so that it's prepared for another function.
31  MF = nullptr;
32  CurrentFnLexicalScope = nullptr;
33  LexicalScopeMap.clear();
34  AbstractScopeMap.clear();
35  InlinedLexicalScopeMap.clear();
36  AbstractScopesList.clear();
37 }
38 
39 /// initialize - Scan machine function and constuct lexical scope nest.
41  reset();
42  MF = &Fn;
45  extractLexicalScopes(MIRanges, MI2ScopeMap);
46  if (CurrentFnLexicalScope) {
47  constructScopeNest(CurrentFnLexicalScope);
48  assignInstructionRanges(MIRanges, MI2ScopeMap);
49  }
50 }
51 
52 /// extractLexicalScopes - Extract instruction ranges for each lexical scopes
53 /// for the given machine function.
54 void LexicalScopes::extractLexicalScopes(
57 
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();
66  if (!MIDL) {
67  PrevMI = &MInsn;
68  continue;
69  }
70 
71  // If scope has not changed then skip this instruction.
72  if (MIDL == PrevDL) {
73  PrevMI = &MInsn;
74  continue;
75  }
76 
77  // Ignore DBG_VALUE. It does not contribute to any instruction in output.
78  if (MInsn.isDebugValue())
79  continue;
80 
81  if (RangeBeginMI) {
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);
88  }
89 
90  // This is a beginning of a new instruction range.
91  RangeBeginMI = &MInsn;
92 
93  // Reset previous markers.
94  PrevMI = &MInsn;
95  PrevDL = MIDL;
96  }
97 
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);
103  }
104  }
105 }
106 
107 /// findLexicalScope - Find lexical scope, either regular or inlined, for the
108 /// given DebugLoc. Return NULL if not found.
110  DILocalScope *Scope = DL->getScope();
111  if (!Scope)
112  return nullptr;
113 
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();
118 
119  if (auto *IA = DL->getInlinedAt()) {
120  auto I = InlinedLexicalScopeMap.find(std::make_pair(Scope, IA));
121  return I != InlinedLexicalScopeMap.end() ? &I->second : nullptr;
122  }
123  return findLexicalScope(Scope);
124 }
125 
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) {
130  if (IA) {
131  // Create an abstract scope for inlined function.
133  // Create an inlined scope for inlined function.
134  return getOrCreateInlinedScope(Scope, IA);
135  }
136 
137  return getOrCreateRegularScope(Scope);
138 }
139 
140 /// getOrCreateRegularScope - Find or create a regular lexical scope.
141 LexicalScope *
142 LexicalScopes::getOrCreateRegularScope(const DILocalScope *Scope) {
143  if (auto *File = dyn_cast<DILexicalBlockFile>(Scope))
144  Scope = File->getScope();
145 
146  auto I = LexicalScopeMap.find(Scope);
147  if (I != LexicalScopeMap.end())
148  return &I->second;
149 
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,
157  false)).first;
158 
159  if (!Parent) {
160  assert(cast<DISubprogram>(Scope)->describes(MF->getFunction()));
161  assert(!CurrentFnLexicalScope);
162  CurrentFnLexicalScope = &I->second;
163  }
164 
165  return &I->second;
166 }
167 
168 /// getOrCreateInlinedScope - Find or create an inlined lexical scope.
169 LexicalScope *
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())
175  return &I->second;
176 
177  LexicalScope *Parent;
178  if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
179  Parent = getOrCreateInlinedScope(Block->getScope(), InlinedAt);
180  else
181  Parent = getOrCreateLexicalScope(InlinedAt);
182 
183  I = InlinedLexicalScopeMap.emplace(std::piecewise_construct,
184  std::forward_as_tuple(P),
185  std::forward_as_tuple(Parent, Scope,
186  InlinedAt, false))
187  .first;
188  return &I->second;
189 }
190 
191 /// getOrCreateAbstractScope - Find or create an abstract lexical scope.
192 LexicalScope *
194  assert(Scope && "Invalid Scope encoding!");
195 
196  if (auto *File = dyn_cast<DILexicalBlockFile>(Scope))
197  Scope = File->getScope();
198  auto I = AbstractScopeMap.find(Scope);
199  if (I != AbstractScopeMap.end())
200  return &I->second;
201 
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());
206 
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);
213  return &I->second;
214 }
215 
216 /// constructScopeNest
217 void LexicalScopes::constructScopeNest(LexicalScope *Scope) {
218  assert(Scope && "Unable to calculate scope dominance graph!");
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;
227  SE = Children.end();
228  SI != SE; ++SI) {
229  LexicalScope *ChildScope = *SI;
230  if (!ChildScope->getDFSOut()) {
231  WorkStack.push_back(ChildScope);
232  visitedChildren = true;
233  ChildScope->setDFSIn(++Counter);
234  break;
235  }
236  }
237  if (!visitedChildren) {
238  WorkStack.pop_back();
239  WS->setDFSOut(++Counter);
240  }
241  }
242 }
243 
244 /// assignInstructionRanges - Find ranges of instructions covered by each
245 /// lexical scope.
246 void LexicalScopes::assignInstructionRanges(
247  SmallVectorImpl<InsnRange> &MIRanges,
249 
250  LexicalScope *PrevLexicalScope = nullptr;
252  RE = MIRanges.end();
253  RI != RE; ++RI) {
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;
262  }
263 
264  if (PrevLexicalScope)
265  PrevLexicalScope->closeInsnRange();
266 }
267 
268 /// getMachineBasicBlocks - Populate given set using machine basic blocks which
269 /// have machine instructions that belong to lexical scope identified by
270 /// DebugLoc.
273  MBBs.clear();
274  LexicalScope *Scope = getOrCreateLexicalScope(DL);
275  if (!Scope)
276  return;
277 
278  if (Scope == CurrentFnLexicalScope) {
279  for (const auto &MBB : *MF)
280  MBBs.insert(&MBB);
281  return;
282  }
283 
284  SmallVectorImpl<InsnRange> &InsnRanges = Scope->getRanges();
285  for (SmallVectorImpl<InsnRange>::iterator I = InsnRanges.begin(),
286  E = InsnRanges.end();
287  I != E; ++I) {
288  InsnRange &R = *I;
289  MBBs.insert(R.first->getParent());
290  }
291 }
292 
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.
296  LexicalScope *Scope = getOrCreateLexicalScope(DL);
297  if (!Scope)
298  return false;
299 
300  // Current function scope covers all basic blocks in the function.
301  if (Scope == CurrentFnLexicalScope && MBB->getParent() == MF)
302  return true;
303 
304  bool Result = false;
305  for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E;
306  ++I) {
307  if (const DILocation *IDL = I->getDebugLoc())
308  if (LexicalScope *IScope = getOrCreateLexicalScope(IDL))
309  if (Scope->dominates(IScope))
310  return true;
311  }
312  return Result;
313 }
314 
315 /// dump - Print data structures.
316 void LexicalScope::dump(unsigned Indent) const {
317 #ifndef NDEBUG
318  raw_ostream &err = dbgs();
319  err.indent(Indent);
320  err << "DFSIn: " << DFSIn << " DFSOut: " << DFSOut << "\n";
321  const MDNode *N = Desc;
322  err.indent(Indent);
323  N->dump();
324  if (AbstractScope)
325  err << std::string(Indent, ' ') << "Abstract Scope\n";
326 
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);
332 #endif
333 }
void push_back(const T &Elt)
Definition: SmallVector.h:222
const MachineFunction * getParent() const
getParent - Return the MachineFunction containing this basic block.
void openInsnRange(const MachineInstr *MI)
openInsnRange - This scope covers instruction range starting from MI.
Definition: LexicalScopes.h:71
void dump(unsigned Indent=0) const
dump - print lexical scope.
void extendInsnRange(const MachineInstr *MI)
extendInsnRange - Extend the current instruction range covered by this scope.
Definition: LexicalScopes.h:81
ValueT lookup(const KeyT &Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition: DenseMap.h:159
bool dominates(const DILocation *DL, MachineBasicBlock *MBB)
dominates - Return true if DebugLoc's lexical scope dominates at least one machine instruction's lexi...
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
SmallVectorImpl< InsnRange > & getRanges()
Definition: LexicalScopes.h:65
Metadata node.
Definition: Metadata.h:740
LexicalScope - This class is used to track scope information.
Definition: LexicalScopes.h:45
A scope for locals.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Definition: SmallPtrSet.h:242
LexicalScope * getOrCreateAbstractScope(const DILocalScope *Scope)
getOrCreateAbstractScope - Find or create an abstract lexical scope.
SmallVectorImpl< LexicalScope * > & getChildren()
Definition: LexicalScopes.h:64
void setDFSOut(unsigned O)
void reset()
releaseMemory - release memory.
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
Definition: SmallVector.h:57
void initialize(const MachineFunction &)
initialize - Scan machine function and constuct lexical scope nest, resets the instance if necessary...
LexicalScope * findLexicalScope(const DILocation *DL)
findLexicalScope - Find lexical scope, either regular or inlined, for the given DebugLoc.
Debug location.
bundle_iterator< MachineInstr, instr_iterator > iterator
#define P(N)
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
bool dominates(const LexicalScope *S) const
dominates - Return true if current scope dominates given lexical scope.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:264
unsigned getDFSOut() const
void setDFSIn(unsigned I)
void dump() const
User-friendly dump.
Definition: AsmWriter.cpp:3372
void getMachineBasicBlocks(const DILocation *DL, SmallPtrSetImpl< const MachineBasicBlock * > &MBBs)
getMachineBasicBlocks - Populate given set using machine basic blocks which have machine instructions...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:123
Representation of each machine instruction.
Definition: MachineInstr.h:51
void closeInsnRange(LexicalScope *NewScope=nullptr)
closeInsnRange - Create a range based on FirstInsn and LastInsn collected until now.
Definition: LexicalScopes.h:91
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
std::pair< const MachineInstr *, const MachineInstr * > InsnRange
InsnRange - This is used to track range of instructions with identical lexical scope.
Definition: LexicalScopes.h:34
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:38