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