diff options
author | Vladislav Dzhidzhoev <vdzhidzhoev@accesssoftek.com> | 2024-01-11 17:08:12 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-11 17:08:12 +0100 |
commit | fc6faa1113e9069f41b5500db051210af0eea843 (patch) | |
tree | 105a76fe962bf21897f044fb563d7b5abd83a226 /llvm/lib/Bitcode/Reader/MetadataLoader.cpp | |
parent | 31ce0f1dda3caed829db09b9212eac54a8a28572 (diff) | |
download | llvm-fc6faa1113e9069f41b5500db051210af0eea843.zip llvm-fc6faa1113e9069f41b5500db051210af0eea843.tar.gz llvm-fc6faa1113e9069f41b5500db051210af0eea843.tar.bz2 |
[CloneFunction][DebugInfo] Avoid cloning DILocalVariables of inlined functions (#75385)
- [DebugMetadata][DwarfDebug] Support function-local types in lexical
block scopes (4/7)
- [CloneFunction][DebugInfo] Avoid cloning DILocalVariables of inlined
functions
This is a follow-up for https://reviews.llvm.org/D144006, fixing a crash
reported
in Chromium (https://reviews.llvm.org/D144006#4651955).
The first commit is added for convenience, as it has already been
accepted.
If DISubpogram was not cloned (e.g. we are cloning a function that has
other
functions inlined into it, and subprograms of the inlined functions are
not supposed to be cloned), it doesn't make sense to clone its
DILocalVariables as well.
Otherwise get duplicated DILocalVariables not tracked in their
subprogram's retainedNodes, that crash LTO with Chromium.
This is meant to be committed along with
https://reviews.llvm.org/D144006.
Diffstat (limited to 'llvm/lib/Bitcode/Reader/MetadataLoader.cpp')
-rw-r--r-- | llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 111 |
1 files changed, 78 insertions, 33 deletions
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index 910e974..d118695 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. |