From b2bc86f25144aa907b977e27fd93e316e15500d6 Mon Sep 17 00:00:00 2001 From: Mehdi Amini Date: Tue, 8 Dec 2015 22:39:40 +0000 Subject: [PATCH] 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@255064 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Transforms/IPO/FunctionImport.h | 30 +++++------------- lib/Transforms/IPO/FunctionImport.cpp | 33 ++++++++------------ 2 files changed, 20 insertions(+), 43 deletions(-) diff --git a/include/llvm/Transforms/IPO/FunctionImport.h b/include/llvm/Transforms/IPO/FunctionImport.h index 0315c72811c..e3da8a79c23 100644 --- a/include/llvm/Transforms/IPO/FunctionImport.h +++ b/include/llvm/Transforms/IPO/FunctionImport.h @@ -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> 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 getLazyModule; + /// Factory function to load a Module for a given identifier + std::function(StringRef Identifier)> ModuleLoader; public: /// Create a Function Importer. - FunctionImporter(const FunctionInfoIndex &Index, - DiagnosticHandlerFunction DiagnosticHandler, - std::function ModuleLoader) + FunctionImporter( + const FunctionInfoIndex &Index, + DiagnosticHandlerFunction DiagnosticHandler, + std::function(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); diff --git a/lib/Transforms/IPO/FunctionImport.cpp b/lib/Transforms/IPO/FunctionImport.cpp index 67d77adb650..48d6e40f8b9 100644 --- a/lib/Transforms/IPO/FunctionImport.cpp +++ b/lib/Transforms/IPO/FunctionImport.cpp @@ -50,14 +50,6 @@ static std::unique_ptr 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 &Worklist, StringSet<> &CalledFunctions, Linker &TheLinker, const FunctionInfoIndex &Index, - std::function &LazyModuleLoader) { + std::function(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 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 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; -- 2.34.1