LLVM API Documentation
00001 //===- LexicalScopes.cpp - Collecting lexical scope info ------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements LexicalScopes analysis. 00011 // 00012 // This pass collects lexical scope information and maps machine instructions 00013 // to respective lexical scopes. 00014 // 00015 //===----------------------------------------------------------------------===// 00016 00017 #include "llvm/CodeGen/LexicalScopes.h" 00018 #include "llvm/CodeGen/MachineFunction.h" 00019 #include "llvm/CodeGen/MachineInstr.h" 00020 #include "llvm/IR/DebugInfo.h" 00021 #include "llvm/IR/Function.h" 00022 #include "llvm/Support/Debug.h" 00023 #include "llvm/Support/ErrorHandling.h" 00024 #include "llvm/Support/FormattedStream.h" 00025 using namespace llvm; 00026 00027 #define DEBUG_TYPE "lexicalscopes" 00028 00029 /// reset - Reset the instance so that it's prepared for another function. 00030 void LexicalScopes::reset() { 00031 MF = nullptr; 00032 CurrentFnLexicalScope = nullptr; 00033 LexicalScopeMap.clear(); 00034 AbstractScopeMap.clear(); 00035 InlinedLexicalScopeMap.clear(); 00036 AbstractScopesList.clear(); 00037 } 00038 00039 /// initialize - Scan machine function and constuct lexical scope nest. 00040 void LexicalScopes::initialize(const MachineFunction &Fn) { 00041 reset(); 00042 MF = &Fn; 00043 SmallVector<InsnRange, 4> MIRanges; 00044 DenseMap<const MachineInstr *, LexicalScope *> MI2ScopeMap; 00045 extractLexicalScopes(MIRanges, MI2ScopeMap); 00046 if (CurrentFnLexicalScope) { 00047 constructScopeNest(CurrentFnLexicalScope); 00048 assignInstructionRanges(MIRanges, MI2ScopeMap); 00049 } 00050 } 00051 00052 /// extractLexicalScopes - Extract instruction ranges for each lexical scopes 00053 /// for the given machine function. 00054 void LexicalScopes::extractLexicalScopes( 00055 SmallVectorImpl<InsnRange> &MIRanges, 00056 DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) { 00057 00058 // Scan each instruction and create scopes. First build working set of scopes. 00059 for (const auto &MBB : *MF) { 00060 const MachineInstr *RangeBeginMI = nullptr; 00061 const MachineInstr *PrevMI = nullptr; 00062 DebugLoc PrevDL; 00063 for (const auto &MInsn : MBB) { 00064 // Check if instruction has valid location information. 00065 const DebugLoc MIDL = MInsn.getDebugLoc(); 00066 if (MIDL.isUnknown()) { 00067 PrevMI = &MInsn; 00068 continue; 00069 } 00070 00071 // If scope has not changed then skip this instruction. 00072 if (MIDL == PrevDL) { 00073 PrevMI = &MInsn; 00074 continue; 00075 } 00076 00077 // Ignore DBG_VALUE. It does not contribute to any instruction in output. 00078 if (MInsn.isDebugValue()) 00079 continue; 00080 00081 if (RangeBeginMI) { 00082 // If we have already seen a beginning of an instruction range and 00083 // current instruction scope does not match scope of first instruction 00084 // in this range then create a new instruction range. 00085 InsnRange R(RangeBeginMI, PrevMI); 00086 MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL); 00087 MIRanges.push_back(R); 00088 } 00089 00090 // This is a beginning of a new instruction range. 00091 RangeBeginMI = &MInsn; 00092 00093 // Reset previous markers. 00094 PrevMI = &MInsn; 00095 PrevDL = MIDL; 00096 } 00097 00098 // Create last instruction range. 00099 if (RangeBeginMI && PrevMI && !PrevDL.isUnknown()) { 00100 InsnRange R(RangeBeginMI, PrevMI); 00101 MIRanges.push_back(R); 00102 MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL); 00103 } 00104 } 00105 } 00106 00107 LexicalScope *LexicalScopes::findInlinedScope(DebugLoc DL) { 00108 MDNode *Scope = nullptr; 00109 MDNode *IA = nullptr; 00110 DL.getScopeAndInlinedAt(Scope, IA, MF->getFunction()->getContext()); 00111 auto I = InlinedLexicalScopeMap.find(std::make_pair(Scope, IA)); 00112 return I != InlinedLexicalScopeMap.end() ? &I->second : nullptr; 00113 } 00114 00115 /// findLexicalScope - Find lexical scope, either regular or inlined, for the 00116 /// given DebugLoc. Return NULL if not found. 00117 LexicalScope *LexicalScopes::findLexicalScope(DebugLoc DL) { 00118 MDNode *Scope = nullptr; 00119 MDNode *IA = nullptr; 00120 DL.getScopeAndInlinedAt(Scope, IA, MF->getFunction()->getContext()); 00121 if (!Scope) 00122 return nullptr; 00123 00124 // The scope that we were created with could have an extra file - which 00125 // isn't what we care about in this case. 00126 DIDescriptor D = DIDescriptor(Scope); 00127 if (D.isLexicalBlockFile()) 00128 Scope = DILexicalBlockFile(Scope).getScope(); 00129 00130 if (IA) { 00131 auto I = InlinedLexicalScopeMap.find(std::make_pair(Scope, IA)); 00132 return I != InlinedLexicalScopeMap.end() ? &I->second : nullptr; 00133 } 00134 return findLexicalScope(Scope); 00135 } 00136 00137 /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If 00138 /// not available then create new lexical scope. 00139 LexicalScope *LexicalScopes::getOrCreateLexicalScope(DebugLoc DL) { 00140 MDNode *Scope = nullptr; 00141 MDNode *InlinedAt = nullptr; 00142 DL.getScopeAndInlinedAt(Scope, InlinedAt, MF->getFunction()->getContext()); 00143 00144 if (InlinedAt) { 00145 // Create an abstract scope for inlined function. 00146 getOrCreateAbstractScope(Scope); 00147 // Create an inlined scope for inlined function. 00148 return getOrCreateInlinedScope(Scope, InlinedAt); 00149 } 00150 00151 return getOrCreateRegularScope(Scope); 00152 } 00153 00154 /// getOrCreateRegularScope - Find or create a regular lexical scope. 00155 LexicalScope *LexicalScopes::getOrCreateRegularScope(MDNode *Scope) { 00156 DIDescriptor D = DIDescriptor(Scope); 00157 if (D.isLexicalBlockFile()) { 00158 Scope = DILexicalBlockFile(Scope).getScope(); 00159 D = DIDescriptor(Scope); 00160 } 00161 00162 auto I = LexicalScopeMap.find(Scope); 00163 if (I != LexicalScopeMap.end()) 00164 return &I->second; 00165 00166 LexicalScope *Parent = nullptr; 00167 if (D.isLexicalBlock()) 00168 Parent = getOrCreateLexicalScope(DebugLoc::getFromDILexicalBlock(Scope)); 00169 // FIXME: Use forward_as_tuple instead of make_tuple, once MSVC2012 00170 // compatibility is no longer required. 00171 I = LexicalScopeMap.emplace(std::piecewise_construct, std::make_tuple(Scope), 00172 std::make_tuple(Parent, DIDescriptor(Scope), 00173 nullptr, false)).first; 00174 00175 if (!Parent && DIDescriptor(Scope).isSubprogram() && 00176 DISubprogram(Scope).describes(MF->getFunction())) 00177 CurrentFnLexicalScope = &I->second; 00178 00179 return &I->second; 00180 } 00181 00182 /// getOrCreateInlinedScope - Find or create an inlined lexical scope. 00183 LexicalScope *LexicalScopes::getOrCreateInlinedScope(MDNode *ScopeNode, 00184 MDNode *InlinedAt) { 00185 std::pair<const MDNode*, const MDNode*> P(ScopeNode, InlinedAt); 00186 auto I = InlinedLexicalScopeMap.find(P); 00187 if (I != InlinedLexicalScopeMap.end()) 00188 return &I->second; 00189 00190 LexicalScope *Parent; 00191 DILexicalBlock Scope(ScopeNode); 00192 if (Scope.isSubprogram()) 00193 Parent = getOrCreateLexicalScope(DebugLoc::getFromDILocation(InlinedAt)); 00194 else 00195 Parent = getOrCreateInlinedScope(Scope.getContext(), InlinedAt); 00196 00197 // FIXME: Use forward_as_tuple instead of make_tuple, once MSVC2012 00198 // compatibility is no longer required. 00199 I = InlinedLexicalScopeMap.emplace(std::piecewise_construct, 00200 std::make_tuple(P), 00201 std::make_tuple(Parent, Scope, InlinedAt, 00202 false)).first; 00203 return &I->second; 00204 } 00205 00206 /// getOrCreateAbstractScope - Find or create an abstract lexical scope. 00207 LexicalScope *LexicalScopes::getOrCreateAbstractScope(const MDNode *N) { 00208 assert(N && "Invalid Scope encoding!"); 00209 00210 DIDescriptor Scope(N); 00211 if (Scope.isLexicalBlockFile()) 00212 Scope = DILexicalBlockFile(Scope).getScope(); 00213 auto I = AbstractScopeMap.find(Scope); 00214 if (I != AbstractScopeMap.end()) 00215 return &I->second; 00216 00217 LexicalScope *Parent = nullptr; 00218 if (Scope.isLexicalBlock()) { 00219 DILexicalBlock DB(Scope); 00220 DIDescriptor ParentDesc = DB.getContext(); 00221 Parent = getOrCreateAbstractScope(ParentDesc); 00222 } 00223 I = AbstractScopeMap.emplace(std::piecewise_construct, 00224 std::forward_as_tuple(Scope), 00225 std::forward_as_tuple(Parent, Scope, 00226 nullptr, true)).first; 00227 if (Scope.isSubprogram()) 00228 AbstractScopesList.push_back(&I->second); 00229 return &I->second; 00230 } 00231 00232 /// constructScopeNest 00233 void LexicalScopes::constructScopeNest(LexicalScope *Scope) { 00234 assert(Scope && "Unable to calculate scope dominance graph!"); 00235 SmallVector<LexicalScope *, 4> WorkStack; 00236 WorkStack.push_back(Scope); 00237 unsigned Counter = 0; 00238 while (!WorkStack.empty()) { 00239 LexicalScope *WS = WorkStack.back(); 00240 const SmallVectorImpl<LexicalScope *> &Children = WS->getChildren(); 00241 bool visitedChildren = false; 00242 for (SmallVectorImpl<LexicalScope *>::const_iterator SI = Children.begin(), 00243 SE = Children.end(); 00244 SI != SE; ++SI) { 00245 LexicalScope *ChildScope = *SI; 00246 if (!ChildScope->getDFSOut()) { 00247 WorkStack.push_back(ChildScope); 00248 visitedChildren = true; 00249 ChildScope->setDFSIn(++Counter); 00250 break; 00251 } 00252 } 00253 if (!visitedChildren) { 00254 WorkStack.pop_back(); 00255 WS->setDFSOut(++Counter); 00256 } 00257 } 00258 } 00259 00260 /// assignInstructionRanges - Find ranges of instructions covered by each 00261 /// lexical scope. 00262 void LexicalScopes::assignInstructionRanges( 00263 SmallVectorImpl<InsnRange> &MIRanges, 00264 DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) { 00265 00266 LexicalScope *PrevLexicalScope = nullptr; 00267 for (SmallVectorImpl<InsnRange>::const_iterator RI = MIRanges.begin(), 00268 RE = MIRanges.end(); 00269 RI != RE; ++RI) { 00270 const InsnRange &R = *RI; 00271 LexicalScope *S = MI2ScopeMap.lookup(R.first); 00272 assert(S && "Lost LexicalScope for a machine instruction!"); 00273 if (PrevLexicalScope && !PrevLexicalScope->dominates(S)) 00274 PrevLexicalScope->closeInsnRange(S); 00275 S->openInsnRange(R.first); 00276 S->extendInsnRange(R.second); 00277 PrevLexicalScope = S; 00278 } 00279 00280 if (PrevLexicalScope) 00281 PrevLexicalScope->closeInsnRange(); 00282 } 00283 00284 /// getMachineBasicBlocks - Populate given set using machine basic blocks which 00285 /// have machine instructions that belong to lexical scope identified by 00286 /// DebugLoc. 00287 void LexicalScopes::getMachineBasicBlocks( 00288 DebugLoc DL, SmallPtrSetImpl<const MachineBasicBlock *> &MBBs) { 00289 MBBs.clear(); 00290 LexicalScope *Scope = getOrCreateLexicalScope(DL); 00291 if (!Scope) 00292 return; 00293 00294 if (Scope == CurrentFnLexicalScope) { 00295 for (const auto &MBB : *MF) 00296 MBBs.insert(&MBB); 00297 return; 00298 } 00299 00300 SmallVectorImpl<InsnRange> &InsnRanges = Scope->getRanges(); 00301 for (SmallVectorImpl<InsnRange>::iterator I = InsnRanges.begin(), 00302 E = InsnRanges.end(); 00303 I != E; ++I) { 00304 InsnRange &R = *I; 00305 MBBs.insert(R.first->getParent()); 00306 } 00307 } 00308 00309 /// dominates - Return true if DebugLoc's lexical scope dominates at least one 00310 /// machine instruction's lexical scope in a given machine basic block. 00311 bool LexicalScopes::dominates(DebugLoc DL, MachineBasicBlock *MBB) { 00312 LexicalScope *Scope = getOrCreateLexicalScope(DL); 00313 if (!Scope) 00314 return false; 00315 00316 // Current function scope covers all basic blocks in the function. 00317 if (Scope == CurrentFnLexicalScope && MBB->getParent() == MF) 00318 return true; 00319 00320 bool Result = false; 00321 for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); I != E; 00322 ++I) { 00323 DebugLoc IDL = I->getDebugLoc(); 00324 if (IDL.isUnknown()) 00325 continue; 00326 if (LexicalScope *IScope = getOrCreateLexicalScope(IDL)) 00327 if (Scope->dominates(IScope)) 00328 return true; 00329 } 00330 return Result; 00331 } 00332 00333 /// dump - Print data structures. 00334 void LexicalScope::dump(unsigned Indent) const { 00335 #ifndef NDEBUG 00336 raw_ostream &err = dbgs(); 00337 err.indent(Indent); 00338 err << "DFSIn: " << DFSIn << " DFSOut: " << DFSOut << "\n"; 00339 const MDNode *N = Desc; 00340 err.indent(Indent); 00341 N->dump(); 00342 if (AbstractScope) 00343 err << std::string(Indent, ' ') << "Abstract Scope\n"; 00344 00345 if (!Children.empty()) 00346 err << std::string(Indent + 2, ' ') << "Children ...\n"; 00347 for (unsigned i = 0, e = Children.size(); i != e; ++i) 00348 if (Children[i] != this) 00349 Children[i]->dump(Indent + 2); 00350 #endif 00351 }