/// as part of a different backend compilation process.
bool HasExportedFunctions = false;
+ /// Association between metadata value id and temporary metadata that
+ /// remains unmapped after function importing. Saved during function
+ /// importing and consumed during the metadata linking postpass.
+ DenseMap<unsigned, MDNode *> *ValIDToTempMDMap;
+
/// Used as the callback for lazy linking.
/// The mover has just hit GV and we have to decide if it, and other members
/// of the same comdat, should be linked. Every member to be linked is passed
/// Helper methods to check if we are importing from or potentially
/// exporting from the current source module.
- bool isPerformingImport() { return ImportFunction != nullptr; }
- bool isModuleExporting() { return HasExportedFunctions; }
+ bool isPerformingImport() const { return ImportFunction != nullptr; }
+ bool isModuleExporting() const { return HasExportedFunctions; }
/// If we are importing from the source module, checks if we should
/// import SGV as a definition, otherwise import as a declaration.
public:
ModuleLinker(IRMover &Mover, Module &SrcM, unsigned Flags,
const FunctionInfoIndex *Index = nullptr,
- DenseSet<const GlobalValue *> *FunctionsToImport = nullptr)
+ DenseSet<const GlobalValue *> *FunctionsToImport = nullptr,
+ DenseMap<unsigned, MDNode *> *ValIDToTempMDMap = nullptr)
: Mover(Mover), SrcM(SrcM), Flags(Flags), ImportIndex(Index),
- ImportFunction(FunctionsToImport) {
+ ImportFunction(FunctionsToImport), ValIDToTempMDMap(ValIDToTempMDMap) {
assert((ImportIndex || !ImportFunction) &&
"Expect a FunctionInfoIndex when importing");
// If we have a FunctionInfoIndex but no function to import,
// may be exported to another backend compilation.
if (ImportIndex && !ImportFunction)
HasExportedFunctions = ImportIndex->hasExportedFunctions(SrcM);
+ assert((ValIDToTempMDMap || !ImportFunction) &&
+ "Function importing must provide a ValIDToTempMDMap");
}
bool run();
bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc,
const GlobalValue &Dest,
const GlobalValue &Src) {
+
// Should we unconditionally use the Src?
if (shouldOverrideFromSrc()) {
LinkFromSrc = true;
if (Mover.move(SrcM, ValuesToLink.getArrayRef(),
[this](GlobalValue &GV, IRMover::ValueAdder Add) {
addLazyFor(GV, Add);
- }))
+ },
+ ValIDToTempMDMap, false))
return true;
Module &DstM = Mover.getModule();
for (auto &P : Internalize) {
Linker::Linker(Module &M) : Mover(M) {}
-bool Linker::linkInModule(Module &Src, unsigned Flags,
+bool Linker::linkInModule(std::unique_ptr<Module> Src, unsigned Flags,
const FunctionInfoIndex *Index,
- DenseSet<const GlobalValue *> *FunctionsToImport) {
- ModuleLinker TheLinker(Mover, Src, Flags, Index, FunctionsToImport);
- return TheLinker.run();
+ DenseSet<const GlobalValue *> *FunctionsToImport,
+ DenseMap<unsigned, MDNode *> *ValIDToTempMDMap) {
+ ModuleLinker ModLinker(Mover, *Src, Flags, Index, FunctionsToImport,
+ ValIDToTempMDMap);
+ return ModLinker.run();
+}
+
+bool Linker::linkInModuleForCAPI(Module &Src) {
+ ModuleLinker ModLinker(Mover, Src, 0, nullptr, nullptr);
+ return ModLinker.run();
+}
+
+bool Linker::linkInMetadata(Module &Src,
+ DenseMap<unsigned, MDNode *> *ValIDToTempMDMap) {
+ SetVector<GlobalValue *> ValuesToLink;
+ if (Mover.move(
+ Src, ValuesToLink.getArrayRef(),
+ [this](GlobalValue &GV, IRMover::ValueAdder Add) { assert(false); },
+ ValIDToTempMDMap, true))
+ return true;
+ return false;
}
//===----------------------------------------------------------------------===//
/// true is returned and ErrorMsg (if not null) is set to indicate the problem.
/// Upon failure, the Dest module could be in a modified state, and shouldn't be
/// relied on to be consistent.
-bool Linker::linkModules(Module &Dest, Module &Src, unsigned Flags) {
+bool Linker::linkModules(Module &Dest, std::unique_ptr<Module> Src,
+ unsigned Flags) {
Linker L(Dest);
- return L.linkInModule(Src, Flags);
+ return L.linkInModule(std::move(Src), Flags);
}
std::unique_ptr<Module>
-llvm::renameModuleForThinLTO(std::unique_ptr<Module> &M,
+llvm::renameModuleForThinLTO(std::unique_ptr<Module> M,
const FunctionInfoIndex *Index) {
std::unique_ptr<llvm::Module> RenamedModule(
new llvm::Module(M->getModuleIdentifier(), M->getContext()));
Linker L(*RenamedModule.get());
- if (L.linkInModule(*M.get(), llvm::Linker::Flags::None, Index))
+ if (L.linkInModule(std::move(M), llvm::Linker::Flags::None, Index))
return nullptr;
return RenamedModule;
}
std::string Message;
Ctx.setDiagnosticHandler(diagnosticHandler, &Message, true);
- LLVMBool Result = Linker::linkModules(*D, *unwrap(Src));
+ Linker L(*D);
+ Module *M = unwrap(Src);
+ LLVMBool Result = L.linkInModuleForCAPI(*M);
Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext, true);
*OutMessages = strdup(Message.c_str());
return Result;
}
+
+LLVMBool LLVMLinkModules2(LLVMModuleRef Dest, LLVMModuleRef Src) {
+ Module *D = unwrap(Dest);
+ std::unique_ptr<Module> M(unwrap(Src));
+ return Linker::linkModules(*D, std::move(M));
+}