diff --git a/include/llvm/Analysis/BranchProbabilityInfo.h b/include/llvm/Analysis/BranchProbabilityInfo.h index 6a0221209a0..54514a9f1f3 100644 --- a/include/llvm/Analysis/BranchProbabilityInfo.h +++ b/include/llvm/Analysis/BranchProbabilityInfo.h @@ -17,6 +17,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/IR/CFG.h" +#include "llvm/IR/PassManager.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Support/BranchProbability.h" @@ -44,6 +45,19 @@ public: calculate(F, LI); } + BranchProbabilityInfo(BranchProbabilityInfo &&Arg) + : Probs(std::move(Arg.Probs)), LastF(Arg.LastF), + PostDominatedByUnreachable(std::move(Arg.PostDominatedByUnreachable)), + PostDominatedByColdCall(std::move(Arg.PostDominatedByColdCall)) {} + + BranchProbabilityInfo &operator=(BranchProbabilityInfo &&RHS) { + releaseMemory(); + Probs = std::move(RHS.Probs); + PostDominatedByColdCall = std::move(RHS.PostDominatedByColdCall); + PostDominatedByUnreachable = std::move(RHS.PostDominatedByUnreachable); + return *this; + } + void releaseMemory(); void print(raw_ostream &OS) const; @@ -103,6 +117,9 @@ public: void calculate(const Function &F, const LoopInfo &LI); private: + void operator=(const BranchProbabilityInfo &) = delete; + BranchProbabilityInfo(const BranchProbabilityInfo &) = delete; + // Since we allow duplicate edges from one basic block to another, we use // a pair (PredBlock and an index in the successors) to specify an edge. typedef std::pair Edge; @@ -136,6 +153,30 @@ private: bool calcInvokeHeuristics(const BasicBlock *BB); }; +/// \brief Analysis pass which computes \c BranchProbabilityInfo. +class BranchProbabilityAnalysis + : public AnalysisInfoMixin { + friend AnalysisInfoMixin; + static char PassID; + +public: + /// \brief Provide the result typedef for this analysis pass. + typedef BranchProbabilityInfo Result; + + /// \brief Run the analysis pass over a function and produce BPI. + BranchProbabilityInfo run(Function &F, AnalysisManager &AM); +}; + +/// \brief Printer pass for the \c BranchProbabilityAnalysis results. +class BranchProbabilityPrinterPass + : public PassInfoMixin { + raw_ostream &OS; + +public: + explicit BranchProbabilityPrinterPass(raw_ostream &OS) : OS(OS) {} + PreservedAnalyses run(Function &F, AnalysisManager &AM); +}; + /// \brief Legacy analysis pass which computes \c BranchProbabilityInfo. class BranchProbabilityInfoWrapperPass : public FunctionPass { BranchProbabilityInfo BPI; diff --git a/lib/Analysis/BranchProbabilityInfo.cpp b/lib/Analysis/BranchProbabilityInfo.cpp index b431e621622..33036b72615 100644 --- a/lib/Analysis/BranchProbabilityInfo.cpp +++ b/lib/Analysis/BranchProbabilityInfo.cpp @@ -689,3 +689,20 @@ void BranchProbabilityInfoWrapperPass::print(raw_ostream &OS, const Module *) const { BPI.print(OS); } + +char BranchProbabilityAnalysis::PassID; +BranchProbabilityInfo +BranchProbabilityAnalysis::run(Function &F, AnalysisManager &AM) { + BranchProbabilityInfo BPI; + BPI.calculate(F, AM.getResult(F)); + return BPI; +} + +PreservedAnalyses +BranchProbabilityPrinterPass::run(Function &F, AnalysisManager &AM) { + OS << "Printing analysis results of BPI for function " + << "'" << F.getName() << "':" + << "\n"; + AM.getResult(F).print(OS); + return PreservedAnalyses::all(); +} diff --git a/lib/Passes/PassBuilder.cpp b/lib/Passes/PassBuilder.cpp index f17eb681f1c..bc03cc1059a 100644 --- a/lib/Passes/PassBuilder.cpp +++ b/lib/Passes/PassBuilder.cpp @@ -21,6 +21,7 @@ #include "llvm/Analysis/AliasAnalysisEvaluator.h" #include "llvm/Analysis/AssumptionCache.h" #include "llvm/Analysis/BasicAliasAnalysis.h" +#include "llvm/Analysis/BranchProbabilityInfo.h" #include "llvm/Analysis/CFLAliasAnalysis.h" #include "llvm/Analysis/CGSCCPassManager.h" #include "llvm/Analysis/CallGraph.h" diff --git a/lib/Passes/PassRegistry.def b/lib/Passes/PassRegistry.def index 6bae08efea2..37ef2245f43 100644 --- a/lib/Passes/PassRegistry.def +++ b/lib/Passes/PassRegistry.def @@ -71,6 +71,7 @@ CGSCC_PASS("no-op-cgscc", NoOpCGSCCPass()) #endif FUNCTION_ANALYSIS("aa", AAManager()) FUNCTION_ANALYSIS("assumptions", AssumptionAnalysis()) +FUNCTION_ANALYSIS("branch-prob", BranchProbabilityAnalysis()) FUNCTION_ANALYSIS("domtree", DominatorTreeAnalysis()) FUNCTION_ANALYSIS("postdomtree", PostDominatorTreeAnalysis()) FUNCTION_ANALYSIS("demanded-bits", DemandedBitsAnalysis()) @@ -110,6 +111,7 @@ FUNCTION_PASS("lower-expect", LowerExpectIntrinsicPass()) FUNCTION_PASS("gvn", GVN()) FUNCTION_PASS("print", PrintFunctionPass(dbgs())) FUNCTION_PASS("print", AssumptionPrinterPass(dbgs())) +FUNCTION_PASS("print", BranchProbabilityPrinterPass(dbgs())) FUNCTION_PASS("print", DominatorTreePrinterPass(dbgs())) FUNCTION_PASS("print", PostDominatorTreePrinterPass(dbgs())) FUNCTION_PASS("print", DemandedBitsPrinterPass(dbgs())) diff --git a/test/Analysis/BranchProbabilityInfo/basic.ll b/test/Analysis/BranchProbabilityInfo/basic.ll index d833b8339aa..d86709130f3 100644 --- a/test/Analysis/BranchProbabilityInfo/basic.ll +++ b/test/Analysis/BranchProbabilityInfo/basic.ll @@ -1,4 +1,5 @@ ; RUN: opt < %s -analyze -branch-prob | FileCheck %s +; RUN: opt < %s -passes='print' -disable-output 2>&1 | FileCheck %s define i32 @test1(i32 %i, i32* %a) { ; CHECK: Printing analysis {{.*}} for function 'test1' diff --git a/test/Analysis/BranchProbabilityInfo/deopt-intrinsic.ll b/test/Analysis/BranchProbabilityInfo/deopt-intrinsic.ll index 8728d4ab8fe..faa09f9e8a0 100644 --- a/test/Analysis/BranchProbabilityInfo/deopt-intrinsic.ll +++ b/test/Analysis/BranchProbabilityInfo/deopt-intrinsic.ll @@ -1,9 +1,10 @@ ; RUN: opt -analyze -branch-prob < %s | FileCheck %s +; RUN: opt < %s -passes='print' -disable-output 2>&1 | FileCheck %s declare i32 @llvm.experimental.deoptimize.i32(...) define i32 @test1(i32 %a, i32 %b) { -; CHECK-LABEL: Printing analysis 'Branch Probability Analysis' for function 'test1': +; CHECK-LABEL: Printing analysis {{.*}} for function 'test1': entry: %cond = icmp eq i32 %a, 42 br i1 %cond, label %exit, label %deopt diff --git a/test/Analysis/BranchProbabilityInfo/loop.ll b/test/Analysis/BranchProbabilityInfo/loop.ll index 5be7adf3909..1a37a7a4659 100644 --- a/test/Analysis/BranchProbabilityInfo/loop.ll +++ b/test/Analysis/BranchProbabilityInfo/loop.ll @@ -1,5 +1,6 @@ ; Test the static branch probability heuristics for no-return functions. ; RUN: opt < %s -analyze -branch-prob | FileCheck %s +; RUN: opt < %s -passes='print' --disable-output 2>&1 | FileCheck %s declare void @g1() declare void @g2() diff --git a/test/Analysis/BranchProbabilityInfo/noreturn.ll b/test/Analysis/BranchProbabilityInfo/noreturn.ll index 7098c2f7b8c..0c2fe863d03 100644 --- a/test/Analysis/BranchProbabilityInfo/noreturn.ll +++ b/test/Analysis/BranchProbabilityInfo/noreturn.ll @@ -1,5 +1,6 @@ ; Test the static branch probability heuristics for no-return functions. ; RUN: opt < %s -analyze -branch-prob | FileCheck %s +; RUN: opt < %s -passes='print' -disable-output 2>&1 | FileCheck %s declare void @abort() noreturn diff --git a/test/Analysis/BranchProbabilityInfo/pr18705.ll b/test/Analysis/BranchProbabilityInfo/pr18705.ll index f5f9612fcdb..74983ef1b4f 100644 --- a/test/Analysis/BranchProbabilityInfo/pr18705.ll +++ b/test/Analysis/BranchProbabilityInfo/pr18705.ll @@ -1,4 +1,5 @@ ; RUN: opt < %s -analyze -branch-prob | FileCheck %s +; RUN: opt < %s -passes='print' -disable-output 2>&1 | FileCheck %s ; Since neither of while.body's out-edges is an exit or a back edge, ; calcLoopBranchHeuristics should return early without setting the weights. diff --git a/test/Analysis/BranchProbabilityInfo/pr22718.ll b/test/Analysis/BranchProbabilityInfo/pr22718.ll index 51bbd13e83c..66ac89793b8 100644 --- a/test/Analysis/BranchProbabilityInfo/pr22718.ll +++ b/test/Analysis/BranchProbabilityInfo/pr22718.ll @@ -1,4 +1,5 @@ ; RUN: opt < %s -analyze -branch-prob | FileCheck %s +; RUN: opt < %s -passes='print' -disable-output 2>&1 | FileCheck %s ; In this test, the else clause is taken about 90% of the time. This was not ; reflected in the probability computation because the weight is larger than