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 176bda14b3SChandler Carruth #include "llvm/CodeGen/LexicalScopes.h" 185db84df7SEugene Zelenko #include "llvm/ADT/DenseMap.h" 195db84df7SEugene Zelenko #include "llvm/ADT/SmallVector.h" 205db84df7SEugene Zelenko #include "llvm/CodeGen/MachineBasicBlock.h" 21e1649c31SDevang Patel #include "llvm/CodeGen/MachineFunction.h" 22e1649c31SDevang Patel #include "llvm/CodeGen/MachineInstr.h" 235db84df7SEugene Zelenko #include "llvm/IR/DebugInfoMetadata.h" 245db84df7SEugene Zelenko #include "llvm/IR/Metadata.h" 255db84df7SEugene Zelenko #include "llvm/Support/Casting.h" 265db84df7SEugene Zelenko #include "llvm/Support/Compiler.h" 27e1649c31SDevang Patel #include "llvm/Support/Debug.h" 285db84df7SEugene Zelenko #include "llvm/Support/raw_ostream.h" 295db84df7SEugene Zelenko #include <cassert> 305db84df7SEugene Zelenko #include <string> 315db84df7SEugene Zelenko #include <tuple> 325db84df7SEugene Zelenko #include <utility> 335db84df7SEugene Zelenko 34e1649c31SDevang Patel using namespace llvm; 35e1649c31SDevang Patel 361b9dde08SChandler Carruth #define DEBUG_TYPE "lexicalscopes" 371b9dde08SChandler Carruth 38b7dee8a6SEric Christopher /// reset - Reset the instance so that it's prepared for another function. 39b7dee8a6SEric Christopher void LexicalScopes::reset() { 40c0196b1bSCraig Topper MF = nullptr; 41c0196b1bSCraig Topper CurrentFnLexicalScope = nullptr; 422f143e0cSDavid Blaikie LexicalScopeMap.clear(); 432f143e0cSDavid Blaikie AbstractScopeMap.clear(); 44e1649c31SDevang Patel InlinedLexicalScopeMap.clear(); 45e1649c31SDevang Patel AbstractScopesList.clear(); 46e1649c31SDevang Patel } 47e1649c31SDevang Patel 48e1649c31SDevang Patel /// initialize - Scan machine function and constuct lexical scope nest. 49e1649c31SDevang Patel void LexicalScopes::initialize(const MachineFunction &Fn) { 50*e018bbd8SWolfgang Pieb reset(); 5176b5b749STeresa Johnson // Don't attempt any lexical scope creation for a NoDebug compile unit. 5276b5b749STeresa Johnson if (Fn.getFunction()->getSubprogram()->getUnit()->getEmissionKind() == 5376b5b749STeresa Johnson DICompileUnit::NoDebug) 5476b5b749STeresa Johnson return; 55e1649c31SDevang Patel MF = &Fn; 56e1649c31SDevang Patel SmallVector<InsnRange, 4> MIRanges; 57e1649c31SDevang Patel DenseMap<const MachineInstr *, LexicalScope *> MI2ScopeMap; 58e1649c31SDevang Patel extractLexicalScopes(MIRanges, MI2ScopeMap); 59e1649c31SDevang Patel if (CurrentFnLexicalScope) { 60e1649c31SDevang Patel constructScopeNest(CurrentFnLexicalScope); 61e1649c31SDevang Patel assignInstructionRanges(MIRanges, MI2ScopeMap); 62e1649c31SDevang Patel } 63e1649c31SDevang Patel } 64e1649c31SDevang Patel 65e1649c31SDevang Patel /// extractLexicalScopes - Extract instruction ranges for each lexical scopes 66e1649c31SDevang Patel /// for the given machine function. 676211e4b9SEric Christopher void LexicalScopes::extractLexicalScopes( 686211e4b9SEric Christopher SmallVectorImpl<InsnRange> &MIRanges, 69e1649c31SDevang Patel DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) { 70e1649c31SDevang Patel // Scan each instruction and create scopes. First build working set of scopes. 7141b977dfSAlexey Samsonov for (const auto &MBB : *MF) { 72c0196b1bSCraig Topper const MachineInstr *RangeBeginMI = nullptr; 73c0196b1bSCraig Topper const MachineInstr *PrevMI = nullptr; 74a9308c49SDuncan P. N. Exon Smith const DILocation *PrevDL = nullptr; 75f74bde67SAlexey Samsonov for (const auto &MInsn : MBB) { 76e1649c31SDevang Patel // Check if instruction has valid location information. 77a9308c49SDuncan P. N. Exon Smith const DILocation *MIDL = MInsn.getDebugLoc(); 789dffcd04SDuncan P. N. Exon Smith if (!MIDL) { 79f74bde67SAlexey Samsonov PrevMI = &MInsn; 80e1649c31SDevang Patel continue; 81e1649c31SDevang Patel } 82e1649c31SDevang Patel 83e1649c31SDevang Patel // If scope has not changed then skip this instruction. 84e1649c31SDevang Patel if (MIDL == PrevDL) { 85f74bde67SAlexey Samsonov PrevMI = &MInsn; 86e1649c31SDevang Patel continue; 87e1649c31SDevang Patel } 88e1649c31SDevang Patel 89fb31da13SAdrian Prantl // Ignore DBG_VALUE and similar instruction that do not contribute to any 90fb31da13SAdrian Prantl // instruction in the output. 91fb31da13SAdrian Prantl if (MInsn.isMetaInstruction()) 92e1649c31SDevang Patel continue; 93e1649c31SDevang Patel 94e1649c31SDevang Patel if (RangeBeginMI) { 95e1649c31SDevang Patel // If we have already seen a beginning of an instruction range and 96e1649c31SDevang Patel // current instruction scope does not match scope of first instruction 97e1649c31SDevang Patel // in this range then create a new instruction range. 98e1649c31SDevang Patel InsnRange R(RangeBeginMI, PrevMI); 99e1649c31SDevang Patel MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL); 100e1649c31SDevang Patel MIRanges.push_back(R); 101e1649c31SDevang Patel } 102e1649c31SDevang Patel 103e1649c31SDevang Patel // This is a beginning of a new instruction range. 104f74bde67SAlexey Samsonov RangeBeginMI = &MInsn; 105e1649c31SDevang Patel 106e1649c31SDevang Patel // Reset previous markers. 107f74bde67SAlexey Samsonov PrevMI = &MInsn; 108e1649c31SDevang Patel PrevDL = MIDL; 109e1649c31SDevang Patel } 110e1649c31SDevang Patel 111e1649c31SDevang Patel // Create last instruction range. 1129dffcd04SDuncan P. N. Exon Smith if (RangeBeginMI && PrevMI && PrevDL) { 113e1649c31SDevang Patel InsnRange R(RangeBeginMI, PrevMI); 114e1649c31SDevang Patel MIRanges.push_back(R); 115e1649c31SDevang Patel MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL); 116e1649c31SDevang Patel } 117e1649c31SDevang Patel } 118e1649c31SDevang Patel } 119e1649c31SDevang Patel 120e1649c31SDevang Patel /// findLexicalScope - Find lexical scope, either regular or inlined, for the 121e1649c31SDevang Patel /// given DebugLoc. Return NULL if not found. 122a9308c49SDuncan P. N. Exon Smith LexicalScope *LexicalScopes::findLexicalScope(const DILocation *DL) { 123a9308c49SDuncan P. N. Exon Smith DILocalScope *Scope = DL->getScope(); 1246211e4b9SEric Christopher if (!Scope) 125c0196b1bSCraig Topper return nullptr; 1266647b830SEric Christopher 1276647b830SEric Christopher // The scope that we were created with could have an extra file - which 1286647b830SEric Christopher // isn't what we care about in this case. 129a5ba9914SAmjad Aboud Scope = Scope->getNonLexicalBlockFileScope(); 1306647b830SEric Christopher 1315a227fffSDuncan P. N. Exon Smith if (auto *IA = DL->getInlinedAt()) { 1329b8c8cdaSDavid Blaikie auto I = InlinedLexicalScopeMap.find(std::make_pair(Scope, IA)); 1339b8c8cdaSDavid Blaikie return I != InlinedLexicalScopeMap.end() ? &I->second : nullptr; 1349b8c8cdaSDavid Blaikie } 1352f143e0cSDavid Blaikie return findLexicalScope(Scope); 136e1649c31SDevang Patel } 137e1649c31SDevang Patel 138e1649c31SDevang Patel /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If 139e1649c31SDevang Patel /// not available then create new lexical scope. 140a9308c49SDuncan P. N. Exon Smith LexicalScope *LexicalScopes::getOrCreateLexicalScope(const DILocalScope *Scope, 141a9308c49SDuncan P. N. Exon Smith const DILocation *IA) { 14282eba746SDuncan P. N. Exon Smith if (IA) { 14376b5b749STeresa Johnson // Skip scopes inlined from a NoDebug compile unit. 14476b5b749STeresa Johnson if (Scope->getSubprogram()->getUnit()->getEmissionKind() == 14576b5b749STeresa Johnson DICompileUnit::NoDebug) 14676b5b749STeresa Johnson return getOrCreateLexicalScope(IA); 147e1649c31SDevang Patel // Create an abstract scope for inlined function. 148e1649c31SDevang Patel getOrCreateAbstractScope(Scope); 149e1649c31SDevang Patel // Create an inlined scope for inlined function. 15082eba746SDuncan P. N. Exon Smith return getOrCreateInlinedScope(Scope, IA); 151e1649c31SDevang Patel } 152e1649c31SDevang Patel 153e1649c31SDevang Patel return getOrCreateRegularScope(Scope); 154e1649c31SDevang Patel } 155e1649c31SDevang Patel 156e1649c31SDevang Patel /// getOrCreateRegularScope - Find or create a regular lexical scope. 15733af7a8fSDuncan P. N. Exon Smith LexicalScope * 158a9308c49SDuncan P. N. Exon Smith LexicalScopes::getOrCreateRegularScope(const DILocalScope *Scope) { 159a5ba9914SAmjad Aboud assert(Scope && "Invalid Scope encoding!"); 160a5ba9914SAmjad Aboud Scope = Scope->getNonLexicalBlockFileScope(); 1616647b830SEric Christopher 1622f143e0cSDavid Blaikie auto I = LexicalScopeMap.find(Scope); 1632f143e0cSDavid Blaikie if (I != LexicalScopeMap.end()) 1642f143e0cSDavid Blaikie return &I->second; 165e1649c31SDevang Patel 166a9308c49SDuncan P. N. Exon Smith // FIXME: Should the following dyn_cast be DILexicalBlock? 167c0196b1bSCraig Topper LexicalScope *Parent = nullptr; 168a9308c49SDuncan P. N. Exon Smith if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope)) 16982eba746SDuncan P. N. Exon Smith Parent = getOrCreateLexicalScope(Block->getScope()); 170f17583eeSAaron Ballman I = LexicalScopeMap.emplace(std::piecewise_construct, 171f17583eeSAaron Ballman std::forward_as_tuple(Scope), 17233af7a8fSDuncan P. N. Exon Smith std::forward_as_tuple(Parent, Scope, nullptr, 17333af7a8fSDuncan P. N. Exon Smith false)).first; 1742f143e0cSDavid Blaikie 1753dfe4788SDavid Blaikie if (!Parent) { 176a9308c49SDuncan P. N. Exon Smith assert(cast<DISubprogram>(Scope)->describes(MF->getFunction())); 1773dfe4788SDavid Blaikie assert(!CurrentFnLexicalScope); 1782f143e0cSDavid Blaikie CurrentFnLexicalScope = &I->second; 1793dfe4788SDavid Blaikie } 180e1649c31SDevang Patel 1812f143e0cSDavid Blaikie return &I->second; 182e1649c31SDevang Patel } 183e1649c31SDevang Patel 184e1649c31SDevang Patel /// getOrCreateInlinedScope - Find or create an inlined lexical scope. 18533af7a8fSDuncan P. N. Exon Smith LexicalScope * 186a9308c49SDuncan P. N. Exon Smith LexicalScopes::getOrCreateInlinedScope(const DILocalScope *Scope, 187a9308c49SDuncan P. N. Exon Smith const DILocation *InlinedAt) { 188a5ba9914SAmjad Aboud assert(Scope && "Invalid Scope encoding!"); 189a5ba9914SAmjad Aboud Scope = Scope->getNonLexicalBlockFileScope(); 190a9308c49SDuncan P. N. Exon Smith std::pair<const DILocalScope *, const DILocation *> P(Scope, InlinedAt); 1919b8c8cdaSDavid Blaikie auto I = InlinedLexicalScopeMap.find(P); 1929b8c8cdaSDavid Blaikie if (I != InlinedLexicalScopeMap.end()) 1932f143e0cSDavid Blaikie return &I->second; 194e1649c31SDevang Patel 1959b8c8cdaSDavid Blaikie LexicalScope *Parent; 196a9308c49SDuncan P. N. Exon Smith if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope)) 19733af7a8fSDuncan P. N. Exon Smith Parent = getOrCreateInlinedScope(Block->getScope(), InlinedAt); 1989b8c8cdaSDavid Blaikie else 19933af7a8fSDuncan P. N. Exon Smith Parent = getOrCreateLexicalScope(InlinedAt); 2009b8c8cdaSDavid Blaikie 20114303d18SEric Christopher I = InlinedLexicalScopeMap 20214303d18SEric Christopher .emplace(std::piecewise_construct, std::forward_as_tuple(P), 20314303d18SEric Christopher std::forward_as_tuple(Parent, Scope, InlinedAt, false)) 204f17583eeSAaron Ballman .first; 2052f143e0cSDavid Blaikie return &I->second; 206e1649c31SDevang Patel } 207e1649c31SDevang Patel 208e1649c31SDevang Patel /// getOrCreateAbstractScope - Find or create an abstract lexical scope. 20933af7a8fSDuncan P. N. Exon Smith LexicalScope * 210a9308c49SDuncan P. N. Exon Smith LexicalScopes::getOrCreateAbstractScope(const DILocalScope *Scope) { 21133af7a8fSDuncan P. N. Exon Smith assert(Scope && "Invalid Scope encoding!"); 212a5ba9914SAmjad Aboud Scope = Scope->getNonLexicalBlockFileScope(); 213ea862267SDavid Blaikie auto I = AbstractScopeMap.find(Scope); 2142f143e0cSDavid Blaikie if (I != AbstractScopeMap.end()) 2152f143e0cSDavid Blaikie return &I->second; 216e1649c31SDevang Patel 217a9308c49SDuncan P. N. Exon Smith // FIXME: Should the following isa be DILexicalBlock? 218c0196b1bSCraig Topper LexicalScope *Parent = nullptr; 219a9308c49SDuncan P. N. Exon Smith if (auto *Block = dyn_cast<DILexicalBlockBase>(Scope)) 22033af7a8fSDuncan P. N. Exon Smith Parent = getOrCreateAbstractScope(Block->getScope()); 22133af7a8fSDuncan P. N. Exon Smith 2222f143e0cSDavid Blaikie I = AbstractScopeMap.emplace(std::piecewise_construct, 223ea862267SDavid Blaikie std::forward_as_tuple(Scope), 224ea862267SDavid Blaikie std::forward_as_tuple(Parent, Scope, 2252f143e0cSDavid Blaikie nullptr, true)).first; 226a9308c49SDuncan P. N. Exon Smith if (isa<DISubprogram>(Scope)) 2272f143e0cSDavid Blaikie AbstractScopesList.push_back(&I->second); 2282f143e0cSDavid Blaikie return &I->second; 229e1649c31SDevang Patel } 230e1649c31SDevang Patel 231e1649c31SDevang Patel /// constructScopeNest 232e1649c31SDevang Patel void LexicalScopes::constructScopeNest(LexicalScope *Scope) { 233e1649c31SDevang Patel assert(Scope && "Unable to calculate scope dominance graph!"); 234e1649c31SDevang Patel SmallVector<LexicalScope *, 4> WorkStack; 235e1649c31SDevang Patel WorkStack.push_back(Scope); 236e1649c31SDevang Patel unsigned Counter = 0; 237e1649c31SDevang Patel while (!WorkStack.empty()) { 238e1649c31SDevang Patel LexicalScope *WS = WorkStack.back(); 23980170e54SCraig Topper const SmallVectorImpl<LexicalScope *> &Children = WS->getChildren(); 240e1649c31SDevang Patel bool visitedChildren = false; 24116b2ace0SAdrian Prantl for (auto &ChildScope : Children) 242e1649c31SDevang Patel if (!ChildScope->getDFSOut()) { 243e1649c31SDevang Patel WorkStack.push_back(ChildScope); 244e1649c31SDevang Patel visitedChildren = true; 245e1649c31SDevang Patel ChildScope->setDFSIn(++Counter); 246e1649c31SDevang Patel break; 247e1649c31SDevang Patel } 248e1649c31SDevang Patel if (!visitedChildren) { 249e1649c31SDevang Patel WorkStack.pop_back(); 250e1649c31SDevang Patel WS->setDFSOut(++Counter); 251e1649c31SDevang Patel } 252e1649c31SDevang Patel } 253e1649c31SDevang Patel } 254e1649c31SDevang Patel 255784077ebSDevang Patel /// assignInstructionRanges - Find ranges of instructions covered by each 256784077ebSDevang Patel /// lexical scope. 2576211e4b9SEric Christopher void LexicalScopes::assignInstructionRanges( 2586211e4b9SEric Christopher SmallVectorImpl<InsnRange> &MIRanges, 2596211e4b9SEric Christopher DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) { 260c0196b1bSCraig Topper LexicalScope *PrevLexicalScope = nullptr; 26116b2ace0SAdrian Prantl for (const auto &R : MIRanges) { 262e1649c31SDevang Patel LexicalScope *S = MI2ScopeMap.lookup(R.first); 263e1649c31SDevang Patel assert(S && "Lost LexicalScope for a machine instruction!"); 264e1649c31SDevang Patel if (PrevLexicalScope && !PrevLexicalScope->dominates(S)) 265e1649c31SDevang Patel PrevLexicalScope->closeInsnRange(S); 266e1649c31SDevang Patel S->openInsnRange(R.first); 267e1649c31SDevang Patel S->extendInsnRange(R.second); 268e1649c31SDevang Patel PrevLexicalScope = S; 269e1649c31SDevang Patel } 270e1649c31SDevang Patel 271e1649c31SDevang Patel if (PrevLexicalScope) 272e1649c31SDevang Patel PrevLexicalScope->closeInsnRange(); 273e1649c31SDevang Patel } 274e1649c31SDevang Patel 275e1649c31SDevang Patel /// getMachineBasicBlocks - Populate given set using machine basic blocks which 276e1649c31SDevang Patel /// have machine instructions that belong to lexical scope identified by 277e1649c31SDevang Patel /// DebugLoc. 2786211e4b9SEric Christopher void LexicalScopes::getMachineBasicBlocks( 279a9308c49SDuncan P. N. Exon Smith const DILocation *DL, SmallPtrSetImpl<const MachineBasicBlock *> &MBBs) { 280*e018bbd8SWolfgang Pieb assert(MF && "Method called on a uninitialized LexicalScopes object!"); 281e1649c31SDevang Patel MBBs.clear(); 282*e018bbd8SWolfgang Pieb 283e1649c31SDevang Patel LexicalScope *Scope = getOrCreateLexicalScope(DL); 284e1649c31SDevang Patel if (!Scope) 285e1649c31SDevang Patel return; 286e1649c31SDevang Patel 287db4374a2SDevang Patel if (Scope == CurrentFnLexicalScope) { 28841b977dfSAlexey Samsonov for (const auto &MBB : *MF) 28941b977dfSAlexey Samsonov MBBs.insert(&MBB); 290db4374a2SDevang Patel return; 291db4374a2SDevang Patel } 292db4374a2SDevang Patel 29380170e54SCraig Topper SmallVectorImpl<InsnRange> &InsnRanges = Scope->getRanges(); 29416b2ace0SAdrian Prantl for (auto &R : InsnRanges) 295e1649c31SDevang Patel MBBs.insert(R.first->getParent()); 296e1649c31SDevang Patel } 297e1649c31SDevang Patel 298e1649c31SDevang Patel /// dominates - Return true if DebugLoc's lexical scope dominates at least one 299e1649c31SDevang Patel /// machine instruction's lexical scope in a given machine basic block. 300a9308c49SDuncan P. N. Exon Smith bool LexicalScopes::dominates(const DILocation *DL, MachineBasicBlock *MBB) { 301*e018bbd8SWolfgang Pieb assert(MF && "Unexpected uninitialized LexicalScopes object!"); 302e1649c31SDevang Patel LexicalScope *Scope = getOrCreateLexicalScope(DL); 303e1649c31SDevang Patel if (!Scope) 304e1649c31SDevang Patel return false; 305db4374a2SDevang Patel 306db4374a2SDevang Patel // Current function scope covers all basic blocks in the function. 307db4374a2SDevang Patel if (Scope == CurrentFnLexicalScope && MBB->getParent() == MF) 308db4374a2SDevang Patel return true; 309db4374a2SDevang Patel 310e1649c31SDevang Patel bool Result = false; 31116b2ace0SAdrian Prantl for (auto &I : *MBB) { 31216b2ace0SAdrian Prantl if (const DILocation *IDL = I.getDebugLoc()) 313e1649c31SDevang Patel if (LexicalScope *IScope = getOrCreateLexicalScope(IDL)) 314e1649c31SDevang Patel if (Scope->dominates(IScope)) 315e1649c31SDevang Patel return true; 316e1649c31SDevang Patel } 317e1649c31SDevang Patel return Result; 318e1649c31SDevang Patel } 319e1649c31SDevang Patel 3208c209aa8SMatthias Braun #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 3218c209aa8SMatthias Braun LLVM_DUMP_METHOD void LexicalScope::dump(unsigned Indent) const { 322e1649c31SDevang Patel raw_ostream &err = dbgs(); 323e498b25bSManman Ren err.indent(Indent); 324e1649c31SDevang Patel err << "DFSIn: " << DFSIn << " DFSOut: " << DFSOut << "\n"; 325e1649c31SDevang Patel const MDNode *N = Desc; 326e498b25bSManman Ren err.indent(Indent); 327e1649c31SDevang Patel N->dump(); 328e1649c31SDevang Patel if (AbstractScope) 329e498b25bSManman Ren err << std::string(Indent, ' ') << "Abstract Scope\n"; 330e1649c31SDevang Patel 331e1649c31SDevang Patel if (!Children.empty()) 332e498b25bSManman Ren err << std::string(Indent + 2, ' ') << "Children ...\n"; 333e1649c31SDevang Patel for (unsigned i = 0, e = Children.size(); i != e; ++i) 334e1649c31SDevang Patel if (Children[i] != this) 335e498b25bSManman Ren Children[i]->dump(Indent + 2); 336e1649c31SDevang Patel } 3378c209aa8SMatthias Braun #endif 338