LexicalScopes.cpp revision 314564
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
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"
25using namespace llvm;
26
27#define DEBUG_TYPE "lexicalscopes"
28
29/// reset - Reset the instance so that it's prepared for another function.
30void LexicalScopes::reset() {
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.
40void LexicalScopes::initialize(const MachineFunction &Fn) {
41  reset();
42  MF = &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);
49  }
50}
51
52/// extractLexicalScopes - Extract instruction ranges for each lexical scopes
53/// for the given machine function.
54void LexicalScopes::extractLexicalScopes(
55    SmallVectorImpl<InsnRange> &MIRanges,
56    DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) {
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.
109LexicalScope *LexicalScopes::findLexicalScope(const DILocation *DL) {
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.
127LexicalScope *LexicalScopes::getOrCreateLexicalScope(const DILocalScope *Scope,
128                                                     const DILocation *IA) {
129  if (IA) {
130    // Create an abstract scope for inlined function.
131    getOrCreateAbstractScope(Scope);
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.
140LexicalScope *
141LexicalScopes::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.
168LexicalScope *
169LexicalScopes::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.
193LexicalScope *
194LexicalScopes::getOrCreateAbstractScope(const DILocalScope *Scope) {
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
216void LexicalScopes::constructScopeNest(LexicalScope *Scope) {
217  assert(Scope && "Unable to calculate scope dominance graph!");
218  SmallVector<LexicalScope *, 4> WorkStack;
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.
241void LexicalScopes::assignInstructionRanges(
242    SmallVectorImpl<InsnRange> &MIRanges,
243    DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) {
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.
263void LexicalScopes::getMachineBasicBlocks(
264    const DILocation *DL, SmallPtrSetImpl<const MachineBasicBlock *> &MBBs) {
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.
283bool LexicalScopes::dominates(const DILocation *DL, MachineBasicBlock *MBB) {
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.
303void 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}
321