LLVM API Documentation
00001 //===- LexicalScopes.cpp - Collecting lexical scope info -*- C++ -*--------===// 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 #ifndef LLVM_CODEGEN_LEXICALSCOPES_H 00018 #define LLVM_CODEGEN_LEXICALSCOPES_H 00019 00020 #include "llvm/ADT/ArrayRef.h" 00021 #include "llvm/ADT/DenseMap.h" 00022 #include "llvm/ADT/SmallPtrSet.h" 00023 #include "llvm/ADT/SmallVector.h" 00024 #include "llvm/ADT/STLExtras.h" 00025 #include "llvm/IR/DebugLoc.h" 00026 #include "llvm/IR/Metadata.h" 00027 #include "llvm/IR/ValueHandle.h" 00028 #include <utility> 00029 #include <unordered_map> 00030 namespace llvm { 00031 00032 class MachineInstr; 00033 class MachineBasicBlock; 00034 class MachineFunction; 00035 00036 //===----------------------------------------------------------------------===// 00037 /// InsnRange - This is used to track range of instructions with identical 00038 /// lexical scope. 00039 /// 00040 typedef std::pair<const MachineInstr *, const MachineInstr *> InsnRange; 00041 00042 //===----------------------------------------------------------------------===// 00043 /// LexicalScope - This class is used to track scope information. 00044 /// 00045 class LexicalScope { 00046 00047 public: 00048 LexicalScope(LexicalScope *P, const MDNode *D, const MDNode *I, bool A) 00049 : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A), 00050 LastInsn(nullptr), FirstInsn(nullptr), DFSIn(0), DFSOut(0) { 00051 if (Parent) 00052 Parent->addChild(this); 00053 } 00054 00055 // Accessors. 00056 LexicalScope *getParent() const { return Parent; } 00057 const MDNode *getDesc() const { return Desc; } 00058 const MDNode *getInlinedAt() const { return InlinedAtLocation; } 00059 const MDNode *getScopeNode() const { return Desc; } 00060 bool isAbstractScope() const { return AbstractScope; } 00061 SmallVectorImpl<LexicalScope *> &getChildren() { return Children; } 00062 SmallVectorImpl<InsnRange> &getRanges() { return Ranges; } 00063 00064 /// addChild - Add a child scope. 00065 void addChild(LexicalScope *S) { Children.push_back(S); } 00066 00067 /// openInsnRange - This scope covers instruction range starting from MI. 00068 void openInsnRange(const MachineInstr *MI) { 00069 if (!FirstInsn) 00070 FirstInsn = MI; 00071 00072 if (Parent) 00073 Parent->openInsnRange(MI); 00074 } 00075 00076 /// extendInsnRange - Extend the current instruction range covered by 00077 /// this scope. 00078 void extendInsnRange(const MachineInstr *MI) { 00079 assert(FirstInsn && "MI Range is not open!"); 00080 LastInsn = MI; 00081 if (Parent) 00082 Parent->extendInsnRange(MI); 00083 } 00084 00085 /// closeInsnRange - Create a range based on FirstInsn and LastInsn collected 00086 /// until now. This is used when a new scope is encountered while walking 00087 /// machine instructions. 00088 void closeInsnRange(LexicalScope *NewScope = nullptr) { 00089 assert(LastInsn && "Last insn missing!"); 00090 Ranges.push_back(InsnRange(FirstInsn, LastInsn)); 00091 FirstInsn = nullptr; 00092 LastInsn = nullptr; 00093 // If Parent dominates NewScope then do not close Parent's instruction 00094 // range. 00095 if (Parent && (!NewScope || !Parent->dominates(NewScope))) 00096 Parent->closeInsnRange(NewScope); 00097 } 00098 00099 /// dominates - Return true if current scope dominates given lexical scope. 00100 bool dominates(const LexicalScope *S) const { 00101 if (S == this) 00102 return true; 00103 if (DFSIn < S->getDFSIn() && DFSOut > S->getDFSOut()) 00104 return true; 00105 return false; 00106 } 00107 00108 // Depth First Search support to walk and manipulate LexicalScope hierarchy. 00109 unsigned getDFSOut() const { return DFSOut; } 00110 void setDFSOut(unsigned O) { DFSOut = O; } 00111 unsigned getDFSIn() const { return DFSIn; } 00112 void setDFSIn(unsigned I) { DFSIn = I; } 00113 00114 /// dump - print lexical scope. 00115 void dump(unsigned Indent = 0) const; 00116 00117 private: 00118 LexicalScope *Parent; // Parent to this scope. 00119 AssertingVH<const MDNode> Desc; // Debug info descriptor. 00120 AssertingVH<const MDNode> InlinedAtLocation; // Location at which this 00121 // scope is inlined. 00122 bool AbstractScope; // Abstract Scope 00123 SmallVector<LexicalScope *, 4> Children; // Scopes defined in scope. 00124 // Contents not owned. 00125 SmallVector<InsnRange, 4> Ranges; 00126 00127 const MachineInstr *LastInsn; // Last instruction of this scope. 00128 const MachineInstr *FirstInsn; // First instruction of this scope. 00129 unsigned DFSIn, DFSOut; // In & Out Depth use to determine 00130 // scope nesting. 00131 }; 00132 00133 //===----------------------------------------------------------------------===// 00134 /// LexicalScopes - This class provides interface to collect and use lexical 00135 /// scoping information from machine instruction. 00136 /// 00137 class LexicalScopes { 00138 public: 00139 LexicalScopes() : MF(nullptr), CurrentFnLexicalScope(nullptr) {} 00140 00141 /// initialize - Scan machine function and constuct lexical scope nest, resets 00142 /// the instance if necessary. 00143 void initialize(const MachineFunction &); 00144 00145 /// releaseMemory - release memory. 00146 void reset(); 00147 00148 /// empty - Return true if there is any lexical scope information available. 00149 bool empty() { return CurrentFnLexicalScope == nullptr; } 00150 00151 /// isCurrentFunctionScope - Return true if given lexical scope represents 00152 /// current function. 00153 bool isCurrentFunctionScope(const LexicalScope *LS) { 00154 return LS == CurrentFnLexicalScope; 00155 } 00156 00157 /// getCurrentFunctionScope - Return lexical scope for the current function. 00158 LexicalScope *getCurrentFunctionScope() const { 00159 return CurrentFnLexicalScope; 00160 } 00161 00162 /// getMachineBasicBlocks - Populate given set using machine basic blocks 00163 /// which have machine instructions that belong to lexical scope identified by 00164 /// DebugLoc. 00165 void getMachineBasicBlocks(DebugLoc DL, 00166 SmallPtrSetImpl<const MachineBasicBlock *> &MBBs); 00167 00168 /// dominates - Return true if DebugLoc's lexical scope dominates at least one 00169 /// machine instruction's lexical scope in a given machine basic block. 00170 bool dominates(DebugLoc DL, MachineBasicBlock *MBB); 00171 00172 /// findLexicalScope - Find lexical scope, either regular or inlined, for the 00173 /// given DebugLoc. Return NULL if not found. 00174 LexicalScope *findLexicalScope(DebugLoc DL); 00175 00176 /// getAbstractScopesList - Return a reference to list of abstract scopes. 00177 ArrayRef<LexicalScope *> getAbstractScopesList() const { 00178 return AbstractScopesList; 00179 } 00180 00181 /// findAbstractScope - Find an abstract scope or return null. 00182 LexicalScope *findAbstractScope(const MDNode *N) { 00183 auto I = AbstractScopeMap.find(N); 00184 return I != AbstractScopeMap.end() ? &I->second : nullptr; 00185 } 00186 00187 /// findInlinedScope - Find an inlined scope for the given DebugLoc or return 00188 /// NULL. 00189 LexicalScope *findInlinedScope(DebugLoc DL); 00190 00191 /// findLexicalScope - Find regular lexical scope or return null. 00192 LexicalScope *findLexicalScope(const MDNode *N) { 00193 auto I = LexicalScopeMap.find(N); 00194 return I != LexicalScopeMap.end() ? &I->second : nullptr; 00195 } 00196 00197 /// dump - Print data structures to dbgs(). 00198 void dump(); 00199 00200 /// getOrCreateAbstractScope - Find or create an abstract lexical scope. 00201 LexicalScope *getOrCreateAbstractScope(const MDNode *N); 00202 00203 private: 00204 /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If 00205 /// not available then create new lexical scope. 00206 LexicalScope *getOrCreateLexicalScope(DebugLoc DL); 00207 00208 /// getOrCreateRegularScope - Find or create a regular lexical scope. 00209 LexicalScope *getOrCreateRegularScope(MDNode *Scope); 00210 00211 /// getOrCreateInlinedScope - Find or create an inlined lexical scope. 00212 LexicalScope *getOrCreateInlinedScope(MDNode *Scope, MDNode *InlinedAt); 00213 00214 /// extractLexicalScopes - Extract instruction ranges for each lexical scopes 00215 /// for the given machine function. 00216 void extractLexicalScopes(SmallVectorImpl<InsnRange> &MIRanges, 00217 DenseMap<const MachineInstr *, LexicalScope *> &M); 00218 void constructScopeNest(LexicalScope *Scope); 00219 void 00220 assignInstructionRanges(SmallVectorImpl<InsnRange> &MIRanges, 00221 DenseMap<const MachineInstr *, LexicalScope *> &M); 00222 00223 private: 00224 const MachineFunction *MF; 00225 00226 /// LexicalScopeMap - Tracks the scopes in the current function. 00227 // Use an unordered_map to ensure value pointer validity over insertion. 00228 std::unordered_map<const MDNode *, LexicalScope> LexicalScopeMap; 00229 00230 /// InlinedLexicalScopeMap - Tracks inlined function scopes in current 00231 /// function. 00232 std::unordered_map<std::pair<const MDNode *, const MDNode *>, LexicalScope, 00233 pair_hash<const MDNode *, const MDNode *>> 00234 InlinedLexicalScopeMap; 00235 00236 /// AbstractScopeMap - These scopes are not included LexicalScopeMap. 00237 // Use an unordered_map to ensure value pointer validity over insertion. 00238 std::unordered_map<const MDNode *, LexicalScope> AbstractScopeMap; 00239 00240 /// AbstractScopesList - Tracks abstract scopes constructed while processing 00241 /// a function. 00242 SmallVector<LexicalScope *, 4> AbstractScopesList; 00243 00244 /// CurrentFnLexicalScope - Top level scope for the current function. 00245 /// 00246 LexicalScope *CurrentFnLexicalScope; 00247 }; 00248 00249 } // end llvm namespace 00250 00251 #endif