summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/IR/GlobalObject.h3
-rw-r--r--llvm/lib/IR/Metadata.cpp7
-rw-r--r--llvm/lib/Linker/IRMover.cpp11
-rw-r--r--llvm/test/Linker/metadata-attach.ll19
4 files changed, 36 insertions, 4 deletions
diff --git a/llvm/include/llvm/IR/GlobalObject.h b/llvm/include/llvm/IR/GlobalObject.h
index 8c494cf3bc9..6414ca5b147 100644
--- a/llvm/include/llvm/IR/GlobalObject.h
+++ b/llvm/include/llvm/IR/GlobalObject.h
@@ -114,6 +114,9 @@ public:
/// Erase all metadata attachments with the given kind.
void eraseMetadata(unsigned KindID);
+ /// Copy metadata from Src.
+ void copyMetadata(const GlobalObject *Src);
+
void copyAttributesFrom(const GlobalValue *Src) override;
// Methods for support type inquiry through isa, cast, and dyn_cast:
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index 5d84bb75cfb..3b5f87a2b40 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -1393,6 +1393,13 @@ MDNode *GlobalObject::getMetadata(StringRef Kind) const {
return getMetadata(getContext().getMDKindID(Kind));
}
+void GlobalObject::copyMetadata(const GlobalObject *Other) {
+ SmallVector<std::pair<unsigned, MDNode *>, 8> MDs;
+ Other->getAllMetadata(MDs);
+ for (auto &MD : MDs)
+ addMetadata(MD.first, *MD.second);
+}
+
void Function::setSubprogram(DISubprogram *SP) {
setMetadata(LLVMContext::MD_dbg, SP);
}
diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp
index c82fc8b3dff..2f3813f6184 100644
--- a/llvm/lib/Linker/IRMover.cpp
+++ b/llvm/lib/Linker/IRMover.cpp
@@ -638,6 +638,12 @@ GlobalValue *IRLinker::copyGlobalValueProto(const GlobalValue *SGV,
NewGV->copyAttributesFrom(SGV);
+ if (auto *NewGO = dyn_cast<GlobalObject>(NewGV)) {
+ // Metadata for global variables and function declarations is copied eagerly.
+ if (isa<GlobalVariable>(SGV) || SGV->isDeclaration())
+ NewGO->copyMetadata(cast<GlobalObject>(SGV));
+ }
+
// Remove these copied constants in case this stays a declaration, since
// they point to the source module. If the def is linked the values will
// be mapped in during linkFunctionBody.
@@ -961,10 +967,7 @@ Error IRLinker::linkFunctionBody(Function &Dst, Function &Src) {
Dst.setPersonalityFn(Src.getPersonalityFn());
// Copy over the metadata attachments without remapping.
- SmallVector<std::pair<unsigned, MDNode *>, 8> MDs;
- Src.getAllMetadata(MDs);
- for (const auto &I : MDs)
- Dst.setMetadata(I.first, I.second);
+ Dst.copyMetadata(&Src);
// Steal arguments and splice the body of Src into Dst.
Dst.stealArgumentListFrom(Src);
diff --git a/llvm/test/Linker/metadata-attach.ll b/llvm/test/Linker/metadata-attach.ll
new file mode 100644
index 00000000000..eac1dc378f9
--- /dev/null
+++ b/llvm/test/Linker/metadata-attach.ll
@@ -0,0 +1,19 @@
+; RUN: llvm-link %s -S -o - | FileCheck %s
+
+; CHECK: @g1 = global i32 0, !attach !0
+@g1 = global i32 0, !attach !0
+
+; CHECK: @g2 = external global i32, !attach !0
+@g2 = external global i32, !attach !0
+
+; CHECK: define void @f1() !attach !0
+define void @f1() !attach !0 {
+ call void @f2()
+ store i32 0, i32* @g2
+ ret void
+}
+
+; CHECK: declare !attach !0 void @f2()
+declare !attach !0 void @f2()
+
+!0 = !{}
OpenPOWER on IntegriCloud