LLVM  4.0.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  Scope = Scope->getNonLexicalBlockFileScope();
117 
118  if (auto *IA = DL->getInlinedAt()) {
119  auto I = InlinedLexicalScopeMap.find(std::make_pair(Scope, IA));
120  return I != InlinedLexicalScopeMap.end() ? &I->second : nullptr;
121  }
122  return findLexicalScope(Scope);
123 }
124 
125 /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
126 /// not available then create new lexical scope.
127 LexicalScope *LexicalScopes::getOrCreateLexicalScope(const DILocalScope *Scope,
128  const DILocation *IA) {
129  if (IA) {
130  // Create an abstract scope for inlined function.
132  // Create an inlined scope for inlined function.
133  return getOrCreateInlinedScope(Scope, IA);
134  }
135 
136  return getOrCreateRegularScope(Scope);
137 }
138 
139 /// getOrCreateRegularScope - Find or create a regular lexical scope.
140 LexicalScope *
141 LexicalScopes::getOrCreateRegularScope(const DILocalScope *Scope) {
142  assert(Scope && "Invalid Scope encoding!");
143  Scope = Scope->getNonLexicalBlockFileScope();
144 
145  auto I = LexicalScopeMap.find(Scope);
146  if (I != LexicalScopeMap.end())
147  return &I->second;
148 
149  // FIXME: Should the following dyn_cast be DILexicalBlock?
150  LexicalScope *Parent = nullptr;
151  if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
152  Parent = getOrCreateLexicalScope(Block->getScope());
153  I = LexicalScopeMap.emplace(std::piecewise_construct,
154  std::forward_as_tuple(Scope),
155  std::forward_as_tuple(Parent, Scope, nullptr,
156  false)).first;
157 
158  if (!Parent) {
159  assert(cast<DISubprogram>(Scope)->describes(MF->getFunction()));
160  assert(!CurrentFnLexicalScope);
161  CurrentFnLexicalScope = &I->second;
162  }
163 
164  return &I->second;
165 }
166 
167 /// getOrCreateInlinedScope - Find or create an inlined lexical scope.
168 LexicalScope *
169 LexicalScopes::getOrCreateInlinedScope(const DILocalScope *Scope,
170  const DILocation *InlinedAt) {
171  assert(Scope && "Invalid Scope encoding!");
172  Scope = Scope->getNonLexicalBlockFileScope();
173  std::pair<const DILocalScope *, const DILocation *> P(Scope, InlinedAt);
174  auto I = InlinedLexicalScopeMap.find(P);
175  if (I != InlinedLexicalScopeMap.end())
176  return &I->second;
177 
178  LexicalScope *Parent;
179  if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
180  Parent = getOrCreateInlinedScope(Block->getScope(), InlinedAt);
181  else
182  Parent = getOrCreateLexicalScope(InlinedAt);
183 
184  I = InlinedLexicalScopeMap.emplace(std::piecewise_construct,
185  std::forward_as_tuple(P),
186  std::forward_as_tuple(Parent, Scope,
187  InlinedAt, false))
188  .first;
189  return &I->second;
190 }
191 
192 /// getOrCreateAbstractScope - Find or create an abstract lexical scope.
193 LexicalScope *
195  assert(Scope && "Invalid Scope encoding!");
196  Scope = Scope->getNonLexicalBlockFileScope();
197  auto I = AbstractScopeMap.find(Scope);
198  if (I != AbstractScopeMap.end())
199  return &I->second;
200 
201  // FIXME: Should the following isa be DILexicalBlock?
202  LexicalScope *Parent = nullptr;
203  if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
204  Parent = getOrCreateAbstractScope(Block->getScope());
205 
206  I = AbstractScopeMap.emplace(std::piecewise_construct,
207  std::forward_as_tuple(Scope),
208  std::forward_as_tuple(Parent, Scope,
209  nullptr, true)).first;
210  if (isa<DISubprogram>(Scope))
211  AbstractScopesList.push_back(&I->second);
212  return &I->second;
213 }
214 
215 /// constructScopeNest
216 void LexicalScopes::constructScopeNest(LexicalScope *Scope) {
217  assert(Scope && "Unable to calculate scope dominance graph!");
219  WorkStack.push_back(Scope);
220  unsigned Counter = 0;
221  while (!WorkStack.empty()) {
222  LexicalScope *WS = WorkStack.back();
223  const SmallVectorImpl<LexicalScope *> &Children = WS->getChildren();
224  bool visitedChildren = false;
225  for (auto &ChildScope : Children)
226  if (!ChildScope->getDFSOut()) {
227  WorkStack.push_back(ChildScope);
228  visitedChildren = true;
229  ChildScope->setDFSIn(++Counter);
230  break;
231  }
232  if (!visitedChildren) {
233  WorkStack.pop_back();
234  WS->setDFSOut(++Counter);
235  }
236  }
237 }
238 
239 /// assignInstructionRanges - Find ranges of instructions covered by each
240 /// lexical scope.
241 void LexicalScopes::assignInstructionRanges(
242  SmallVectorImpl<InsnRange> &MIRanges,
244 
245  LexicalScope *PrevLexicalScope = nullptr;
246  for (const auto &R : MIRanges) {
247  LexicalScope *S = MI2ScopeMap.lookup(R.first);
248  assert(S && "Lost LexicalScope for a machine instruction!");
249  if (PrevLexicalScope && !PrevLexicalScope->dominates(S))
250  PrevLexicalScope->closeInsnRange(S);
251  S->openInsnRange(R.first);
252  S->extendInsnRange(R.second);
253  PrevLexicalScope = S;
254  }
255 
256  if (PrevLexicalScope)
257  PrevLexicalScope->closeInsnRange();
258 }
259 
260 /// getMachineBasicBlocks - Populate given set using machine basic blocks which
261 /// have machine instructions that belong to lexical scope identified by
262 /// DebugLoc.
265  MBBs.clear();
266  LexicalScope *Scope = getOrCreateLexicalScope(DL);
267  if (!Scope)
268  return;
269 
270  if (Scope == CurrentFnLexicalScope) {
271  for (const auto &MBB : *MF)
272  MBBs.insert(&MBB);
273  return;
274  }
275 
276  SmallVectorImpl<InsnRange> &InsnRanges = Scope->getRanges();
277  for (auto &R : InsnRanges)
278  MBBs.insert(R.first->getParent());
279 }
280 
281 /// dominates - Return true if DebugLoc's lexical scope dominates at least one
282 /// machine instruction's lexical scope in a given machine basic block.
284  LexicalScope *Scope = getOrCreateLexicalScope(DL);
285  if (!Scope)
286  return false;
287 
288  // Current function scope covers all basic blocks in the function.
289  if (Scope == CurrentFnLexicalScope && MBB->getParent() == MF)
290  return true;
291 
292  bool Result = false;
293  for (auto &I : *MBB) {
294  if (const DILocation *IDL = I.getDebugLoc())
295  if (LexicalScope *IScope = getOrCreateLexicalScope(IDL))
296  if (Scope->dominates(IScope))
297  return true;
298  }
299  return Result;
300 }
301 
302 /// dump - Print data structures.
303 void LexicalScope::dump(unsigned Indent) const {
304 #ifndef NDEBUG
305  raw_ostream &err = dbgs();
306  err.indent(Indent);
307  err << "DFSIn: " << DFSIn << " DFSOut: " << DFSOut << "\n";
308  const MDNode *N = Desc;
309  err.indent(Indent);
310  N->dump();
311  if (AbstractScope)
312  err << std::string(Indent, ' ') << "Abstract Scope\n";
313 
314  if (!Children.empty())
315  err << std::string(Indent + 2, ' ') << "Children ...\n";
316  for (unsigned i = 0, e = Children.size(); i != e; ++i)
317  if (Children[i] != this)
318  Children[i]->dump(Indent + 2);
319 #endif
320 }
void push_back(const T &Elt)
Definition: SmallVector.h:211
const MachineFunction * getParent() const
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
size_t i
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:162
bool dominates(const DILocation *DL, MachineBasicBlock *MBB)
dominates - Return true if DebugLoc's lexical scope dominates at least one machine instruction's lexi...
static int Counter
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
SmallVectorImpl< InsnRange > & getRanges()
Definition: LexicalScopes.h:65
Metadata node.
Definition: Metadata.h:830
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:345
DILocalScope * getNonLexicalBlockFileScope() const
Get the first non DILexicalBlockFile scope of this scope.
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.
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:60
MachineBasicBlock * MBB
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.
#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:368
void dump() const
User-friendly dump.
Definition: AsmWriter.cpp:3562
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:132
Representation of each machine instruction.
Definition: MachineInstr.h:52
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
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44