diff options
| -rw-r--r-- | llvm/include/llvm/IR/GlobalObject.h | 3 | ||||
| -rw-r--r-- | llvm/lib/IR/Metadata.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/Linker/IRMover.cpp | 11 | ||||
| -rw-r--r-- | llvm/test/Linker/metadata-attach.ll | 19 |
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 = !{} |

