From 10c37a012ea11596d44cd9059fe09c959caf30c8 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Fri, 2 May 2014 22:21:05 +0000 Subject: [PATCH] Try simplifying LexicalScopes ownership again. Committed initially in r207724-r207726 and reverted due to compiler-rt crashes in r207732. Instead, fix this harder with unordered_map and store the LexicalScopes by value in the map. This did necessitate moving the definition of LexicalScope above the definition of LexicalScopes. Let's see how the buildbots/compilers tolerate unordered_map::emplace + std::piecewise_construct + std::forward_as_tuple... git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207876 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/LexicalScopes.h | 233 ++++++++++++++------------- lib/CodeGen/LexicalScopes.cpp | 60 +++---- 2 files changed, 149 insertions(+), 144 deletions(-) diff --git a/include/llvm/CodeGen/LexicalScopes.h b/include/llvm/CodeGen/LexicalScopes.h index d6468bd75c2..89e0287032d 100644 --- a/include/llvm/CodeGen/LexicalScopes.h +++ b/include/llvm/CodeGen/LexicalScopes.h @@ -25,12 +25,12 @@ #include "llvm/IR/Metadata.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,121 +38,6 @@ class LexicalScope; /// typedef std::pair InsnRange; -//===----------------------------------------------------------------------===// -/// LexicalScopes - This class provides interface to collect and use lexical -/// scoping information from machine instruction. -/// -class LexicalScopes { -public: - LexicalScopes() : MF(nullptr), CurrentFnLexicalScope(nullptr) {} - ~LexicalScopes(); - - /// initialize - Scan machine function and constuct lexical scope nest, resets - /// the instance if necessary. - void initialize(const MachineFunction &); - - /// releaseMemory - release memory. - void reset(); - - /// empty - Return true if there is any lexical scope information available. - bool empty() { return CurrentFnLexicalScope == nullptr; } - - /// isCurrentFunctionScope - Return true if given lexical scope represents - /// current function. - bool isCurrentFunctionScope(const LexicalScope *LS) { - return LS == CurrentFnLexicalScope; - } - - /// getCurrentFunctionScope - Return lexical scope for the current function. - 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); - - /// 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); - - /// findLexicalScope - Find lexical scope, either regular or inlined, for the - /// given DebugLoc. Return NULL if not found. - LexicalScope *findLexicalScope(DebugLoc 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); - } - - /// findInlinedScope - Find an inlined scope for the given DebugLoc or return - /// NULL. - LexicalScope *findInlinedScope(DebugLoc DL) { - return InlinedLexicalScopeMap.lookup(DL); - } - - /// findLexicalScope - Find regular lexical scope or return NULL. - LexicalScope *findLexicalScope(const MDNode *N) { - return LexicalScopeMap.lookup(N); - } - - /// dump - Print data structures to dbgs(). - void dump(); - -private: - /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If - /// not available then create new lexical scope. - LexicalScope *getOrCreateLexicalScope(DebugLoc DL); - - /// getOrCreateRegularScope - Find or create a regular lexical scope. - LexicalScope *getOrCreateRegularScope(MDNode *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); - - /// 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); - -private: - const MachineFunction *MF; - - /// LexicalScopeMap - Tracks the scopes in the current function. Owns the - /// contained LexicalScope*s. - DenseMap LexicalScopeMap; - - /// InlinedLexicalScopeMap - Tracks inlined function scopes in current - /// function. - DenseMap InlinedLexicalScopeMap; - - /// AbstractScopeMap - These scopes are not included LexicalScopeMap. - /// AbstractScopes owns its LexicalScope*s. - DenseMap AbstractScopeMap; - - /// AbstractScopesList - Tracks abstract scopes constructed while processing - /// a function. - SmallVector AbstractScopesList; - - /// CurrentFnLexicalScope - Top level scope for the current function. - /// - LexicalScope *CurrentFnLexicalScope; -}; - //===----------------------------------------------------------------------===// /// LexicalScope - This class is used to track scope information. /// @@ -244,6 +129,122 @@ private: // scope nesting. }; +//===----------------------------------------------------------------------===// +/// LexicalScopes - This class provides interface to collect and use lexical +/// scoping information from machine instruction. +/// +class LexicalScopes { +public: + LexicalScopes() : MF(nullptr), CurrentFnLexicalScope(nullptr) {} + + /// initialize - Scan machine function and constuct lexical scope nest, resets + /// the instance if necessary. + void initialize(const MachineFunction &); + + /// releaseMemory - release memory. + void reset(); + + /// empty - Return true if there is any lexical scope information available. + bool empty() { return CurrentFnLexicalScope == nullptr; } + + /// isCurrentFunctionScope - Return true if given lexical scope represents + /// current function. + bool isCurrentFunctionScope(const LexicalScope *LS) { + return LS == CurrentFnLexicalScope; + } + + /// getCurrentFunctionScope - Return lexical scope for the current function. + 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); + + /// 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); + + /// findLexicalScope - Find lexical scope, either regular or inlined, for the + /// given DebugLoc. Return NULL if not found. + LexicalScope *findLexicalScope(DebugLoc 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) { + 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); + } + + /// findLexicalScope - Find regular lexical scope or return null. + LexicalScope *findLexicalScope(const MDNode *N) { + auto I = LexicalScopeMap.find(N); + return I != LexicalScopeMap.end() ? &I->second : nullptr; + } + + /// dump - Print data structures to dbgs(). + void dump(); + +private: + /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If + /// not available then create new lexical scope. + LexicalScope *getOrCreateLexicalScope(DebugLoc DL); + + /// getOrCreateRegularScope - Find or create a regular lexical scope. + LexicalScope *getOrCreateRegularScope(MDNode *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); + + /// 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); + +private: + const MachineFunction *MF; + + /// LexicalScopeMap - Tracks the scopes in the current function. Owns the + /// contained LexicalScope*s. + std::unordered_map LexicalScopeMap; + + /// InlinedLexicalScopeMap - Tracks inlined function scopes in current + /// function. + DenseMap InlinedLexicalScopeMap; + + /// AbstractScopeMap - These scopes are not included LexicalScopeMap. + /// AbstractScopes owns its LexicalScope*s. + std::unordered_map AbstractScopeMap; + + /// AbstractScopesList - Tracks abstract scopes constructed while processing + /// a function. + SmallVector AbstractScopesList; + + /// CurrentFnLexicalScope - Top level scope for the current function. + /// + LexicalScope *CurrentFnLexicalScope; +}; + } // end llvm namespace #endif diff --git a/lib/CodeGen/LexicalScopes.cpp b/lib/CodeGen/LexicalScopes.cpp index f01dec28e52..89c90539f4a 100644 --- a/lib/CodeGen/LexicalScopes.cpp +++ b/lib/CodeGen/LexicalScopes.cpp @@ -26,15 +26,12 @@ using namespace llvm; #define DEBUG_TYPE "lexicalscopes" -/// ~LexicalScopes - final cleanup after ourselves. -LexicalScopes::~LexicalScopes() { reset(); } - /// reset - Reset the instance so that it's prepared for another function. void LexicalScopes::reset() { MF = nullptr; CurrentFnLexicalScope = nullptr; - DeleteContainerSeconds(LexicalScopeMap); - DeleteContainerSeconds(AbstractScopeMap); + LexicalScopeMap.clear(); + AbstractScopeMap.clear(); InlinedLexicalScopeMap.clear(); AbstractScopesList.clear(); } @@ -124,7 +121,7 @@ LexicalScope *LexicalScopes::findLexicalScope(DebugLoc DL) { if (IA) return InlinedLexicalScopeMap.lookup(DebugLoc::getFromDILocation(IA)); - return LexicalScopeMap.lookup(Scope); + return findLexicalScope(Scope); } /// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If @@ -152,35 +149,40 @@ LexicalScope *LexicalScopes::getOrCreateRegularScope(MDNode *Scope) { D = DIDescriptor(Scope); } - LexicalScope *WScope = LexicalScopeMap.lookup(Scope); - if (WScope) - return WScope; + auto I = LexicalScopeMap.find(Scope); + if (I != LexicalScopeMap.end()) + return &I->second; LexicalScope *Parent = nullptr; if (D.isLexicalBlock()) Parent = getOrCreateLexicalScope(DebugLoc::getFromDILexicalBlock(Scope)); - WScope = new LexicalScope(Parent, DIDescriptor(Scope), nullptr, false); - LexicalScopeMap.insert(std::make_pair(Scope, WScope)); + I = LexicalScopeMap.emplace(std::piecewise_construct, + std::forward_as_tuple(Scope), + std::forward_as_tuple(Parent, DIDescriptor(Scope), + nullptr, false)).first; + if (!Parent && DIDescriptor(Scope).isSubprogram() && DISubprogram(Scope).describes(MF->getFunction())) - CurrentFnLexicalScope = WScope; + CurrentFnLexicalScope = &I->second; - return WScope; + return &I->second; } /// getOrCreateInlinedScope - Find or create an inlined lexical scope. LexicalScope *LexicalScopes::getOrCreateInlinedScope(MDNode *Scope, MDNode *InlinedAt) { - LexicalScope *InlinedScope = LexicalScopeMap.lookup(InlinedAt); - if (InlinedScope) - return InlinedScope; + auto I = LexicalScopeMap.find(InlinedAt); + if (I != LexicalScopeMap.end()) + return &I->second; DebugLoc InlinedLoc = DebugLoc::getFromDILocation(InlinedAt); - InlinedScope = new LexicalScope(getOrCreateLexicalScope(InlinedLoc), - DIDescriptor(Scope), InlinedAt, false); - InlinedLexicalScopeMap[InlinedLoc] = InlinedScope; - LexicalScopeMap[InlinedAt] = InlinedScope; - return InlinedScope; + I = LexicalScopeMap.emplace(std::piecewise_construct, + std::forward_as_tuple(InlinedAt), + std::forward_as_tuple( + getOrCreateLexicalScope(InlinedLoc), + DIDescriptor(Scope), InlinedAt, false)).first; + InlinedLexicalScopeMap[InlinedLoc] = &I->second; + return &I->second; } /// getOrCreateAbstractScope - Find or create an abstract lexical scope. @@ -190,9 +192,9 @@ LexicalScope *LexicalScopes::getOrCreateAbstractScope(const MDNode *N) { DIDescriptor Scope(N); if (Scope.isLexicalBlockFile()) Scope = DILexicalBlockFile(Scope).getScope(); - LexicalScope *AScope = AbstractScopeMap.lookup(N); - if (AScope) - return AScope; + auto I = AbstractScopeMap.find(N); + if (I != AbstractScopeMap.end()) + return &I->second; LexicalScope *Parent = nullptr; if (Scope.isLexicalBlock()) { @@ -200,11 +202,13 @@ LexicalScope *LexicalScopes::getOrCreateAbstractScope(const MDNode *N) { DIDescriptor ParentDesc = DB.getContext(); Parent = getOrCreateAbstractScope(ParentDesc); } - AScope = new LexicalScope(Parent, DIDescriptor(N), nullptr, true); - AbstractScopeMap[N] = AScope; + I = AbstractScopeMap.emplace(std::piecewise_construct, + std::forward_as_tuple(N), + std::forward_as_tuple(Parent, DIDescriptor(N), + nullptr, true)).first; if (DIDescriptor(N).isSubprogram()) - AbstractScopesList.push_back(AScope); - return AScope; + AbstractScopesList.push_back(&I->second); + return &I->second; } /// constructScopeNest