Index: include/llvm/LinkAllPasses.h =================================================================== --- include/llvm/LinkAllPasses.h +++ include/llvm/LinkAllPasses.h @@ -86,6 +86,7 @@ (void) llvm::createDomViewerPass(); (void) llvm::createGCOVProfilerPass(); (void) llvm::createInstrProfilingPass(); + (void) llvm::createFunctionImportPass(std::string()); (void) llvm::createFunctionInliningPass(); (void) llvm::createAlwaysInlinerPass(); (void) llvm::createGlobalDCEPass(); Index: include/llvm/Linker/Linker.h =================================================================== --- include/llvm/Linker/Linker.h +++ include/llvm/Linker/Linker.h @@ -90,10 +90,12 @@ static bool LinkModules(Module *Dest, Module *Src, DiagnosticHandlerFunction DiagnosticHandler, - unsigned Flags = Flags::None); + unsigned Flags = Flags::None, + FunctionInfoIndex *Index = nullptr); static bool LinkModules(Module *Dest, Module *Src, - unsigned Flags = Flags::None); + unsigned Flags = Flags::None, + FunctionInfoIndex *Index = nullptr); private: void init(Module *M, DiagnosticHandlerFunction DiagnosticHandler); Index: include/llvm/Transforms/IPO.h =================================================================== --- include/llvm/Transforms/IPO.h +++ include/llvm/Transforms/IPO.h @@ -85,6 +85,8 @@ ModulePass *createGVExtractionPass(std::vector& GVs, bool deleteFn = false); +ModulePass *createFunctionImportPass(StringRef IndexFile); + //===----------------------------------------------------------------------===// /// createFunctionInliningPass - Return a new pass object that uses a heuristic /// to inline direct function calls to small functions. Index: include/llvm/Transforms/IPO/PassManagerBuilder.h =================================================================== --- include/llvm/Transforms/IPO/PassManagerBuilder.h +++ include/llvm/Transforms/IPO/PassManagerBuilder.h @@ -15,6 +15,7 @@ #ifndef LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H #define LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H +#include #include namespace llvm { @@ -114,6 +115,9 @@ /// added to the per-module passes. Pass *Inliner; + /// The function summary index file to use for function importing. + std::string FunctionImportIndexFile; + bool DisableTailCalls; bool DisableUnitAtATime; bool DisableUnrollLoops; Index: lib/Linker/LinkModules.cpp =================================================================== --- lib/Linker/LinkModules.cpp +++ lib/Linker/LinkModules.cpp @@ -2113,14 +2113,15 @@ /// relied on to be consistent. bool Linker::LinkModules(Module *Dest, Module *Src, DiagnosticHandlerFunction DiagnosticHandler, - unsigned Flags) { + unsigned Flags, FunctionInfoIndex *Index) { Linker L(Dest, DiagnosticHandler); - return L.linkInModule(Src, Flags); + return L.linkInModule(Src, Flags, Index); } -bool Linker::LinkModules(Module *Dest, Module *Src, unsigned Flags) { +bool Linker::LinkModules(Module *Dest, Module *Src, unsigned Flags, + FunctionInfoIndex *Index) { Linker L(Dest); - return L.linkInModule(Src, Flags); + return L.linkInModule(Src, Flags, Index); } //===----------------------------------------------------------------------===// Index: lib/Transforms/IPO/FunctionImport.cpp =================================================================== --- lib/Transforms/IPO/FunctionImport.cpp +++ lib/Transforms/IPO/FunctionImport.cpp @@ -239,22 +239,36 @@ /// Pass that performs cross-module function import provided a summary file. class FunctionImportPass : public ModulePass { + /// File holding the function summary index for import + StringRef IndexFile; public: /// Pass identification, replacement for typeid static char ID; - explicit FunctionImportPass() : ModulePass(ID) {} + /// Specify pass name for debug output + const char *getPassName() const override { + return "Function Importing"; + } - bool runOnModule(Module &M) override { - if (SummaryFile.empty()) { - report_fatal_error("error: -function-import requires -summary-file\n"); + explicit FunctionImportPass(StringRef IndexFileName = "") + : ModulePass(ID), IndexFile(IndexFileName) { + if (!SummaryFile.empty()) { + if (!IndexFile.empty()) + report_fatal_error("error: -summary-file and file from frontend\n"); + IndexFile = SummaryFile; } + if (IndexFile.empty()) + report_fatal_error("error: -function-import requires -summary-file or " + "file from frontend\n"); + } + + bool runOnModule(Module &M) override { std::string Error; std::unique_ptr Index = - getFunctionIndexForFile(SummaryFile, Error, diagnosticHandler); + getFunctionIndexForFile(IndexFile, Error, diagnosticHandler); if (!Index) { - errs() << "Error loading file '" << SummaryFile << "': " << Error << "\n"; + errs() << "Error loading file '" << IndexFile << "': " << Error << "\n"; return false; } @@ -273,5 +287,7 @@ "Summary Based Function Import", false, false) namespace llvm { -Pass *createFunctionImportPass() { return new FunctionImportPass(); } +Pass *createFunctionImportPass(StringRef IndexFile) { + return new FunctionImportPass(IndexFile); +} } Index: lib/Transforms/IPO/PassManagerBuilder.cpp =================================================================== --- lib/Transforms/IPO/PassManagerBuilder.cpp +++ lib/Transforms/IPO/PassManagerBuilder.cpp @@ -476,6 +476,9 @@ // Provide AliasAnalysis services for optimizations. addInitialAliasAnalysisPasses(PM); + if (!FunctionImportIndexFile.empty()) + PM.add(createFunctionImportPass(FunctionImportIndexFile)); + // Propagate constants at call sites into the functions they call. This // opens opportunities for globalopt (and inlining) by substituting function // pointers passed as arguments to direct uses of functions.