forked from OSchip/llvm-project
Remove caching in FunctionImport: a Module can't be reused after being linked from
The Linker destroys the source module (API change coming to make it explicit) From: Mehdi Amini <mehdi.amini@apple.com> llvm-svn: 255064
This commit is contained in:
parent
e18f92bfe9
commit
d16c8065ff
|
@ -18,23 +18,6 @@ class LLVMContext;
|
|||
class Module;
|
||||
class FunctionInfoIndex;
|
||||
|
||||
/// Helper to load on demand a Module from file and cache it for subsequent
|
||||
/// queries. It can be used with the FunctionImporter.
|
||||
class ModuleLazyLoaderCache {
|
||||
/// The context that will be used for importing.
|
||||
LLVMContext &Context;
|
||||
|
||||
/// Cache of lazily loaded module for import.
|
||||
StringMap<std::unique_ptr<Module>> ModuleMap;
|
||||
|
||||
public:
|
||||
/// Create the loader, Module will be initialized in \p Context.
|
||||
ModuleLazyLoaderCache(LLVMContext &Context) : Context(Context) {}
|
||||
|
||||
/// Retrieve a Module from the cache or lazily load it on demand.
|
||||
Module &operator()(StringRef FileName);
|
||||
};
|
||||
|
||||
/// The function importer is automatically importing function from other modules
|
||||
/// based on the provided summary informations.
|
||||
class FunctionImporter {
|
||||
|
@ -45,16 +28,17 @@ class FunctionImporter {
|
|||
/// Diagnostic will be sent to this handler.
|
||||
DiagnosticHandlerFunction DiagnosticHandler;
|
||||
|
||||
/// Retrieve a Module from the cache or lazily load it on demand.
|
||||
std::function<Module &(StringRef FileName)> getLazyModule;
|
||||
/// Factory function to load a Module for a given identifier
|
||||
std::function<std::unique_ptr<Module>(StringRef Identifier)> ModuleLoader;
|
||||
|
||||
public:
|
||||
/// Create a Function Importer.
|
||||
FunctionImporter(const FunctionInfoIndex &Index,
|
||||
DiagnosticHandlerFunction DiagnosticHandler,
|
||||
std::function<Module &(StringRef FileName)> ModuleLoader)
|
||||
FunctionImporter(
|
||||
const FunctionInfoIndex &Index,
|
||||
DiagnosticHandlerFunction DiagnosticHandler,
|
||||
std::function<std::unique_ptr<Module>(StringRef Identifier)> ModuleLoader)
|
||||
: Index(Index), DiagnosticHandler(DiagnosticHandler),
|
||||
getLazyModule(ModuleLoader) {}
|
||||
ModuleLoader(ModuleLoader) {}
|
||||
|
||||
/// Import functions in Module \p M based on the summary informations.
|
||||
bool importFunctions(Module &M);
|
||||
|
|
|
@ -50,14 +50,6 @@ static std::unique_ptr<Module> loadFile(const std::string &FileName,
|
|||
return Result;
|
||||
}
|
||||
|
||||
// Get a Module for \p FileName from the cache, or load it lazily.
|
||||
Module &ModuleLazyLoaderCache::operator()(StringRef FileName) {
|
||||
auto &Module = ModuleMap[FileName];
|
||||
if (!Module)
|
||||
Module = loadFile(FileName, Context);
|
||||
return *Module;
|
||||
}
|
||||
|
||||
/// Walk through the instructions in \p F looking for external
|
||||
/// calls not already in the \p CalledFunctions set. If any are
|
||||
/// found they are added to the \p Worklist for importing.
|
||||
|
@ -86,7 +78,8 @@ static unsigned ProcessImportWorklist(
|
|||
Module &DestModule, SmallVector<StringRef, 64> &Worklist,
|
||||
StringSet<> &CalledFunctions, Linker &TheLinker,
|
||||
const FunctionInfoIndex &Index,
|
||||
std::function<Module &(StringRef FileName)> &LazyModuleLoader) {
|
||||
std::function<std::unique_ptr<Module>(StringRef FileName)> &
|
||||
LazyModuleLoader) {
|
||||
unsigned ImportCount = 0;
|
||||
while (!Worklist.empty()) {
|
||||
auto CalledFunctionName = Worklist.pop_back_val();
|
||||
|
@ -125,18 +118,18 @@ static unsigned ProcessImportWorklist(
|
|||
DEBUG(dbgs() << "Importing " << CalledFunctionName << " from " << FileName
|
||||
<< "\n");
|
||||
|
||||
// Get the module for the import (potentially from the cache).
|
||||
auto &Module = LazyModuleLoader(FileName);
|
||||
assert(&Module.getContext() == &DestModule.getContext());
|
||||
// Get the module for the import
|
||||
auto SrcModule = LazyModuleLoader(FileName);
|
||||
assert(&SrcModule->getContext() == &DestModule.getContext());
|
||||
|
||||
// The function that we will import!
|
||||
GlobalValue *SGV = Module.getNamedValue(CalledFunctionName);
|
||||
GlobalValue *SGV = SrcModule->getNamedValue(CalledFunctionName);
|
||||
StringRef ImportFunctionName = CalledFunctionName;
|
||||
if (!SGV) {
|
||||
// Might be local in source Module, promoted/renamed in DestModule.
|
||||
std::pair<StringRef, StringRef> Split =
|
||||
CalledFunctionName.split(".llvm.");
|
||||
SGV = Module.getNamedValue(Split.first);
|
||||
SGV = SrcModule->getNamedValue(Split.first);
|
||||
#ifndef NDEBUG
|
||||
// Assert that Split.second is module id
|
||||
uint64_t ModuleId;
|
||||
|
@ -169,7 +162,7 @@ static unsigned ProcessImportWorklist(
|
|||
// Link in the specified function.
|
||||
DenseSet<const GlobalValue *> FunctionsToImport;
|
||||
FunctionsToImport.insert(F);
|
||||
if (TheLinker.linkInModule(Module, Linker::Flags::None, &Index,
|
||||
if (TheLinker.linkInModule(*SrcModule, Linker::Flags::None, &Index,
|
||||
&FunctionsToImport))
|
||||
report_fatal_error("Function Import: link error");
|
||||
|
||||
|
@ -211,7 +204,7 @@ bool FunctionImporter::importFunctions(Module &DestModule) {
|
|||
Linker TheLinker(DestModule, DiagnosticHandler);
|
||||
|
||||
ImportedCount += ProcessImportWorklist(DestModule, Worklist, CalledFunctions,
|
||||
TheLinker, Index, getLazyModule);
|
||||
TheLinker, Index, ModuleLoader);
|
||||
|
||||
DEBUG(errs() << "Imported " << ImportedCount << " functions for Module "
|
||||
<< DestModule.getModuleIdentifier() << "\n");
|
||||
|
@ -291,10 +284,10 @@ public:
|
|||
}
|
||||
|
||||
// Perform the import now.
|
||||
ModuleLazyLoaderCache Loader(M.getContext());
|
||||
FunctionImporter Importer(*Index, diagnosticHandler,
|
||||
[&](StringRef Name)
|
||||
-> Module &{ return Loader(Name); });
|
||||
auto ModuleLoader = [&M](StringRef Identifier) {
|
||||
return loadFile(Identifier, M.getContext());
|
||||
};
|
||||
FunctionImporter Importer(*Index, diagnosticHandler, ModuleLoader);
|
||||
return Importer.importFunctions(M);
|
||||
|
||||
return false;
|
||||
|
|
Loading…
Reference in New Issue