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(); (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 @@ -104,6 +104,13 @@ DiagnosticHandlerFunction DiagnosticHandler; }; +/// Create a new module with exported local functions renamed and promoted +/// for ThinLTO. +std::unique_ptr +renameModuleForThinLTO(std::unique_ptr &M, + const FunctionInfoIndex *Index, + DiagnosticHandlerFunction DiagnosticHandler); + } // End llvm namespace #endif Index: include/llvm/Transforms/IPO.h =================================================================== --- include/llvm/Transforms/IPO.h +++ include/llvm/Transforms/IPO.h @@ -20,6 +20,7 @@ namespace llvm { +class FunctionInfoIndex; class ModulePass; class Pass; class Function; @@ -86,6 +87,10 @@ deleteFn = false); //===----------------------------------------------------------------------===// +/// This pass performs iterative function importing from other modules. +ModulePass *createFunctionImportPass(FunctionInfoIndex *Index = nullptr); + +//===----------------------------------------------------------------------===// /// 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,9 +15,11 @@ #ifndef LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H #define LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H +#include #include namespace llvm { +class FunctionInfoIndex; class Pass; class TargetLibraryInfoImpl; class TargetMachine; @@ -114,6 +116,9 @@ /// added to the per-module passes. Pass *Inliner; + /// The function summary index to use for function importing. + std::unique_ptr FunctionIndex; + bool DisableTailCalls; bool DisableUnitAtATime; bool DisableUnrollLoops; Index: lib/Linker/LinkModules.cpp =================================================================== --- lib/Linker/LinkModules.cpp +++ lib/Linker/LinkModules.cpp @@ -2123,6 +2123,18 @@ return L.linkInModule(Src, Flags); } +std::unique_ptr +llvm::renameModuleForThinLTO(std::unique_ptr &M, + const FunctionInfoIndex *Index, + DiagnosticHandlerFunction DiagnosticHandler) { + std::unique_ptr RenamedModule( + new llvm::Module(M->getModuleIdentifier(), M->getContext())); + Linker L(RenamedModule.get(), DiagnosticHandler); + if (L.linkInModule(M.get(), llvm::Linker::Flags::None, Index)) + return nullptr; + return RenamedModule; +} + //===----------------------------------------------------------------------===// // C API. //===----------------------------------------------------------------------===// Index: lib/Transforms/IPO/FunctionImport.cpp =================================================================== --- lib/Transforms/IPO/FunctionImport.cpp +++ lib/Transforms/IPO/FunctionImport.cpp @@ -239,23 +239,37 @@ /// Pass that performs cross-module function import provided a summary file. class FunctionImportPass : public ModulePass { + /// Function summary index to use for importing + FunctionInfoIndex *Index; 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"; + } + + explicit FunctionImportPass(FunctionInfoIndex *Index = nullptr) + : ModulePass(ID), Index(Index) {} bool runOnModule(Module &M) override { - if (SummaryFile.empty()) { - report_fatal_error("error: -function-import requires -summary-file\n"); - } - std::string Error; - std::unique_ptr Index = - getFunctionIndexForFile(SummaryFile, Error, diagnosticHandler); - if (!Index) { - errs() << "Error loading file '" << SummaryFile << "': " << Error << "\n"; - return false; + if (SummaryFile.empty() && !Index) + report_fatal_error("error: -function-import requires -summary-file or " + "file from frontend\n"); + std::unique_ptr IndexPtr; + if (!SummaryFile.empty()) { + if (Index) + report_fatal_error("error: -summary-file and index from frontend\n"); + std::string Error; + IndexPtr = getFunctionIndexForFile(SummaryFile, Error, diagnosticHandler); + if (!IndexPtr) { + errs() << "Error loading file '" << SummaryFile << "': " << Error + << "\n"; + return false; + } + Index = IndexPtr.get(); } // Perform the import now. @@ -273,5 +287,7 @@ "Summary Based Function Import", false, false) namespace llvm { -Pass *createFunctionImportPass() { return new FunctionImportPass(); } +Pass *createFunctionImportPass(FunctionInfoIndex *Index = nullptr) { + return new FunctionImportPass(Index); +} } Index: lib/Transforms/IPO/PassManagerBuilder.cpp =================================================================== --- lib/Transforms/IPO/PassManagerBuilder.cpp +++ lib/Transforms/IPO/PassManagerBuilder.cpp @@ -18,6 +18,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/Analysis/Passes.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/FunctionInfo.h" #include "llvm/IR/Verifier.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/Support/CommandLine.h" @@ -476,6 +477,9 @@ // Provide AliasAnalysis services for optimizations. addInitialAliasAnalysisPasses(PM); + if (FunctionIndex) + PM.add(createFunctionImportPass(FunctionIndex.get())); + // 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.