aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Linker/IRMover.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Linker/IRMover.cpp')
-rw-r--r--llvm/lib/Linker/IRMover.cpp63
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);
+ }
}
}