aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
diff options
context:
space:
mode:
authorVladislav Dzhidzhoev <vdzhidzhoev@accesssoftek.com>2023-07-18 14:22:46 +0200
committerVladislav Dzhidzhoev <vdzhidzhoev@accesssoftek.com>2023-11-02 17:44:52 +0100
commit3b449bd46a11a55a40cbc0016a99b202fa05248e (patch)
tree2f43becc4e0cd830b15db5c075ff5b9c6a378610 /llvm/lib/Bitcode/Reader/MetadataLoader.cpp
parent98bd0d9dd2da0edec15b5eb7acb480c47c4594cc (diff)
downloadllvm-3b449bd46a11a55a40cbc0016a99b202fa05248e.zip
llvm-3b449bd46a11a55a40cbc0016a99b202fa05248e.tar.gz
llvm-3b449bd46a11a55a40cbc0016a99b202fa05248e.tar.bz2
[DebugMetadata][DwarfDebug] Support function-local types in lexical block scopes (4/7)
RFC https://discourse.llvm.org/t/rfc-dwarfdebug-fix-and-improve-handling-imported-entities-types-and-static-local-in-subprogram-and-lexical-block-scopes/68544 Similar to imported declarations, the patch tracks function-local types in DISubprogram's 'retainedNodes' field. DwarfDebug is adjusted in accordance with the aforementioned metadata change and provided a support of function-local types scoped within a lexical block. The patch assumes that DICompileUnit's 'enums field' no longer tracks local types and DwarfDebug would assert if any locally-scoped types get placed there. Reviewed By: jmmartinez Authored-by: Kristina Bessonova <kbessonova@accesssoftek.com> Differential Revision: https://reviews.llvm.org/D144006
Diffstat (limited to 'llvm/lib/Bitcode/Reader/MetadataLoader.cpp')
-rw-r--r--llvm/lib/Bitcode/Reader/MetadataLoader.cpp111
1 files changed, 78 insertions, 33 deletions
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
index 1a4b55e..963bc6b 100644
--- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -547,6 +547,8 @@ class MetadataLoader::MetadataLoaderImpl {
/// Move local imports from DICompileUnit's 'imports' field to
/// DISubprogram's retainedNodes.
+ /// Move fucntion-local enums from DICompileUnit's enums
+ /// to DISubprogram's retainedNodes.
void upgradeCULocals() {
if (NamedMDNode *CUNodes = TheModule.getNamedMetadata("llvm.dbg.cu")) {
for (unsigned I = 0, E = CUNodes->getNumOperands(); I != E; ++I) {
@@ -554,48 +556,66 @@ class MetadataLoader::MetadataLoaderImpl {
if (!CU)
continue;
- if (CU->getRawImportedEntities()) {
- // Collect a set of imported entities to be moved.
- SetVector<Metadata *> EntitiesToRemove;
+ SetVector<Metadata *> MetadataToRemove;
+ // Collect imported entities to be moved.
+ if (CU->getRawImportedEntities())
for (Metadata *Op : CU->getImportedEntities()->operands()) {
auto *IE = cast<DIImportedEntity>(Op);
- if (dyn_cast_or_null<DILocalScope>(IE->getScope())) {
- EntitiesToRemove.insert(IE);
- }
+ if (dyn_cast_or_null<DILocalScope>(IE->getScope()))
+ MetadataToRemove.insert(IE);
+ }
+ // Collect enums to be moved.
+ if (CU->getRawEnumTypes())
+ for (Metadata *Op : CU->getEnumTypes()->operands()) {
+ auto *Enum = cast<DICompositeType>(Op);
+ if (dyn_cast_or_null<DILocalScope>(Enum->getScope()))
+ MetadataToRemove.insert(Enum);
}
- if (!EntitiesToRemove.empty()) {
- // Make a new list of CU's 'imports'.
- SmallVector<Metadata *> NewImports;
- for (Metadata *Op : CU->getImportedEntities()->operands()) {
- if (!EntitiesToRemove.contains(cast<DIImportedEntity>(Op))) {
+ if (!MetadataToRemove.empty()) {
+ // Make a new list of CU's 'imports'.
+ SmallVector<Metadata *> NewImports;
+ if (CU->getRawImportedEntities())
+ for (Metadata *Op : CU->getImportedEntities()->operands())
+ if (!MetadataToRemove.contains(Op))
NewImports.push_back(Op);
- }
- }
- // Find DISubprogram corresponding to each entity.
- std::map<DISubprogram *, SmallVector<Metadata *>> SPToEntities;
- for (auto *I : EntitiesToRemove) {
- auto *Entity = cast<DIImportedEntity>(I);
- if (auto *SP = findEnclosingSubprogram(
- cast<DILocalScope>(Entity->getScope()))) {
- SPToEntities[SP].push_back(Entity);
- }
- }
+ // Make a new list of CU's 'enums'.
+ SmallVector<Metadata *> NewEnums;
+ if (CU->getRawEnumTypes())
+ for (Metadata *Op : CU->getEnumTypes()->operands())
+ if (!MetadataToRemove.contains(Op))
+ NewEnums.push_back(Op);
+
+ // Find DISubprogram corresponding to each entity.
+ std::map<DISubprogram *, SmallVector<Metadata *>> SPToEntities;
+ for (auto *I : MetadataToRemove) {
+ DILocalScope *Scope = nullptr;
+ if (auto *Entity = dyn_cast<DIImportedEntity>(I))
+ Scope = cast<DILocalScope>(Entity->getScope());
+ else if (auto *Enum = dyn_cast<DICompositeType>(I))
+ Scope = cast<DILocalScope>(Enum->getScope());
+
+ if (auto *SP = findEnclosingSubprogram(Scope))
+ SPToEntities[SP].push_back(I);
+ }
- // Update DISubprograms' retainedNodes.
- for (auto I = SPToEntities.begin(); I != SPToEntities.end(); ++I) {
- auto *SP = I->first;
- auto RetainedNodes = SP->getRetainedNodes();
- SmallVector<Metadata *> MDs(RetainedNodes.begin(),
- RetainedNodes.end());
- MDs.append(I->second);
- SP->replaceRetainedNodes(MDNode::get(Context, MDs));
- }
+ // Update DISubprograms' retainedNodes.
+ for (auto I = SPToEntities.begin(); I != SPToEntities.end(); ++I) {
+ auto *SP = I->first;
+ auto RetainedNodes = SP->getRetainedNodes();
+ SmallVector<Metadata *> MDs(RetainedNodes.begin(),
+ RetainedNodes.end());
+ MDs.append(I->second);
+ SP->replaceRetainedNodes(MDNode::get(Context, MDs));
+ }
- // Remove entities with local scope from CU.
+ // Remove entities with local scope from CU.
+ if (CU->getRawImportedEntities())
CU->replaceImportedEntities(MDTuple::get(Context, NewImports));
- }
+ // Remove enums with local scope from CU.
+ if (CU->getRawEnumTypes())
+ CU->replaceEnumTypes(MDTuple::get(Context, NewEnums));
}
}
}
@@ -711,6 +731,29 @@ class MetadataLoader::MetadataLoaderImpl {
upgradeCULocals();
}
+ void cloneLocalTypes() {
+ for (unsigned I = 0; I < MetadataList.size(); ++I) {
+ if (auto *SP = dyn_cast_or_null<DISubprogram>(MetadataList[I])) {
+ auto RetainedNodes = SP->getRetainedNodes();
+ SmallVector<Metadata *> MDs(RetainedNodes.begin(), RetainedNodes.end());
+ bool HasChanged = false;
+ for (auto &N : MDs)
+ if (auto *T = dyn_cast<DIType>(N))
+ if (auto *LS = dyn_cast_or_null<DILocalScope>(T->getScope()))
+ if (auto *Parent = findEnclosingSubprogram(LS))
+ if (Parent != SP) {
+ HasChanged = true;
+ auto NewT = T->clone();
+ NewT->replaceOperandWith(1, SP);
+ N = MDNode::replaceWithUniqued(std::move(NewT));
+ }
+
+ if (HasChanged)
+ SP->replaceRetainedNodes(MDNode::get(Context, MDs));
+ }
+ }
+ }
+
void callMDTypeCallback(Metadata **Val, unsigned TypeID);
public:
@@ -1086,6 +1129,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) {
// placeholders, that we flush here.
resolveForwardRefsAndPlaceholders(Placeholders);
upgradeDebugInfo(ModuleLevel);
+ cloneLocalTypes();
// Return at the beginning of the block, since it is easy to skip it
// entirely from there.
Stream.ReadBlockEnd(); // Pop the abbrev block context.
@@ -1117,6 +1161,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) {
case BitstreamEntry::EndBlock:
resolveForwardRefsAndPlaceholders(Placeholders);
upgradeDebugInfo(ModuleLevel);
+ cloneLocalTypes();
return Error::success();
case BitstreamEntry::Record:
// The interesting case.