aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-09-02 21:17:18 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-12-08 17:34:50 +0000
commit06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e (patch)
tree62f873df87c7c675557a179e0c4c83fe9f3087bc /contrib/llvm-project/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
parentcf037972ea8863e2bab7461d77345367d2c1e054 (diff)
parent7fa27ce4a07f19b07799a767fc29416f3b625afb (diff)
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Bitcode/Reader/MetadataLoader.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Bitcode/Reader/MetadataLoader.cpp84
1 files changed, 84 insertions, 0 deletions
diff --git a/contrib/llvm-project/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/contrib/llvm-project/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
index 4b5cfedaa99c..0a9a80688a41 100644
--- a/contrib/llvm-project/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/contrib/llvm-project/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -15,6 +15,7 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLFunctionalExtras.h"
+#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
@@ -53,6 +54,7 @@
#include <deque>
#include <iterator>
#include <limits>
+#include <map>
#include <optional>
#include <string>
#include <tuple>
@@ -463,6 +465,9 @@ class MetadataLoader::MetadataLoaderImpl {
bool NeedUpgradeToDIGlobalVariableExpression = false;
bool NeedDeclareExpressionUpgrade = false;
+ /// Map DILocalScope to the enclosing DISubprogram, if any.
+ DenseMap<DILocalScope *, DISubprogram *> ParentSubprogram;
+
/// True if metadata is being parsed for a module being ThinLTO imported.
bool IsImporting = false;
@@ -521,6 +526,84 @@ class MetadataLoader::MetadataLoaderImpl {
}
}
+ DISubprogram *findEnclosingSubprogram(DILocalScope *S) {
+ if (!S)
+ return nullptr;
+ if (auto *SP = ParentSubprogram[S]) {
+ return SP;
+ }
+
+ DILocalScope *InitialScope = S;
+ DenseSet<DILocalScope *> Visited;
+ while (S && !isa<DISubprogram>(S)) {
+ S = dyn_cast_or_null<DILocalScope>(S->getScope());
+ if (Visited.contains(S))
+ break;
+ Visited.insert(S);
+ }
+ ParentSubprogram[InitialScope] = llvm::dyn_cast_or_null<DISubprogram>(S);
+
+ return ParentSubprogram[InitialScope];
+ }
+
+ /// Move local imports from DICompileUnit's 'imports' field to
+ /// DISubprogram's retainedNodes.
+ void upgradeCULocals() {
+ if (NamedMDNode *CUNodes = TheModule.getNamedMetadata("llvm.dbg.cu")) {
+ for (unsigned I = 0, E = CUNodes->getNumOperands(); I != E; ++I) {
+ auto *CU = dyn_cast<DICompileUnit>(CUNodes->getOperand(I));
+ if (!CU)
+ continue;
+
+ if (auto *RawImported = CU->getRawImportedEntities()) {
+ // Collect a set of imported entities to be moved.
+ SetVector<Metadata *> EntitiesToRemove;
+ for (Metadata *Op : CU->getImportedEntities()->operands()) {
+ auto *IE = cast<DIImportedEntity>(Op);
+ if (auto *S = dyn_cast_or_null<DILocalScope>(IE->getScope())) {
+ EntitiesToRemove.insert(IE);
+ }
+ }
+
+ 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))) {
+ 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);
+ }
+ }
+
+ // 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.
+ CU->replaceImportedEntities(MDTuple::get(Context, NewImports));
+ }
+ }
+ }
+ }
+
+ ParentSubprogram.clear();
+ }
+
/// Remove a leading DW_OP_deref from DIExpressions in a dbg.declare that
/// describes a function argument.
void upgradeDeclareExpressions(Function &F) {
@@ -625,6 +708,7 @@ class MetadataLoader::MetadataLoaderImpl {
void upgradeDebugInfo() {
upgradeCUSubprograms();
upgradeCUVariables();
+ upgradeCULocals();
}
void callMDTypeCallback(Metadata **Val, unsigned TypeID);