mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-29 06:30:39 +00:00
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
This commit is contained in:
parent
c7b30d80a2
commit
10c37a012e
@ -25,12 +25,12 @@
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
#include <utility>
|
||||
#include <unordered_map>
|
||||
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<const MachineInstr *, const MachineInstr *> 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<const MachineBasicBlock *, 4> &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<LexicalScope *> 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<InsnRange> &MIRanges,
|
||||
DenseMap<const MachineInstr *, LexicalScope *> &M);
|
||||
void constructScopeNest(LexicalScope *Scope);
|
||||
void
|
||||
assignInstructionRanges(SmallVectorImpl<InsnRange> &MIRanges,
|
||||
DenseMap<const MachineInstr *, LexicalScope *> &M);
|
||||
|
||||
private:
|
||||
const MachineFunction *MF;
|
||||
|
||||
/// LexicalScopeMap - Tracks the scopes in the current function. Owns the
|
||||
/// contained LexicalScope*s.
|
||||
DenseMap<const MDNode *, LexicalScope *> LexicalScopeMap;
|
||||
|
||||
/// InlinedLexicalScopeMap - Tracks inlined function scopes in current
|
||||
/// function.
|
||||
DenseMap<DebugLoc, LexicalScope *> InlinedLexicalScopeMap;
|
||||
|
||||
/// AbstractScopeMap - These scopes are not included LexicalScopeMap.
|
||||
/// AbstractScopes owns its LexicalScope*s.
|
||||
DenseMap<const MDNode *, LexicalScope *> AbstractScopeMap;
|
||||
|
||||
/// AbstractScopesList - Tracks abstract scopes constructed while processing
|
||||
/// a function.
|
||||
SmallVector<LexicalScope *, 4> 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<const MachineBasicBlock *, 4> &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<LexicalScope *> 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<InsnRange> &MIRanges,
|
||||
DenseMap<const MachineInstr *, LexicalScope *> &M);
|
||||
void constructScopeNest(LexicalScope *Scope);
|
||||
void
|
||||
assignInstructionRanges(SmallVectorImpl<InsnRange> &MIRanges,
|
||||
DenseMap<const MachineInstr *, LexicalScope *> &M);
|
||||
|
||||
private:
|
||||
const MachineFunction *MF;
|
||||
|
||||
/// LexicalScopeMap - Tracks the scopes in the current function. Owns the
|
||||
/// contained LexicalScope*s.
|
||||
std::unordered_map<const MDNode *, LexicalScope> LexicalScopeMap;
|
||||
|
||||
/// InlinedLexicalScopeMap - Tracks inlined function scopes in current
|
||||
/// function.
|
||||
DenseMap<DebugLoc, LexicalScope *> InlinedLexicalScopeMap;
|
||||
|
||||
/// AbstractScopeMap - These scopes are not included LexicalScopeMap.
|
||||
/// AbstractScopes owns its LexicalScope*s.
|
||||
std::unordered_map<const MDNode *, LexicalScope> AbstractScopeMap;
|
||||
|
||||
/// AbstractScopesList - Tracks abstract scopes constructed while processing
|
||||
/// a function.
|
||||
SmallVector<LexicalScope *, 4> AbstractScopesList;
|
||||
|
||||
/// CurrentFnLexicalScope - Top level scope for the current function.
|
||||
///
|
||||
LexicalScope *CurrentFnLexicalScope;
|
||||
};
|
||||
|
||||
} // end llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user