X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FCodeGen%2FLexicalScopes.h;h=7d7e48af2a0ff3bf5e17f357c465abbd9b936f6a;hb=3bd93089a9b944e40edb913871c2a67972ed0af7;hp=709681b982173b4ce86bca9a3043b6f33594a477;hpb=cd9f6c53de95f5301c0152cab2ccc78d653d6270;p=oota-llvm.git diff --git a/include/llvm/CodeGen/LexicalScopes.h b/include/llvm/CodeGen/LexicalScopes.h index 709681b9821..7d7e48af2a0 100644 --- a/include/llvm/CodeGen/LexicalScopes.h +++ b/include/llvm/CodeGen/LexicalScopes.h @@ -17,20 +17,21 @@ #ifndef LLVM_CODEGEN_LEXICALSCOPES_H #define LLVM_CODEGEN_LEXICALSCOPES_H -#include "llvm/Metadata.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/Support/DebugLoc.h" -#include "llvm/Support/ValueHandle.h" +#include "llvm/IR/DebugLoc.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/ValueHandle.h" +#include #include namespace llvm { class MachineInstr; class MachineBasicBlock; class MachineFunction; -class LexicalScope; //===----------------------------------------------------------------------===// /// InsnRange - This is used to track range of instructions with identical @@ -38,211 +39,219 @@ class LexicalScope; /// typedef std::pair InsnRange; +//===----------------------------------------------------------------------===// +/// LexicalScope - This class is used to track scope information. +/// +class LexicalScope { + +public: + LexicalScope(LexicalScope *P, const DILocalScope *D, const DILocation *I, + bool A) + : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A), + LastInsn(nullptr), FirstInsn(nullptr), DFSIn(0), DFSOut(0) { + assert((!D || D->isResolved()) && "Expected resolved node"); + assert((!I || I->isResolved()) && "Expected resolved node"); + if (Parent) + Parent->addChild(this); + } + + // Accessors. + LexicalScope *getParent() const { return Parent; } + const MDNode *getDesc() const { return Desc; } + const DILocation *getInlinedAt() const { return InlinedAtLocation; } + const DILocalScope *getScopeNode() const { return Desc; } + bool isAbstractScope() const { return AbstractScope; } + SmallVectorImpl &getChildren() { return Children; } + SmallVectorImpl &getRanges() { return Ranges; } + + /// addChild - Add a child scope. + void addChild(LexicalScope *S) { Children.push_back(S); } + + /// openInsnRange - This scope covers instruction range starting from MI. + void openInsnRange(const MachineInstr *MI) { + if (!FirstInsn) + FirstInsn = MI; + + if (Parent) + Parent->openInsnRange(MI); + } + + /// extendInsnRange - Extend the current instruction range covered by + /// this scope. + void extendInsnRange(const MachineInstr *MI) { + assert(FirstInsn && "MI Range is not open!"); + LastInsn = MI; + if (Parent) + Parent->extendInsnRange(MI); + } + + /// closeInsnRange - Create a range based on FirstInsn and LastInsn collected + /// until now. This is used when a new scope is encountered while walking + /// machine instructions. + void closeInsnRange(LexicalScope *NewScope = nullptr) { + assert(LastInsn && "Last insn missing!"); + Ranges.push_back(InsnRange(FirstInsn, LastInsn)); + FirstInsn = nullptr; + LastInsn = nullptr; + // If Parent dominates NewScope then do not close Parent's instruction + // range. + if (Parent && (!NewScope || !Parent->dominates(NewScope))) + Parent->closeInsnRange(NewScope); + } + + /// dominates - Return true if current scope dominates given lexical scope. + bool dominates(const LexicalScope *S) const { + if (S == this) + return true; + if (DFSIn < S->getDFSIn() && DFSOut > S->getDFSOut()) + return true; + return false; + } + + // Depth First Search support to walk and manipulate LexicalScope hierarchy. + unsigned getDFSOut() const { return DFSOut; } + void setDFSOut(unsigned O) { DFSOut = O; } + unsigned getDFSIn() const { return DFSIn; } + void setDFSIn(unsigned I) { DFSIn = I; } + + /// dump - print lexical scope. + void dump(unsigned Indent = 0) const; + +private: + LexicalScope *Parent; // Parent to this scope. + const DILocalScope *Desc; // Debug info descriptor. + const DILocation *InlinedAtLocation; // Location at which this + // scope is inlined. + bool AbstractScope; // Abstract Scope + SmallVector Children; // Scopes defined in scope. + // Contents not owned. + SmallVector Ranges; + + const MachineInstr *LastInsn; // Last instruction of this scope. + const MachineInstr *FirstInsn; // First instruction of this scope. + unsigned DFSIn, DFSOut; // In & Out Depth use to determine + // scope nesting. +}; + //===----------------------------------------------------------------------===// /// LexicalScopes - This class provides interface to collect and use lexical /// scoping information from machine instruction. /// class LexicalScopes { public: - LexicalScopes() : MF(NULL), CurrentFnLexicalScope(NULL) { } - virtual ~LexicalScopes(); + LexicalScopes() : MF(nullptr), CurrentFnLexicalScope(nullptr) {} - /// initialize - Scan machine function and constuct lexical scope nest. - virtual void initialize(const MachineFunction &); + /// initialize - Scan machine function and constuct lexical scope nest, resets + /// the instance if necessary. + void initialize(const MachineFunction &); /// releaseMemory - release memory. - virtual void releaseMemory(); - - /// empty - Return true if there is any lexical scope information available. - bool empty() { return CurrentFnLexicalScope == NULL; } + void reset(); - /// isCurrentFunctionScope - Return true if given lexical scope represents - /// current function. - bool isCurrentFunctionScope(const LexicalScope *LS) { - return LS == CurrentFnLexicalScope; - } + /// empty - Return true if there is any lexical scope information available. + bool empty() { return CurrentFnLexicalScope == nullptr; } /// getCurrentFunctionScope - Return lexical scope for the current function. - LexicalScope *getCurrentFunctionScope() const { return CurrentFnLexicalScope;} + LexicalScope *getCurrentFunctionScope() const { + return CurrentFnLexicalScope; + } /// getMachineBasicBlocks - Populate given set using machine basic blocks /// which have machine instructions that belong to lexical scope identified by /// DebugLoc. - void getMachineBasicBlocks(DebugLoc DL, - SmallPtrSet &MBBs); + void getMachineBasicBlocks(const DILocation *DL, + SmallPtrSetImpl &MBBs); /// dominates - Return true if DebugLoc's lexical scope dominates at least one /// machine instruction's lexical scope in a given machine basic block. - bool dominates(DebugLoc DL, MachineBasicBlock *MBB); + bool dominates(const DILocation *DL, MachineBasicBlock *MBB); /// findLexicalScope - Find lexical scope, either regular or inlined, for the /// given DebugLoc. Return NULL if not found. - LexicalScope *findLexicalScope(DebugLoc DL); + LexicalScope *findLexicalScope(const DILocation *DL); /// getAbstractScopesList - Return a reference to list of abstract scopes. ArrayRef getAbstractScopesList() const { return AbstractScopesList; } - /// findAbstractScope - Find an abstract scope or return NULL. - LexicalScope *findAbstractScope(const MDNode *N) { - return AbstractScopeMap.lookup(N); + /// findAbstractScope - Find an abstract scope or return null. + LexicalScope *findAbstractScope(const DILocalScope *N) { + auto I = AbstractScopeMap.find(N); + return I != AbstractScopeMap.end() ? &I->second : nullptr; } - /// findInlinedScope - Find an inlined scope for the given DebugLoc or return - /// NULL. - LexicalScope *findInlinedScope(DebugLoc DL) { - return InlinedLexicalScopeMap.lookup(DL); + /// findInlinedScope - Find an inlined scope for the given scope/inlined-at. + LexicalScope *findInlinedScope(const DILocalScope *N, const DILocation *IA) { + auto I = InlinedLexicalScopeMap.find(std::make_pair(N, IA)); + return I != InlinedLexicalScopeMap.end() ? &I->second : nullptr; } - /// findLexicalScope - Find regular lexical scope or return NULL. - LexicalScope *findLexicalScope(const MDNode *N) { - return LexicalScopeMap.lookup(N); + /// findLexicalScope - Find regular lexical scope or return null. + LexicalScope *findLexicalScope(const DILocalScope *N) { + auto I = LexicalScopeMap.find(N); + return I != LexicalScopeMap.end() ? &I->second : nullptr; } /// dump - Print data structures to dbgs(). void dump(); -private: + /// getOrCreateAbstractScope - Find or create an abstract lexical scope. + LexicalScope *getOrCreateAbstractScope(const DILocalScope *Scope); - /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If +private: + /// getOrCreateLexicalScope - Find lexical scope for the given Scope/IA. If /// not available then create new lexical scope. - LexicalScope *getOrCreateLexicalScope(DebugLoc DL); + LexicalScope *getOrCreateLexicalScope(const DILocalScope *Scope, + const DILocation *IA = nullptr); + LexicalScope *getOrCreateLexicalScope(const DILocation *DL) { + return DL ? getOrCreateLexicalScope(DL->getScope(), DL->getInlinedAt()) + : nullptr; + } /// getOrCreateRegularScope - Find or create a regular lexical scope. - LexicalScope *getOrCreateRegularScope(MDNode *Scope); + LexicalScope *getOrCreateRegularScope(const DILocalScope *Scope); /// getOrCreateInlinedScope - Find or create an inlined lexical scope. - LexicalScope *getOrCreateInlinedScope(MDNode *Scope, MDNode *InlinedAt); - - /// getOrCreateAbstractScope - Find or create an abstract lexical scope. - LexicalScope *getOrCreateAbstractScope(const MDNode *N); + LexicalScope *getOrCreateInlinedScope(const DILocalScope *Scope, + const DILocation *InlinedAt); /// extractLexicalScopes - Extract instruction ranges for each lexical scopes /// for the given machine function. void extractLexicalScopes(SmallVectorImpl &MIRanges, DenseMap &M); void constructScopeNest(LexicalScope *Scope); - void assignInstructionRanges(SmallVectorImpl &MIRanges, - DenseMap &M); + void + assignInstructionRanges(SmallVectorImpl &MIRanges, + DenseMap &M); private: const MachineFunction *MF; - /// LexicalScopeMap - Tracks the scopes in the current function. Owns the - /// contained LexicalScope*s. - DenseMap LexicalScopeMap; + /// LexicalScopeMap - Tracks the scopes in the current function. + // Use an unordered_map to ensure value pointer validity over insertion. + std::unordered_map LexicalScopeMap; - /// InlinedLexicalScopeMap - Tracks inlined function scopes in current function. - DenseMap InlinedLexicalScopeMap; + /// InlinedLexicalScopeMap - Tracks inlined function scopes in current + /// function. + std::unordered_map, + LexicalScope, + pair_hash> + InlinedLexicalScopeMap; - /// AbstractScopeMap - These scopes are not included LexicalScopeMap. - /// AbstractScopes owns its LexicalScope*s. - DenseMap AbstractScopeMap; + /// AbstractScopeMap - These scopes are not included LexicalScopeMap. + // Use an unordered_map to ensure value pointer validity over insertion. + std::unordered_map AbstractScopeMap; /// AbstractScopesList - Tracks abstract scopes constructed while processing - /// a function. - SmallVectorAbstractScopesList; + /// a function. + SmallVector AbstractScopesList; /// CurrentFnLexicalScope - Top level scope for the current function. /// LexicalScope *CurrentFnLexicalScope; }; -//===----------------------------------------------------------------------===// -/// LexicalScope - This class is used to track scope information. -/// -class LexicalScope { - -public: - LexicalScope(LexicalScope *P, const MDNode *D, const MDNode *I, bool A) - : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(A), - LastInsn(0), FirstInsn(0), DFSIn(0), DFSOut(0), IndentLevel(0) { - if (Parent) - Parent->addChild(this); - } - - virtual ~LexicalScope() {} - - // Accessors. - LexicalScope *getParent() const { return Parent; } - const MDNode *getDesc() const { return Desc; } - const MDNode *getInlinedAt() const { return InlinedAtLocation; } - const MDNode *getScopeNode() const { return Desc; } - bool isAbstractScope() const { return AbstractScope; } - SmallVector &getChildren() { return Children; } - SmallVector &getRanges() { return Ranges; } - - /// addChild - Add a child scope. - void addChild(LexicalScope *S) { Children.push_back(S); } - - /// openInsnRange - This scope covers instruction range starting from MI. - void openInsnRange(const MachineInstr *MI) { - if (!FirstInsn) - FirstInsn = MI; - - if (Parent) - Parent->openInsnRange(MI); - } - - /// extendInsnRange - Extend the current instruction range covered by - /// this scope. - void extendInsnRange(const MachineInstr *MI) { - assert (FirstInsn && "MI Range is not open!"); - LastInsn = MI; - if (Parent) - Parent->extendInsnRange(MI); - } - - /// closeInsnRange - Create a range based on FirstInsn and LastInsn collected - /// until now. This is used when a new scope is encountered while walking - /// machine instructions. - void closeInsnRange(LexicalScope *NewScope = NULL) { - assert (LastInsn && "Last insn missing!"); - Ranges.push_back(InsnRange(FirstInsn, LastInsn)); - FirstInsn = NULL; - LastInsn = NULL; - // If Parent dominates NewScope then do not close Parent's instruction - // range. - if (Parent && (!NewScope || !Parent->dominates(NewScope))) - Parent->closeInsnRange(NewScope); - } - - /// dominates - Return true if current scope dominsates given lexical scope. - bool dominates(const LexicalScope *S) { - if (S == this) - return true; - if (DFSIn < S->getDFSIn() && DFSOut > S->getDFSOut()) - return true; - return false; - } - - // Depth First Search support to walk and manipulate LexicalScope hierarchy. - unsigned getDFSOut() const { return DFSOut; } - void setDFSOut(unsigned O) { DFSOut = O; } - unsigned getDFSIn() const { return DFSIn; } - void setDFSIn(unsigned I) { DFSIn = I; } - - /// dump - print lexical scope. - void dump() const; - -private: - LexicalScope *Parent; // Parent to this scope. - AssertingVH Desc; // Debug info descriptor. - AssertingVH InlinedAtLocation; // Location at which this - // scope is inlined. - bool AbstractScope; // Abstract Scope - SmallVector Children; // Scopes defined in scope. - // Contents not owned. - SmallVector Ranges; - - const MachineInstr *LastInsn; // Last instruction of this scope. - const MachineInstr *FirstInsn; // First instruction of this scope. - unsigned DFSIn, DFSOut; // In & Out Depth use to determine - // scope nesting. - mutable unsigned IndentLevel; // Private state for dump() -}; - } // end llvm namespace #endif