From be0ef4b95d947a324aaf58373691723a0307822b Mon Sep 17 00:00:00 2001 From: Carl Ritson Date: Wed, 8 Mar 2023 15:28:53 +0900 Subject: [PATCH] [IRLinker] Fix mapping of declaration metadata Ensure metadata for declarations copied during materialization is properly mapped if declarations do not become definitions. Reviewed By: tejohnson Differential Revision: https://reviews.llvm.org/D145318 --- llvm/include/llvm/Transforms/Utils/ValueMapper.h | 6 ++++-- llvm/lib/Linker/IRMover.cpp | 16 +++++++++++++++- llvm/lib/Transforms/Utils/ValueMapper.cpp | 4 ++++ llvm/test/Linker/Inputs/metadata-function.ll | 9 +++++++++ llvm/test/Linker/metadata-function.ll | 9 +++++++++ 5 files changed, 41 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/Transforms/Utils/ValueMapper.h b/llvm/include/llvm/Transforms/Utils/ValueMapper.h index 95fd0b1..5f15af7 100644 --- a/llvm/include/llvm/Transforms/Utils/ValueMapper.h +++ b/llvm/include/llvm/Transforms/Utils/ValueMapper.h @@ -112,8 +112,9 @@ inline RemapFlags operator|(RemapFlags LHS, RemapFlags RHS) { /// There are a number of top-level entry points: /// - \a mapValue() (and \a mapConstant()); /// - \a mapMetadata() (and \a mapMDNode()); -/// - \a remapInstruction(); and -/// - \a remapFunction(). +/// - \a remapInstruction(); +/// - \a remapFunction(); and +/// - \a remapGlobalObjectMetadata(). /// /// The \a ValueMaterializer can be used as a callback, but cannot invoke any /// of these top-level functions recursively. Instead, callbacks should use @@ -175,6 +176,7 @@ public: void remapInstruction(Instruction &I); void remapFunction(Function &F); + void remapGlobalObjectMetadata(GlobalObject &GO); void scheduleMapGlobalInitializer(GlobalVariable &GV, Constant &Init, unsigned MappingContextID = 0); diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp index 721acb1..08a82c1 100644 --- a/llvm/lib/Linker/IRMover.cpp +++ b/llvm/lib/Linker/IRMover.cpp @@ -409,6 +409,10 @@ class IRLinker { std::vector Worklist; std::vector> RAUWWorklist; + /// Set of globals with eagerly copied metadata that may require remapping. + /// This remapping is performed after metadata linking. + DenseSet UnmappedMetadata; + void maybeAdd(GlobalValue *GV) { if (ValuesToLink.insert(GV).second) Worklist.push_back(GV); @@ -750,8 +754,11 @@ GlobalValue *IRLinker::copyGlobalValueProto(const GlobalValue *SGV, if (auto *NewGO = dyn_cast(NewGV)) { // Metadata for global variables and function declarations is copied eagerly. - if (isa(SGV) || SGV->isDeclaration()) + if (isa(SGV) || SGV->isDeclaration()) { NewGO->copyMetadata(cast(SGV), 0); + if (SGV->isDeclaration()) + UnmappedMetadata.insert(NewGO); + } } // Remove these copied constants in case this stays a declaration, since @@ -1651,6 +1658,13 @@ Error IRLinker::run() { // are properly remapped. linkNamedMDNodes(); + // Clean up any global objects with potentially unmapped metadata. + // Specifically declarations which did not become definitions. + for (GlobalObject *NGO : UnmappedMetadata) { + if (NGO->isDeclaration()) + Mapper.remapGlobalObjectMetadata(*NGO); + } + if (!IsPerformingImport && !SrcM->getModuleInlineAsm().empty()) { // Append the module inline asm string. DstM.appendModuleInlineAsm(adjustInlineAsm(SrcM->getModuleInlineAsm(), diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp index 2a7aba0..6fd6087 100644 --- a/llvm/lib/Transforms/Utils/ValueMapper.cpp +++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp @@ -1181,6 +1181,10 @@ void ValueMapper::remapFunction(Function &F) { FlushingMapper(pImpl)->remapFunction(F); } +void ValueMapper::remapGlobalObjectMetadata(GlobalObject &GO) { + FlushingMapper(pImpl)->remapGlobalObjectMetadata(GO); +} + void ValueMapper::scheduleMapGlobalInitializer(GlobalVariable &GV, Constant &Init, unsigned MCID) { diff --git a/llvm/test/Linker/Inputs/metadata-function.ll b/llvm/test/Linker/Inputs/metadata-function.ll index 8572ff1..4109c57 100644 --- a/llvm/test/Linker/Inputs/metadata-function.ll +++ b/llvm/test/Linker/Inputs/metadata-function.ll @@ -10,4 +10,13 @@ define void @b() !b !0 { unreachable } +%AltHandle = type { i8* } +declare !types !1 %AltHandle @init.AltHandle() + +define void @uses.AltHandle() { + %.res = call %AltHandle @init.AltHandle() + unreachable +} + !0 = !{!"b"} +!1 = !{%AltHandle undef} diff --git a/llvm/test/Linker/metadata-function.ll b/llvm/test/Linker/metadata-function.ll index 0b17e0c..3fe3b52 100644 --- a/llvm/test/Linker/metadata-function.ll +++ b/llvm/test/Linker/metadata-function.ll @@ -21,6 +21,15 @@ define void @a() !a !0 { unreachable } +; CHECK-DAG: define %[[HandleType:[A-Za-z]+]] @init.Handle() { +; CHECK-DAG: declare !types ![[C:[0-9]+]] %[[HandleType]] @init.AltHandle() +; CHECK-DAG: define void @uses.AltHandle() { +%Handle = type { i8* } +define %Handle @init.Handle() { + unreachable +} + ; CHECK-DAG: ![[A]] = !{!"a"} ; CHECK-DAG: ![[B]] = !{!"b"} +; CHECK-DAG: ![[C]] = !{%[[HandleType]] undef} !0 = !{!"a"} -- 2.7.4