LCOV - code coverage report
Current view: top level - lib/CodeGen - LexicalScopes.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 111 111 100.0 %
Date: 2018-10-20 13:21:21 Functions: 12 12 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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/ADT/DenseMap.h"
      19             : #include "llvm/ADT/SmallVector.h"
      20             : #include "llvm/CodeGen/MachineBasicBlock.h"
      21             : #include "llvm/CodeGen/MachineFunction.h"
      22             : #include "llvm/CodeGen/MachineInstr.h"
      23             : #include "llvm/Config/llvm-config.h"
      24             : #include "llvm/IR/DebugInfoMetadata.h"
      25             : #include "llvm/IR/Metadata.h"
      26             : #include "llvm/Support/Casting.h"
      27             : #include "llvm/Support/Compiler.h"
      28             : #include "llvm/Support/Debug.h"
      29             : #include "llvm/Support/raw_ostream.h"
      30             : #include <cassert>
      31             : #include <string>
      32             : #include <tuple>
      33             : #include <utility>
      34             : 
      35             : using namespace llvm;
      36             : 
      37             : #define DEBUG_TYPE "lexicalscopes"
      38             : 
      39             : /// reset - Reset the instance so that it's prepared for another function.
      40       28566 : void LexicalScopes::reset() {
      41       28566 :   MF = nullptr;
      42       28566 :   CurrentFnLexicalScope = nullptr;
      43             :   LexicalScopeMap.clear();
      44             :   AbstractScopeMap.clear();
      45             :   InlinedLexicalScopeMap.clear();
      46             :   AbstractScopesList.clear();
      47       28566 : }
      48             : 
      49             : /// initialize - Scan machine function and constuct lexical scope nest.
      50       28566 : void LexicalScopes::initialize(const MachineFunction &Fn) {
      51       28566 :   reset();
      52             :   // Don't attempt any lexical scope creation for a NoDebug compile unit.
      53       57132 :   if (Fn.getFunction().getSubprogram()->getUnit()->getEmissionKind() ==
      54             :       DICompileUnit::NoDebug)
      55          16 :     return;
      56       28550 :   MF = &Fn;
      57             :   SmallVector<InsnRange, 4> MIRanges;
      58             :   DenseMap<const MachineInstr *, LexicalScope *> MI2ScopeMap;
      59       28550 :   extractLexicalScopes(MIRanges, MI2ScopeMap);
      60       28550 :   if (CurrentFnLexicalScope) {
      61       28387 :     constructScopeNest(CurrentFnLexicalScope);
      62       28387 :     assignInstructionRanges(MIRanges, MI2ScopeMap);
      63             :   }
      64             : }
      65             : 
      66             : /// extractLexicalScopes - Extract instruction ranges for each lexical scopes
      67             : /// for the given machine function.
      68       28550 : void LexicalScopes::extractLexicalScopes(
      69             :     SmallVectorImpl<InsnRange> &MIRanges,
      70             :     DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) {
      71             :   // Scan each instruction and create scopes. First build working set of scopes.
      72      723799 :   for (const auto &MBB : *MF) {
      73      695249 :     const MachineInstr *RangeBeginMI = nullptr;
      74             :     const MachineInstr *PrevMI = nullptr;
      75             :     const DILocation *PrevDL = nullptr;
      76     6503581 :     for (const auto &MInsn : MBB) {
      77             :       // Check if instruction has valid location information.
      78             :       const DILocation *MIDL = MInsn.getDebugLoc();
      79     5808332 :       if (!MIDL) {
      80             :         PrevMI = &MInsn;
      81             :         continue;
      82             :       }
      83             : 
      84             :       // If scope has not changed then skip this instruction.
      85     4763108 :       if (MIDL == PrevDL) {
      86             :         PrevMI = &MInsn;
      87             :         continue;
      88             :       }
      89             : 
      90             :       // Ignore DBG_VALUE and similar instruction that do not contribute to any
      91             :       // instruction in the output.
      92             :       if (MInsn.isMetaInstruction())
      93             :         continue;
      94             : 
      95     1731730 :       if (RangeBeginMI) {
      96             :         // If we have already seen a beginning of an instruction range and
      97             :         // current instruction scope does not match scope of first instruction
      98             :         // in this range then create a new instruction range.
      99             :         InsnRange R(RangeBeginMI, PrevMI);
     100     1170920 :         MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
     101     1170920 :         MIRanges.push_back(R);
     102             :       }
     103             : 
     104             :       // This is a beginning of a new instruction range.
     105     1731730 :       RangeBeginMI = &MInsn;
     106             : 
     107             :       // Reset previous markers.
     108             :       PrevMI = &MInsn;
     109             :       PrevDL = MIDL;
     110             :     }
     111             : 
     112             :     // Create last instruction range.
     113      695249 :     if (RangeBeginMI && PrevMI && PrevDL) {
     114             :       InsnRange R(RangeBeginMI, PrevMI);
     115      560810 :       MIRanges.push_back(R);
     116      560810 :       MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
     117             :     }
     118             :   }
     119       28550 : }
     120             : 
     121             : /// findLexicalScope - Find lexical scope, either regular or inlined, for the
     122             : /// given DebugLoc. Return NULL if not found.
     123      157341 : LexicalScope *LexicalScopes::findLexicalScope(const DILocation *DL) {
     124             :   DILocalScope *Scope = DL->getScope();
     125      157341 :   if (!Scope)
     126             :     return nullptr;
     127             : 
     128             :   // The scope that we were created with could have an extra file - which
     129             :   // isn't what we care about in this case.
     130      157341 :   Scope = Scope->getNonLexicalBlockFileScope();
     131             : 
     132             :   if (auto *IA = DL->getInlinedAt()) {
     133      133874 :     auto I = InlinedLexicalScopeMap.find(std::make_pair(Scope, IA));
     134      133874 :     return I != InlinedLexicalScopeMap.end() ? &I->second : nullptr;
     135             :   }
     136       23467 :   return findLexicalScope(Scope);
     137             : }
     138             : 
     139             : /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
     140             : /// not available then create new lexical scope.
     141     3409899 : LexicalScope *LexicalScopes::getOrCreateLexicalScope(const DILocalScope *Scope,
     142             :                                                      const DILocation *IA) {
     143     3409899 :   if (IA) {
     144             :     // Skip scopes inlined from a NoDebug compile unit.
     145     4906010 :     if (Scope->getSubprogram()->getUnit()->getEmissionKind() ==
     146             :         DICompileUnit::NoDebug)
     147           3 :       return getOrCreateLexicalScope(IA);
     148             :     // Create an abstract scope for inlined function.
     149     2453002 :     getOrCreateAbstractScope(Scope);
     150             :     // Create an inlined scope for inlined function.
     151     2453002 :     return getOrCreateInlinedScope(Scope, IA);
     152             :   }
     153             : 
     154      956894 :   return getOrCreateRegularScope(Scope);
     155             : }
     156             : 
     157             : /// getOrCreateRegularScope - Find or create a regular lexical scope.
     158             : LexicalScope *
     159      956894 : LexicalScopes::getOrCreateRegularScope(const DILocalScope *Scope) {
     160             :   assert(Scope && "Invalid Scope encoding!");
     161      956894 :   Scope = Scope->getNonLexicalBlockFileScope();
     162             : 
     163             :   auto I = LexicalScopeMap.find(Scope);
     164      956894 :   if (I != LexicalScopeMap.end())
     165      906533 :     return &I->second;
     166             : 
     167             :   // FIXME: Should the following dyn_cast be DILexicalBlock?
     168       50361 :   LexicalScope *Parent = nullptr;
     169             :   if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
     170       21973 :     Parent = getOrCreateLexicalScope(Block->getScope());
     171             :   I = LexicalScopeMap.emplace(std::piecewise_construct,
     172       50361 :                               std::forward_as_tuple(Scope),
     173      100722 :                               std::forward_as_tuple(Parent, Scope, nullptr,
     174       50361 :                                                     false)).first;
     175             : 
     176       50361 :   if (!Parent) {
     177             :     assert(cast<DISubprogram>(Scope)->describes(&MF->getFunction()));
     178             :     assert(!CurrentFnLexicalScope);
     179       28388 :     CurrentFnLexicalScope = &I->second;
     180             :   }
     181             : 
     182       50361 :   return &I->second;
     183             : }
     184             : 
     185             : /// getOrCreateInlinedScope - Find or create an inlined lexical scope.
     186             : LexicalScope *
     187     2507392 : LexicalScopes::getOrCreateInlinedScope(const DILocalScope *Scope,
     188             :                                        const DILocation *InlinedAt) {
     189             :   assert(Scope && "Invalid Scope encoding!");
     190     2507392 :   Scope = Scope->getNonLexicalBlockFileScope();
     191             :   std::pair<const DILocalScope *, const DILocation *> P(Scope, InlinedAt);
     192             :   auto I = InlinedLexicalScopeMap.find(P);
     193     2507392 :   if (I != InlinedLexicalScopeMap.end())
     194     1968917 :     return &I->second;
     195             : 
     196             :   LexicalScope *Parent;
     197      538475 :   if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
     198      108780 :     Parent = getOrCreateInlinedScope(Block->getScope(), InlinedAt);
     199             :   else
     200      484085 :     Parent = getOrCreateLexicalScope(InlinedAt);
     201             : 
     202             :   I = InlinedLexicalScopeMap
     203      538475 :           .emplace(std::piecewise_construct, std::forward_as_tuple(P),
     204      538475 :                    std::forward_as_tuple(Parent, Scope, InlinedAt, false))
     205             :           .first;
     206      538475 :   return &I->second;
     207             : }
     208             : 
     209             : /// getOrCreateAbstractScope - Find or create an abstract lexical scope.
     210             : LexicalScope *
     211     2489194 : LexicalScopes::getOrCreateAbstractScope(const DILocalScope *Scope) {
     212             :   assert(Scope && "Invalid Scope encoding!");
     213     2489194 :   Scope = Scope->getNonLexicalBlockFileScope();
     214             :   auto I = AbstractScopeMap.find(Scope);
     215     2489194 :   if (I != AbstractScopeMap.end())
     216     2269819 :     return &I->second;
     217             : 
     218             :   // FIXME: Should the following isa be DILexicalBlock?
     219      219375 :   LexicalScope *Parent = nullptr;
     220             :   if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope))
     221       32092 :     Parent = getOrCreateAbstractScope(Block->getScope());
     222             : 
     223             :   I = AbstractScopeMap.emplace(std::piecewise_construct,
     224      219375 :                                std::forward_as_tuple(Scope),
     225      219375 :                                std::forward_as_tuple(Parent, Scope,
     226      219375 :                                                      nullptr, true)).first;
     227      438750 :   if (isa<DISubprogram>(Scope))
     228      187283 :     AbstractScopesList.push_back(&I->second);
     229      219375 :   return &I->second;
     230             : }
     231             : 
     232             : /// constructScopeNest
     233       28387 : void LexicalScopes::constructScopeNest(LexicalScope *Scope) {
     234             :   assert(Scope && "Unable to calculate scope dominance graph!");
     235             :   SmallVector<LexicalScope *, 4> WorkStack;
     236       28387 :   WorkStack.push_back(Scope);
     237             :   unsigned Counter = 0;
     238     1167006 :   while (!WorkStack.empty()) {
     239     1138619 :     LexicalScope *WS = WorkStack.back();
     240             :     const SmallVectorImpl<LexicalScope *> &Children = WS->getChildren();
     241             :     bool visitedChildren = false;
     242     7110399 :     for (auto &ChildScope : Children)
     243     6526896 :       if (!ChildScope->getDFSOut()) {
     244      555116 :         WorkStack.push_back(ChildScope);
     245             :         visitedChildren = true;
     246      555116 :         ChildScope->setDFSIn(++Counter);
     247             :         break;
     248             :       }
     249     1138619 :     if (!visitedChildren) {
     250             :       WorkStack.pop_back();
     251      583503 :       WS->setDFSOut(++Counter);
     252             :     }
     253             :   }
     254       28387 : }
     255             : 
     256             : /// assignInstructionRanges - Find ranges of instructions covered by each
     257             : /// lexical scope.
     258       28387 : void LexicalScopes::assignInstructionRanges(
     259             :     SmallVectorImpl<InsnRange> &MIRanges,
     260             :     DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) {
     261             :   LexicalScope *PrevLexicalScope = nullptr;
     262     1760117 :   for (const auto &R : MIRanges) {
     263     1731730 :     LexicalScope *S = MI2ScopeMap.lookup(R.first);
     264             :     assert(S && "Lost LexicalScope for a machine instruction!");
     265     1731730 :     if (PrevLexicalScope && !PrevLexicalScope->dominates(S))
     266      563021 :       PrevLexicalScope->closeInsnRange(S);
     267     1731730 :     S->openInsnRange(R.first);
     268     1731730 :     S->extendInsnRange(R.second);
     269             :     PrevLexicalScope = S;
     270             :   }
     271             : 
     272       28387 :   if (PrevLexicalScope)
     273       28387 :     PrevLexicalScope->closeInsnRange();
     274       28387 : }
     275             : 
     276             : /// getMachineBasicBlocks - Populate given set using machine basic blocks which
     277             : /// have machine instructions that belong to lexical scope identified by
     278             : /// DebugLoc.
     279       52431 : void LexicalScopes::getMachineBasicBlocks(
     280             :     const DILocation *DL, SmallPtrSetImpl<const MachineBasicBlock *> &MBBs) {
     281             :   assert(MF && "Method called on a uninitialized LexicalScopes object!");
     282       52431 :   MBBs.clear();
     283             : 
     284       52431 :   LexicalScope *Scope = getOrCreateLexicalScope(DL);
     285       52431 :   if (!Scope)
     286             :     return;
     287             : 
     288       52431 :   if (Scope == CurrentFnLexicalScope) {
     289      211444 :     for (const auto &MBB : *MF)
     290      205292 :       MBBs.insert(&MBB);
     291             :     return;
     292             :   }
     293             : 
     294             :   SmallVectorImpl<InsnRange> &InsnRanges = Scope->getRanges();
     295       96808 :   for (auto &R : InsnRanges)
     296       50529 :     MBBs.insert(R.first->getParent());
     297             : }
     298             : 
     299             : /// dominates - Return true if DebugLoc's lexical scope dominates at least one
     300             : /// machine instruction's lexical scope in a given machine basic block.
     301      178474 : bool LexicalScopes::dominates(const DILocation *DL, MachineBasicBlock *MBB) {
     302             :   assert(MF && "Unexpected uninitialized LexicalScopes object!");
     303      178474 :   LexicalScope *Scope = getOrCreateLexicalScope(DL);
     304      178474 :   if (!Scope)
     305             :     return false;
     306             : 
     307             :   // Current function scope covers all basic blocks in the function.
     308      178474 :   if (Scope == CurrentFnLexicalScope && MBB->getParent() == MF)
     309             :     return true;
     310             : 
     311             :   bool Result = false;
     312     1077972 :   for (auto &I : *MBB) {
     313      991304 :     if (const DILocation *IDL = I.getDebugLoc())
     314      941203 :       if (LexicalScope *IScope = getOrCreateLexicalScope(IDL))
     315             :         if (Scope->dominates(IScope))
     316             :           return true;
     317             :   }
     318             :   return Result;
     319             : }
     320             : 
     321             : #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
     322             : LLVM_DUMP_METHOD void LexicalScope::dump(unsigned Indent) const {
     323             :   raw_ostream &err = dbgs();
     324             :   err.indent(Indent);
     325             :   err << "DFSIn: " << DFSIn << " DFSOut: " << DFSOut << "\n";
     326             :   const MDNode *N = Desc;
     327             :   err.indent(Indent);
     328             :   N->dump();
     329             :   if (AbstractScope)
     330             :     err << std::string(Indent, ' ') << "Abstract Scope\n";
     331             : 
     332             :   if (!Children.empty())
     333             :     err << std::string(Indent + 2, ' ') << "Children ...\n";
     334             :   for (unsigned i = 0, e = Children.size(); i != e; ++i)
     335             :     if (Children[i] != this)
     336             :       Children[i]->dump(Indent + 2);
     337             : }
     338             : #endif

Generated by: LCOV version 1.13