diff options
Diffstat (limited to 'llvm/lib/Linker/IRMover.cpp')
-rw-r--r-- | llvm/lib/Linker/IRMover.cpp | 63 |
1 files changed, 25 insertions, 38 deletions
diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp index 517e2dc8ebe0..df090c5990e6 100644 --- a/llvm/lib/Linker/IRMover.cpp +++ b/llvm/lib/Linker/IRMover.cpp @@ -11,7 +11,6 @@ #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" -#include "llvm/ADT/Triple.h" #include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfoMetadata.h" @@ -28,6 +27,7 @@ #include "llvm/Object/ModuleSymbolTable.h" #include "llvm/Support/Error.h" #include "llvm/Support/Path.h" +#include "llvm/TargetParser/Triple.h" #include "llvm/Transforms/Utils/ValueMapper.h" #include <optional> #include <utility> @@ -409,6 +409,10 @@ class IRLinker { std::vector<GlobalValue *> Worklist; std::vector<std::pair<GlobalValue *, Value*>> RAUWWorklist; + /// Set of globals with eagerly copied metadata that may require remapping. + /// This remapping is performed after metadata linking. + DenseSet<GlobalObject *> 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<GlobalObject>(NewGV)) { // Metadata for global variables and function declarations is copied eagerly. - if (isa<GlobalVariable>(SGV) || SGV->isDeclaration()) + if (isa<GlobalVariable>(SGV) || SGV->isDeclaration()) { NewGO->copyMetadata(cast<GlobalObject>(SGV), 0); + if (SGV->isDeclaration() && NewGO->hasMetadata()) + UnmappedMetadata.insert(NewGO); + } } // Remove these copied constants in case this stays a declaration, since @@ -1056,6 +1063,10 @@ Expected<Constant *> IRLinker::linkGlobalValueProto(GlobalValue *SGV, // as well. if (Function *F = dyn_cast<Function>(NewGV)) if (auto Remangled = Intrinsic::remangleIntrinsicFunction(F)) { + // Note: remangleIntrinsicFunction does not copy metadata and as such + // F should not occur in the set of objects with unmapped metadata. + // If this assertion fails then remangleIntrinsicFunction needs updating. + assert(!UnmappedMetadata.count(F) && "intrinsic has unmapped metadata"); NewGV->eraseFromParent(); NewGV = *Remangled; NeedsRenaming = false; @@ -1200,39 +1211,7 @@ void IRLinker::prepareCompileUnitsForImport() { // size inefficient. CU->replaceGlobalVariables(nullptr); - // Imported entities only need to be mapped in if they have local - // scope, as those might correspond to an imported entity inside a - // function being imported (any locally scoped imported entities that - // don't end up referenced by an imported function will not be emitted - // into the object). Imported entities not in a local scope - // (e.g. on the namespace) only need to be emitted by the originating - // module. Create a list of the locally scoped imported entities, and - // replace the source CUs imported entity list with the new list, so - // only those are mapped in. - // FIXME: Locally-scoped imported entities could be moved to the - // functions they are local to instead of listing them on the CU, and - // we would naturally only link in those needed by function importing. - SmallVector<TrackingMDNodeRef, 4> AllImportedModules; - bool ReplaceImportedEntities = false; - for (auto *IE : CU->getImportedEntities()) { - DIScope *Scope = IE->getScope(); - assert(Scope && "Invalid Scope encoding!"); - if (isa<DILocalScope>(Scope)) - AllImportedModules.emplace_back(IE); - else - ReplaceImportedEntities = true; - } - if (ReplaceImportedEntities) { - if (!AllImportedModules.empty()) - CU->replaceImportedEntities(MDTuple::get( - CU->getContext(), - SmallVector<Metadata *, 16>(AllImportedModules.begin(), - AllImportedModules.end()))); - else - // If there were no local scope imported entities, we can map - // the whole list to nullptr. - CU->replaceImportedEntities(nullptr); - } + CU->replaceImportedEntities(nullptr); } } @@ -1651,6 +1630,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(), @@ -1671,15 +1657,16 @@ Error IRLinker::run() { // Reorder the globals just added to the destination module to match their // original order in the source module. - Module::GlobalListType &Globals = DstM.getGlobalList(); for (GlobalVariable &GV : SrcM->globals()) { if (GV.hasAppendingLinkage()) continue; Value *NewValue = Mapper.mapValue(GV); if (NewValue) { auto *NewGV = dyn_cast<GlobalVariable>(NewValue->stripPointerCasts()); - if (NewGV) - Globals.splice(Globals.end(), Globals, NewGV->getIterator()); + if (NewGV) { + NewGV->removeFromParent(); + DstM.insertGlobalVariable(NewGV); + } } } |