mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-29 10:32:47 +00:00
LexicalScopes: Use debug info hierarchy pervasively
Pervasively use the types provided by the debug info hierarchy rather than `MDNode` in `LexicalScopes`. I noticed (again, I guess, based on comments in the implementation?) that `DILexicalBlockFile::getScope()` returns something different from `DILexicalBlockFile::getContext()`. I created a local helper for getting the same logic from `MDLexicalBlockFile` called `getScopeOfScope()`. I still don't really understand it, but I've added some FIXMEs and I'll come back to it (I suspect the way we encode these objects isn't really ideal). Note that my previous commit r233610 accidentally changed behaviour in `findLexicalScope()` -- it transitioned from a call to `DILexicalBlockFile::getScope()` to `MDLexicalBlockFile::getScope()` (sounds right, doesn't it?) -- so I've fixed that as a drive-by. No tests failed with my error, so it looks like we're missing some coverage here... when I come back to understand the logic, I'll see if I can add some. Other than the fix to `findLexicalScope()`, no functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233640 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
23ff386e07
commit
62e3e389b9
@ -23,7 +23,7 @@
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/IR/DebugLoc.h"
|
||||
#include "llvm/IR/Metadata.h"
|
||||
#include "llvm/IR/DebugInfoMetadata.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
@ -45,7 +45,8 @@ typedef std::pair<const MachineInstr *, const MachineInstr *> InsnRange;
|
||||
class LexicalScope {
|
||||
|
||||
public:
|
||||
LexicalScope(LexicalScope *P, const MDNode *D, const MDNode *I, bool A)
|
||||
LexicalScope(LexicalScope *P, const MDLocalScope *D, const MDLocation *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");
|
||||
@ -57,8 +58,8 @@ public:
|
||||
// Accessors.
|
||||
LexicalScope *getParent() const { return Parent; }
|
||||
const MDNode *getDesc() const { return Desc; }
|
||||
const MDNode *getInlinedAt() const { return InlinedAtLocation; }
|
||||
const MDNode *getScopeNode() const { return Desc; }
|
||||
const MDLocation *getInlinedAt() const { return InlinedAtLocation; }
|
||||
const MDLocalScope *getScopeNode() const { return Desc; }
|
||||
bool isAbstractScope() const { return AbstractScope; }
|
||||
SmallVectorImpl<LexicalScope *> &getChildren() { return Children; }
|
||||
SmallVectorImpl<InsnRange> &getRanges() { return Ranges; }
|
||||
@ -118,8 +119,8 @@ public:
|
||||
|
||||
private:
|
||||
LexicalScope *Parent; // Parent to this scope.
|
||||
const MDNode *Desc; // Debug info descriptor.
|
||||
const MDNode *InlinedAtLocation; // Location at which this
|
||||
const MDLocalScope *Desc; // Debug info descriptor.
|
||||
const MDLocation *InlinedAtLocation; // Location at which this
|
||||
// scope is inlined.
|
||||
bool AbstractScope; // Abstract Scope
|
||||
SmallVector<LexicalScope *, 4> Children; // Scopes defined in scope.
|
||||
@ -175,19 +176,19 @@ public:
|
||||
}
|
||||
|
||||
/// findAbstractScope - Find an abstract scope or return null.
|
||||
LexicalScope *findAbstractScope(const MDNode *N) {
|
||||
LexicalScope *findAbstractScope(const MDLocalScope *N) {
|
||||
auto I = AbstractScopeMap.find(N);
|
||||
return I != AbstractScopeMap.end() ? &I->second : nullptr;
|
||||
}
|
||||
|
||||
/// findInlinedScope - Find an inlined scope for the given scope/inlined-at.
|
||||
LexicalScope *findInlinedScope(const MDNode *N, const MDNode *IA) {
|
||||
LexicalScope *findInlinedScope(const MDLocalScope *N, const MDLocation *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) {
|
||||
LexicalScope *findLexicalScope(const MDLocalScope *N) {
|
||||
auto I = LexicalScopeMap.find(N);
|
||||
return I != LexicalScopeMap.end() ? &I->second : nullptr;
|
||||
}
|
||||
@ -196,7 +197,7 @@ public:
|
||||
void dump();
|
||||
|
||||
/// getOrCreateAbstractScope - Find or create an abstract lexical scope.
|
||||
LexicalScope *getOrCreateAbstractScope(const MDNode *N);
|
||||
LexicalScope *getOrCreateAbstractScope(const MDLocalScope *Scope);
|
||||
|
||||
private:
|
||||
/// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
|
||||
@ -204,10 +205,11 @@ private:
|
||||
LexicalScope *getOrCreateLexicalScope(const MDLocation *DL);
|
||||
|
||||
/// getOrCreateRegularScope - Find or create a regular lexical scope.
|
||||
LexicalScope *getOrCreateRegularScope(MDNode *Scope);
|
||||
LexicalScope *getOrCreateRegularScope(const MDLocalScope *Scope);
|
||||
|
||||
/// getOrCreateInlinedScope - Find or create an inlined lexical scope.
|
||||
LexicalScope *getOrCreateInlinedScope(MDNode *Scope, MDNode *InlinedAt);
|
||||
LexicalScope *getOrCreateInlinedScope(const MDLocalScope *Scope,
|
||||
const MDLocation *InlinedAt);
|
||||
|
||||
/// extractLexicalScopes - Extract instruction ranges for each lexical scopes
|
||||
/// for the given machine function.
|
||||
@ -223,17 +225,18 @@ private:
|
||||
|
||||
/// 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;
|
||||
std::unordered_map<const MDLocalScope *, LexicalScope> LexicalScopeMap;
|
||||
|
||||
/// InlinedLexicalScopeMap - Tracks inlined function scopes in current
|
||||
/// function.
|
||||
std::unordered_map<std::pair<const MDNode *, const MDNode *>, LexicalScope,
|
||||
pair_hash<const MDNode *, const MDNode *>>
|
||||
InlinedLexicalScopeMap;
|
||||
std::unordered_map<std::pair<const MDLocalScope *, const MDLocation *>,
|
||||
LexicalScope,
|
||||
pair_hash<const MDLocalScope *, const MDLocation *>>
|
||||
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;
|
||||
std::unordered_map<const MDLocalScope *, LexicalScope> AbstractScopeMap;
|
||||
|
||||
/// AbstractScopesList - Tracks abstract scopes constructed while processing
|
||||
/// a function.
|
||||
|
@ -704,7 +704,8 @@ void DwarfDebug::ensureAbstractVariableIsCreated(const DIVariable &DV,
|
||||
if (getExistingAbstractVariable(DV, Cleansed))
|
||||
return;
|
||||
|
||||
createAbstractVariable(Cleansed, LScopes.getOrCreateAbstractScope(ScopeNode));
|
||||
createAbstractVariable(Cleansed, LScopes.getOrCreateAbstractScope(
|
||||
cast<MDLocalScope>(ScopeNode)));
|
||||
}
|
||||
|
||||
void
|
||||
@ -714,7 +715,8 @@ DwarfDebug::ensureAbstractVariableIsCreatedIfScoped(const DIVariable &DV,
|
||||
if (getExistingAbstractVariable(DV, Cleansed))
|
||||
return;
|
||||
|
||||
if (LexicalScope *Scope = LScopes.findAbstractScope(ScopeNode))
|
||||
if (LexicalScope *Scope =
|
||||
LScopes.findAbstractScope(cast_or_null<MDLocalScope>(ScopeNode)))
|
||||
createAbstractVariable(Cleansed, Scope);
|
||||
}
|
||||
|
||||
@ -901,10 +903,10 @@ DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU, DISubprogram SP,
|
||||
continue;
|
||||
|
||||
LexicalScope *Scope = nullptr;
|
||||
if (MDNode *IA = DV.getInlinedAt())
|
||||
Scope = LScopes.findInlinedScope(DV.getContext(), IA);
|
||||
if (MDLocation *IA = DV.get()->getInlinedAt())
|
||||
Scope = LScopes.findInlinedScope(DV.get()->getScope(), IA);
|
||||
else
|
||||
Scope = LScopes.findLexicalScope(DV.getContext());
|
||||
Scope = LScopes.findLexicalScope(DV.get()->getScope());
|
||||
// If variable scope is not found then skip this variable.
|
||||
if (!Scope)
|
||||
continue;
|
||||
@ -943,7 +945,7 @@ DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU, DISubprogram SP,
|
||||
assert(DV.isVariable());
|
||||
if (!Processed.insert(DV).second)
|
||||
continue;
|
||||
if (LexicalScope *Scope = LScopes.findLexicalScope(DV.getContext())) {
|
||||
if (LexicalScope *Scope = LScopes.findLexicalScope(DV.get()->getScope())) {
|
||||
ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode());
|
||||
DIExpression NoExpr;
|
||||
ConcreteVariables.push_back(make_unique<DbgVariable>(DV, NoExpr, this));
|
||||
|
@ -104,6 +104,15 @@ void LexicalScopes::extractLexicalScopes(
|
||||
}
|
||||
}
|
||||
|
||||
static MDLocalScope *getScopeOfScope(const MDLexicalBlockFile *File) {
|
||||
// FIXME: Why double-walk the scope list? Are these just being encoded
|
||||
// awkwardly?
|
||||
auto *Scope = File->getScope();
|
||||
if (auto *Block = dyn_cast<MDLexicalBlockBase>(Scope))
|
||||
return Block->getScope();
|
||||
return Scope;
|
||||
}
|
||||
|
||||
/// findLexicalScope - Find lexical scope, either regular or inlined, for the
|
||||
/// given DebugLoc. Return NULL if not found.
|
||||
LexicalScope *LexicalScopes::findLexicalScope(const MDLocation *DL) {
|
||||
@ -114,7 +123,7 @@ LexicalScope *LexicalScopes::findLexicalScope(const MDLocation *DL) {
|
||||
// The scope that we were created with could have an extra file - which
|
||||
// isn't what we care about in this case.
|
||||
if (auto *File = dyn_cast<MDLexicalBlockFile>(Scope))
|
||||
Scope = File->getScope();
|
||||
Scope = getScopeOfScope(File);
|
||||
|
||||
if (auto *IA = DL->getInlinedAt()) {
|
||||
auto I = InlinedLexicalScopeMap.find(std::make_pair(Scope, IA));
|
||||
@ -128,7 +137,7 @@ LexicalScope *LexicalScopes::findLexicalScope(const MDLocation *DL) {
|
||||
LexicalScope *LexicalScopes::getOrCreateLexicalScope(const MDLocation *DL) {
|
||||
if (!DL)
|
||||
return nullptr;
|
||||
MDScope *Scope = DL->getScope();
|
||||
MDLocalScope *Scope = DL->getScope();
|
||||
if (auto *InlinedAt = DL->getInlinedAt()) {
|
||||
// Create an abstract scope for inlined function.
|
||||
getOrCreateAbstractScope(Scope);
|
||||
@ -140,24 +149,24 @@ LexicalScope *LexicalScopes::getOrCreateLexicalScope(const MDLocation *DL) {
|
||||
}
|
||||
|
||||
/// getOrCreateRegularScope - Find or create a regular lexical scope.
|
||||
LexicalScope *LexicalScopes::getOrCreateRegularScope(MDNode *Scope) {
|
||||
DIDescriptor D = DIDescriptor(Scope);
|
||||
if (D.isLexicalBlockFile()) {
|
||||
Scope = DILexicalBlockFile(Scope).getScope();
|
||||
D = DIDescriptor(Scope);
|
||||
}
|
||||
LexicalScope *
|
||||
LexicalScopes::getOrCreateRegularScope(const MDLocalScope *Scope) {
|
||||
if (auto *File = dyn_cast<MDLexicalBlockFile>(Scope))
|
||||
Scope = getScopeOfScope(File);
|
||||
|
||||
auto I = LexicalScopeMap.find(Scope);
|
||||
if (I != LexicalScopeMap.end())
|
||||
return &I->second;
|
||||
|
||||
LexicalScope *Parent = nullptr;
|
||||
if (D.isLexicalBlock())
|
||||
Parent = getOrCreateLexicalScope(DebugLoc::getFromDILexicalBlock(Scope));
|
||||
if (isa<MDLexicalBlockBase>(Scope)) // FIXME: Should this be MDLexicalBlock?
|
||||
Parent =
|
||||
getOrCreateLexicalScope(DebugLoc::getFromDILexicalBlock(
|
||||
const_cast<MDLocalScope *>(Scope)).get());
|
||||
I = LexicalScopeMap.emplace(std::piecewise_construct,
|
||||
std::forward_as_tuple(Scope),
|
||||
std::forward_as_tuple(Parent, DIDescriptor(Scope),
|
||||
nullptr, false)).first;
|
||||
std::forward_as_tuple(Parent, Scope, nullptr,
|
||||
false)).first;
|
||||
|
||||
if (!Parent) {
|
||||
assert(DIDescriptor(Scope).isSubprogram());
|
||||
@ -170,19 +179,19 @@ LexicalScope *LexicalScopes::getOrCreateRegularScope(MDNode *Scope) {
|
||||
}
|
||||
|
||||
/// getOrCreateInlinedScope - Find or create an inlined lexical scope.
|
||||
LexicalScope *LexicalScopes::getOrCreateInlinedScope(MDNode *ScopeNode,
|
||||
MDNode *InlinedAt) {
|
||||
std::pair<const MDNode*, const MDNode*> P(ScopeNode, InlinedAt);
|
||||
LexicalScope *
|
||||
LexicalScopes::getOrCreateInlinedScope(const MDLocalScope *Scope,
|
||||
const MDLocation *InlinedAt) {
|
||||
std::pair<const MDLocalScope *, const MDLocation *> P(Scope, InlinedAt);
|
||||
auto I = InlinedLexicalScopeMap.find(P);
|
||||
if (I != InlinedLexicalScopeMap.end())
|
||||
return &I->second;
|
||||
|
||||
LexicalScope *Parent;
|
||||
DILexicalBlock Scope(ScopeNode);
|
||||
if (Scope.isSubprogram())
|
||||
Parent = getOrCreateLexicalScope(DebugLoc(InlinedAt));
|
||||
if (auto *Block = dyn_cast<MDLexicalBlockBase>(Scope))
|
||||
Parent = getOrCreateInlinedScope(Block->getScope(), InlinedAt);
|
||||
else
|
||||
Parent = getOrCreateInlinedScope(Scope.getContext(), InlinedAt);
|
||||
Parent = getOrCreateLexicalScope(InlinedAt);
|
||||
|
||||
I = InlinedLexicalScopeMap.emplace(std::piecewise_construct,
|
||||
std::forward_as_tuple(P),
|
||||
@ -193,27 +202,26 @@ LexicalScope *LexicalScopes::getOrCreateInlinedScope(MDNode *ScopeNode,
|
||||
}
|
||||
|
||||
/// getOrCreateAbstractScope - Find or create an abstract lexical scope.
|
||||
LexicalScope *LexicalScopes::getOrCreateAbstractScope(const MDNode *N) {
|
||||
assert(N && "Invalid Scope encoding!");
|
||||
LexicalScope *
|
||||
LexicalScopes::getOrCreateAbstractScope(const MDLocalScope *Scope) {
|
||||
assert(Scope && "Invalid Scope encoding!");
|
||||
|
||||
DIDescriptor Scope(N);
|
||||
if (Scope.isLexicalBlockFile())
|
||||
Scope = DILexicalBlockFile(Scope).getScope();
|
||||
if (auto *File = dyn_cast<MDLexicalBlockFile>(Scope))
|
||||
Scope = getScopeOfScope(File);
|
||||
auto I = AbstractScopeMap.find(Scope);
|
||||
if (I != AbstractScopeMap.end())
|
||||
return &I->second;
|
||||
|
||||
// FIXME: Should the following isa be MDLexicalBlock?
|
||||
LexicalScope *Parent = nullptr;
|
||||
if (Scope.isLexicalBlock()) {
|
||||
DILexicalBlock DB(Scope);
|
||||
DIDescriptor ParentDesc = DB.getContext();
|
||||
Parent = getOrCreateAbstractScope(ParentDesc);
|
||||
}
|
||||
if (auto *Block = dyn_cast<MDLexicalBlockBase>(Scope))
|
||||
Parent = getOrCreateAbstractScope(Block->getScope());
|
||||
|
||||
I = AbstractScopeMap.emplace(std::piecewise_construct,
|
||||
std::forward_as_tuple(Scope),
|
||||
std::forward_as_tuple(Parent, Scope,
|
||||
nullptr, true)).first;
|
||||
if (Scope.isSubprogram())
|
||||
if (isa<MDSubprogram>(Scope))
|
||||
AbstractScopesList.push_back(&I->second);
|
||||
return &I->second;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user