mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-04-13 13:00:24 +00:00
Reapply r207876 (Try simplifying LexicalScopes ownership again) including a workaround for an MSVC2012 bug regarding forward_as_tuple
(r207876 was reverted in r208131 after seeing some consistent buildbot failure for MSVC 2012. The original commits were in r207724-r207726) Takumi was nice enough to dig into this and locate this Microsoft Connect issue: http://connect.microsoft.com/VisualStudio/feedback/details/814899/forward-as-tuple-debug-implementation-error describing a bug in MSVC2012's forward_as_tuple implementation. Since the parameters in this instance are trivial/small, pass them by value (using make_tuple) instead of perfectly-forwarded tuple of rvalue references (involving the broken forward_as_tuple). Hopefully this will satisfy MSVC2012. llvm-svn: 208364
This commit is contained in:
parent
336fe9979c
commit
f61e94a80f
@ -25,12 +25,12 @@
|
|||||||
#include "llvm/IR/Metadata.h"
|
#include "llvm/IR/Metadata.h"
|
||||||
#include "llvm/IR/ValueHandle.h"
|
#include "llvm/IR/ValueHandle.h"
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <unordered_map>
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class MachineInstr;
|
class MachineInstr;
|
||||||
class MachineBasicBlock;
|
class MachineBasicBlock;
|
||||||
class MachineFunction;
|
class MachineFunction;
|
||||||
class LexicalScope;
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
/// InsnRange - This is used to track range of instructions with identical
|
/// 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;
|
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.
|
/// LexicalScope - This class is used to track scope information.
|
||||||
///
|
///
|
||||||
@ -244,6 +129,122 @@ private:
|
|||||||
// scope nesting.
|
// 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.
|
||||||
|
// Use an unordered_map to ensure value pointer validity over insertion.
|
||||||
|
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.
|
||||||
|
// Use an unordered_map to ensure value pointer validity over insertion.
|
||||||
|
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
|
} // end llvm namespace
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,15 +26,12 @@ using namespace llvm;
|
|||||||
|
|
||||||
#define DEBUG_TYPE "lexicalscopes"
|
#define DEBUG_TYPE "lexicalscopes"
|
||||||
|
|
||||||
/// ~LexicalScopes - final cleanup after ourselves.
|
|
||||||
LexicalScopes::~LexicalScopes() { reset(); }
|
|
||||||
|
|
||||||
/// reset - Reset the instance so that it's prepared for another function.
|
/// reset - Reset the instance so that it's prepared for another function.
|
||||||
void LexicalScopes::reset() {
|
void LexicalScopes::reset() {
|
||||||
MF = nullptr;
|
MF = nullptr;
|
||||||
CurrentFnLexicalScope = nullptr;
|
CurrentFnLexicalScope = nullptr;
|
||||||
DeleteContainerSeconds(LexicalScopeMap);
|
LexicalScopeMap.clear();
|
||||||
DeleteContainerSeconds(AbstractScopeMap);
|
AbstractScopeMap.clear();
|
||||||
InlinedLexicalScopeMap.clear();
|
InlinedLexicalScopeMap.clear();
|
||||||
AbstractScopesList.clear();
|
AbstractScopesList.clear();
|
||||||
}
|
}
|
||||||
@ -124,7 +121,7 @@ LexicalScope *LexicalScopes::findLexicalScope(DebugLoc DL) {
|
|||||||
|
|
||||||
if (IA)
|
if (IA)
|
||||||
return InlinedLexicalScopeMap.lookup(DebugLoc::getFromDILocation(IA));
|
return InlinedLexicalScopeMap.lookup(DebugLoc::getFromDILocation(IA));
|
||||||
return LexicalScopeMap.lookup(Scope);
|
return findLexicalScope(Scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
|
/// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
|
||||||
@ -152,35 +149,43 @@ LexicalScope *LexicalScopes::getOrCreateRegularScope(MDNode *Scope) {
|
|||||||
D = DIDescriptor(Scope);
|
D = DIDescriptor(Scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
LexicalScope *WScope = LexicalScopeMap.lookup(Scope);
|
auto I = LexicalScopeMap.find(Scope);
|
||||||
if (WScope)
|
if (I != LexicalScopeMap.end())
|
||||||
return WScope;
|
return &I->second;
|
||||||
|
|
||||||
LexicalScope *Parent = nullptr;
|
LexicalScope *Parent = nullptr;
|
||||||
if (D.isLexicalBlock())
|
if (D.isLexicalBlock())
|
||||||
Parent = getOrCreateLexicalScope(DebugLoc::getFromDILexicalBlock(Scope));
|
Parent = getOrCreateLexicalScope(DebugLoc::getFromDILexicalBlock(Scope));
|
||||||
WScope = new LexicalScope(Parent, DIDescriptor(Scope), nullptr, false);
|
// FIXME: Use forward_as_tuple instead of make_tuple, once MSVC2012
|
||||||
LexicalScopeMap.insert(std::make_pair(Scope, WScope));
|
// compatibility is no longer required.
|
||||||
|
I = LexicalScopeMap.emplace(std::piecewise_construct, std::make_tuple(Scope),
|
||||||
|
std::make_tuple(Parent, DIDescriptor(Scope),
|
||||||
|
nullptr, false)).first;
|
||||||
|
|
||||||
if (!Parent && DIDescriptor(Scope).isSubprogram() &&
|
if (!Parent && DIDescriptor(Scope).isSubprogram() &&
|
||||||
DISubprogram(Scope).describes(MF->getFunction()))
|
DISubprogram(Scope).describes(MF->getFunction()))
|
||||||
CurrentFnLexicalScope = WScope;
|
CurrentFnLexicalScope = &I->second;
|
||||||
|
|
||||||
return WScope;
|
return &I->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getOrCreateInlinedScope - Find or create an inlined lexical scope.
|
/// getOrCreateInlinedScope - Find or create an inlined lexical scope.
|
||||||
LexicalScope *LexicalScopes::getOrCreateInlinedScope(MDNode *Scope,
|
LexicalScope *LexicalScopes::getOrCreateInlinedScope(MDNode *Scope,
|
||||||
MDNode *InlinedAt) {
|
MDNode *InlinedAt) {
|
||||||
LexicalScope *InlinedScope = LexicalScopeMap.lookup(InlinedAt);
|
auto I = LexicalScopeMap.find(InlinedAt);
|
||||||
if (InlinedScope)
|
if (I != LexicalScopeMap.end())
|
||||||
return InlinedScope;
|
return &I->second;
|
||||||
|
|
||||||
DebugLoc InlinedLoc = DebugLoc::getFromDILocation(InlinedAt);
|
DebugLoc InlinedLoc = DebugLoc::getFromDILocation(InlinedAt);
|
||||||
InlinedScope = new LexicalScope(getOrCreateLexicalScope(InlinedLoc),
|
// FIXME: Use forward_as_tuple instead of make_tuple, once MSVC2012
|
||||||
DIDescriptor(Scope), InlinedAt, false);
|
// compatibility is no longer required.
|
||||||
InlinedLexicalScopeMap[InlinedLoc] = InlinedScope;
|
I = LexicalScopeMap.emplace(
|
||||||
LexicalScopeMap[InlinedAt] = InlinedScope;
|
std::piecewise_construct, std::make_tuple(InlinedAt),
|
||||||
return InlinedScope;
|
std::make_tuple(getOrCreateLexicalScope(InlinedLoc),
|
||||||
|
DIDescriptor(Scope), InlinedAt,
|
||||||
|
false)).first;
|
||||||
|
InlinedLexicalScopeMap[InlinedLoc] = &I->second;
|
||||||
|
return &I->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getOrCreateAbstractScope - Find or create an abstract lexical scope.
|
/// getOrCreateAbstractScope - Find or create an abstract lexical scope.
|
||||||
@ -190,9 +195,9 @@ LexicalScope *LexicalScopes::getOrCreateAbstractScope(const MDNode *N) {
|
|||||||
DIDescriptor Scope(N);
|
DIDescriptor Scope(N);
|
||||||
if (Scope.isLexicalBlockFile())
|
if (Scope.isLexicalBlockFile())
|
||||||
Scope = DILexicalBlockFile(Scope).getScope();
|
Scope = DILexicalBlockFile(Scope).getScope();
|
||||||
LexicalScope *AScope = AbstractScopeMap.lookup(N);
|
auto I = AbstractScopeMap.find(N);
|
||||||
if (AScope)
|
if (I != AbstractScopeMap.end())
|
||||||
return AScope;
|
return &I->second;
|
||||||
|
|
||||||
LexicalScope *Parent = nullptr;
|
LexicalScope *Parent = nullptr;
|
||||||
if (Scope.isLexicalBlock()) {
|
if (Scope.isLexicalBlock()) {
|
||||||
@ -200,11 +205,13 @@ LexicalScope *LexicalScopes::getOrCreateAbstractScope(const MDNode *N) {
|
|||||||
DIDescriptor ParentDesc = DB.getContext();
|
DIDescriptor ParentDesc = DB.getContext();
|
||||||
Parent = getOrCreateAbstractScope(ParentDesc);
|
Parent = getOrCreateAbstractScope(ParentDesc);
|
||||||
}
|
}
|
||||||
AScope = new LexicalScope(Parent, DIDescriptor(N), nullptr, true);
|
I = AbstractScopeMap.emplace(std::piecewise_construct,
|
||||||
AbstractScopeMap[N] = AScope;
|
std::forward_as_tuple(N),
|
||||||
|
std::forward_as_tuple(Parent, DIDescriptor(N),
|
||||||
|
nullptr, true)).first;
|
||||||
if (DIDescriptor(N).isSubprogram())
|
if (DIDescriptor(N).isSubprogram())
|
||||||
AbstractScopesList.push_back(AScope);
|
AbstractScopesList.push_back(&I->second);
|
||||||
return AScope;
|
return &I->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// constructScopeNest
|
/// constructScopeNest
|
||||||
|
Loading…
x
Reference in New Issue
Block a user