#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<ModuleSummaryIndex> 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<BlockFrequencyInfo *(const Function &F)> 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<ModuleSummaryIndex> 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<BlockFrequencyInfo *(const Function &F)> GetBFICallback =
+ nullptr);
/// Analysis pass to provide the ModuleSummaryIndex object.
class ModuleSummaryIndexAnalysis
friend AnalysisInfoMixin<ModuleSummaryIndexAnalysis>;
static char PassID;
- std::unique_ptr<ModuleSummaryIndexBuilder> 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);
+ Result run(Module &M, ModuleAnalysisManager &AM);
};
/// Legacy wrapper pass to provide the ModuleSummaryIndex object.
class ModuleSummaryIndexWrapperPass : public ModulePass {
- std::unique_ptr<ModuleSummaryIndexBuilder> IndexBuilder;
+ Optional<ModuleSummaryIndex> Index;
public:
static char ID;
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;
}
}
-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())
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);
}
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<const Value *> RefEdges;
SmallPtrSet<const User *, 8> Visited;
findRefEdges(&V, RefEdges, Visited);
std::unique_ptr<GlobalVarSummary> GVarSummary =
llvm::make_unique<GlobalVarSummary>(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<BlockFrequencyInfo *(const Function &F)> Ftor)
- : Index(llvm::make_unique<ModuleSummaryIndex>()), M(M) {
+ModuleSummaryIndex llvm::buildModuleSummaryIndex(
+ const Module &M,
+ std::function<BlockFrequencyInfo *(const Function &F)> 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<BlockFrequencyInfo> BFIPtr;
- if (Ftor)
- BFI = Ftor(F);
+ if (GetBFICallback)
+ BFI = GetBFICallback(F);
else if (F.getEntryCount().hasValue()) {
LoopInfo LI{DominatorTree(const_cast<Function &>(F))};
BranchProbabilityInfo BPI{F, LI};
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<FunctionAnalysisManagerModuleProxy>(M).getManager();
- IndexBuilder = llvm::make_unique<ModuleSummaryIndexBuilder>(
- &M, [&FAM](const Function &F) {
- return &(
- FAM.getResult<BlockFrequencyAnalysis>(*const_cast<Function *>(&F)));
- });
- return IndexBuilder->getIndex();
+ return buildModuleSummaryIndex(M, [&FAM](const Function &F) {
+ return &FAM.getResult<BlockFrequencyAnalysis>(*const_cast<Function *>(&F));
+ });
}
char ModuleSummaryIndexWrapperPass::ID = 0;
}
bool ModuleSummaryIndexWrapperPass::runOnModule(Module &M) {
- IndexBuilder = llvm::make_unique<ModuleSummaryIndexBuilder>(
- &M, [this](const Function &F) {
- return &(this->getAnalysis<BlockFrequencyInfoWrapperPass>(
- *const_cast<Function *>(&F))
- .getBFI());
- });
+ Index = buildModuleSummaryIndex(M, [this](const Function &F) {
+ return &(this->getAnalysis<BlockFrequencyInfoWrapperPass>(
+ *const_cast<Function *>(&F))
+ .getBFI());
+ });
return false;
}
bool ModuleSummaryIndexWrapperPass::doFinalization(Module &M) {
- IndexBuilder.reset();
+ Index.reset();
return false;
}