Index: include/llvm/Analysis/ModuleSummaryAnalysis.h =================================================================== --- include/llvm/Analysis/ModuleSummaryAnalysis.h +++ include/llvm/Analysis/ModuleSummaryAnalysis.h @@ -20,41 +20,18 @@ #include "llvm/Pass.h" namespace llvm { - class BlockFrequencyInfo; -/// Class to build a module summary index for the given Module, possibly from -/// a Pass. -class ModuleSummaryIndexBuilder { - /// The index being built - std::unique_ptr Index; - /// The module for which we are building an index - const Module *M; - -public: - /// Default constructor - ModuleSummaryIndexBuilder() = default; - - /// Constructor that builds an index for the given Module. An optional - /// callback can be supplied to obtain the frequency info for a function. - ModuleSummaryIndexBuilder( - const Module *M, - std::function Ftor = nullptr); - - /// Get a reference to the index owned by builder - ModuleSummaryIndex &getIndex() const { return *Index; } - - /// Take ownership of the built index - std::unique_ptr takeIndex() { return std::move(Index); } - -private: - /// Compute summary for given function with optional frequency information - void computeFunctionSummary(const Function &F, - BlockFrequencyInfo *BFI = nullptr); - - /// Compute summary for given variable with optional frequency information - void computeVariableSummary(const GlobalVariable &V); -}; +/// Direct function to compute a \c ModuleSummaryIndex from a given module. +/// +/// If operating within a pass manager which has defined ways to compute the \c +/// BlockFrequencyInfo for a given function, that can be provided via +/// a std::function callback. Otherwise, this routine will manually construct +/// that information. +ModuleSummaryIndex buildModuleSummaryIndex( + const Module &M, + std::function GetBFICallback = + nullptr); /// Analysis pass to provide the ModuleSummaryIndex object. class ModuleSummaryIndexAnalysis @@ -62,26 +39,15 @@ friend AnalysisInfoMixin; static char PassID; - std::unique_ptr IndexBuilder; - public: - typedef const ModuleSummaryIndex &Result; - - // FIXME: Remove these once MSVC can synthesize them. - ModuleSummaryIndexAnalysis() {} - ModuleSummaryIndexAnalysis(ModuleSummaryIndexAnalysis &&Arg) - : IndexBuilder(std::move(Arg.IndexBuilder)) {} - ModuleSummaryIndexAnalysis &operator=(ModuleSummaryIndexAnalysis &&RHS) { - IndexBuilder = std::move(RHS.IndexBuilder); - return *this; - } + typedef ModuleSummaryIndex Result; - const ModuleSummaryIndex &run(Module &M, ModuleAnalysisManager &AM); + ModuleSummaryIndex run(Module &M, ModuleAnalysisManager &AM); }; /// Legacy wrapper pass to provide the ModuleSummaryIndex object. class ModuleSummaryIndexWrapperPass : public ModulePass { - std::unique_ptr IndexBuilder; + Optional Index; public: static char ID; @@ -89,10 +55,8 @@ ModuleSummaryIndexWrapperPass(); /// Get the index built by pass - ModuleSummaryIndex &getIndex() { return IndexBuilder->getIndex(); } - const ModuleSummaryIndex &getIndex() const { - return IndexBuilder->getIndex(); - } + ModuleSummaryIndex &getIndex() { return *Index; } + const ModuleSummaryIndex &getIndex() const { return *Index; } bool runOnModule(Module &M) override; bool doFinalization(Module &M) override; Index: include/llvm/IR/ModuleSummaryIndex.h =================================================================== --- include/llvm/IR/ModuleSummaryIndex.h +++ include/llvm/IR/ModuleSummaryIndex.h @@ -363,11 +363,14 @@ public: ModuleSummaryIndex() = default; - - // Disable the copy constructor and assignment operators, so - // no unexpected copying/moving occurs. - ModuleSummaryIndex(const ModuleSummaryIndex &) = delete; - void operator=(const ModuleSummaryIndex &) = delete; + ModuleSummaryIndex(ModuleSummaryIndex &&Arg) + : GlobalValueMap(std::move(Arg.GlobalValueMap)), + ModulePathStringTable(std::move(Arg.ModulePathStringTable)) {} + ModuleSummaryIndex &operator=(ModuleSummaryIndex &&RHS) { + GlobalValueMap = std::move(RHS.GlobalValueMap); + ModulePathStringTable = std::move(RHS.ModulePathStringTable); + return *this; + } gvsummary_iterator begin() { return GlobalValueMap.begin(); } const_gvsummary_iterator begin() const { return GlobalValueMap.begin(); } Index: lib/Analysis/ModuleSummaryAnalysis.cpp =================================================================== --- lib/Analysis/ModuleSummaryAnalysis.cpp +++ lib/Analysis/ModuleSummaryAnalysis.cpp @@ -63,8 +63,8 @@ } } -void ModuleSummaryIndexBuilder::computeFunctionSummary( - const Function &F, BlockFrequencyInfo *BFI) { +static void computeFunctionSummary(ModuleSummaryIndex &Index, const Module &M, + const Function &F, BlockFrequencyInfo *BFI) { // Summary not currently supported for anonymous functions, they must // be renamed. if (!F.hasName()) @@ -91,7 +91,7 @@ if (CalledFunction->hasName() && !CalledFunction->isIntrinsic()) { auto ScaledCount = BFI ? BFI->getBlockProfileCount(&BB) : None; auto *CalleeId = - M->getValueSymbolTable().lookup(CalledFunction->getName()); + M.getValueSymbolTable().lookup(CalledFunction->getName()); CallGraphEdges[CalleeId] += (ScaledCount ? ScaledCount.getValue() : 0); } @@ -120,11 +120,11 @@ FuncSummary->addCallGraphEdges(CallGraphEdges); FuncSummary->addCallGraphEdges(IndirectCallEdges); FuncSummary->addRefEdges(RefEdges); - Index->addGlobalValueSummary(F.getName(), std::move(FuncSummary)); + Index.addGlobalValueSummary(F.getName(), std::move(FuncSummary)); } -void ModuleSummaryIndexBuilder::computeVariableSummary( - const GlobalVariable &V) { +static void computeVariableSummary(ModuleSummaryIndex &Index, + const GlobalVariable &V) { DenseSet RefEdges; SmallPtrSet Visited; findRefEdges(&V, RefEdges, Visited); @@ -132,29 +132,29 @@ std::unique_ptr GVarSummary = llvm::make_unique(Flags); GVarSummary->addRefEdges(RefEdges); - Index->addGlobalValueSummary(V.getName(), std::move(GVarSummary)); + Index.addGlobalValueSummary(V.getName(), std::move(GVarSummary)); } -ModuleSummaryIndexBuilder::ModuleSummaryIndexBuilder( - const Module *M, - std::function Ftor) - : Index(llvm::make_unique()), M(M) { +ModuleSummaryIndex llvm::buildModuleSummaryIndex( + const Module &M, + std::function GetBFICallback) { + ModuleSummaryIndex Index; // Check if the module can be promoted, otherwise just disable importing from // it by not emitting any summary. // FIXME: we could still import *into* it most of the time. - if (!moduleCanBeRenamedForThinLTO(*M)) - return; + if (!moduleCanBeRenamedForThinLTO(M)) + return Index; // Compute summaries for all functions defined in module, and save in the // index. - for (auto &F : *M) { + for (auto &F : M) { if (F.isDeclaration()) continue; BlockFrequencyInfo *BFI = nullptr; std::unique_ptr BFIPtr; - if (Ftor) - BFI = Ftor(F); + if (GetBFICallback) + BFI = GetBFICallback(F); else if (F.getEntryCount().hasValue()) { LoopInfo LI{DominatorTree(const_cast(F))}; BranchProbabilityInfo BPI{F, LI}; @@ -162,29 +162,27 @@ BFI = BFIPtr.get(); } - computeFunctionSummary(F, BFI); + computeFunctionSummary(Index, M, F, BFI); } // Compute summaries for all variables defined in module, and save in the // index. - for (const GlobalVariable &G : M->globals()) { + for (const GlobalVariable &G : M.globals()) { if (G.isDeclaration()) continue; - computeVariableSummary(G); + computeVariableSummary(Index, G); } + return Index; } char ModuleSummaryIndexAnalysis::PassID; -const ModuleSummaryIndex & +ModuleSummaryIndex ModuleSummaryIndexAnalysis::run(Module &M, ModuleAnalysisManager &AM) { auto &FAM = AM.getResult(M).getManager(); - IndexBuilder = llvm::make_unique( - &M, [&FAM](const Function &F) { - return &( - FAM.getResult(*const_cast(&F))); - }); - return IndexBuilder->getIndex(); + return buildModuleSummaryIndex(M, [&FAM](const Function &F) { + return &FAM.getResult(*const_cast(&F)); + }); } char ModuleSummaryIndexWrapperPass::ID = 0; @@ -204,17 +202,16 @@ } bool ModuleSummaryIndexWrapperPass::runOnModule(Module &M) { - IndexBuilder = llvm::make_unique( - &M, [this](const Function &F) { - return &(this->getAnalysis( - *const_cast(&F)) - .getBFI()); - }); + Index = buildModuleSummaryIndex(M, [this](const Function &F) { + return &(this->getAnalysis( + *const_cast(&F)) + .getBFI()); + }); return false; } bool ModuleSummaryIndexWrapperPass::doFinalization(Module &M) { - IndexBuilder.reset(); + Index.reset(); return false; } Index: lib/LTO/ThinLTOCodeGenerator.cpp =================================================================== --- lib/LTO/ThinLTOCodeGenerator.cpp +++ lib/LTO/ThinLTOCodeGenerator.cpp @@ -377,8 +377,8 @@ SmallVector OutputBuffer; { raw_svector_ostream OS(OutputBuffer); - ModuleSummaryIndexBuilder IndexBuilder(&TheModule); - WriteBitcodeToFile(&TheModule, OS, true, &IndexBuilder.getIndex()); + auto Index = buildModuleSummaryIndex(TheModule); + WriteBitcodeToFile(&TheModule, OS, true, &Index); } return make_unique(std::move(OutputBuffer)); }