[PATCH] D19839: [PM] Port BranchProbability Analysis to the new pass manager
Justin Bogner via llvm-commits
llvm-commits at lists.llvm.org
Wed May 4 12:56:09 PDT 2016
David Li via llvm-commits <llvm-commits at lists.llvm.org> writes:
> davidxl created this revision.
> davidxl added a reviewer: chandlerc.
> davidxl added a subscriber: llvm-commits.
>
> This patch ports the Analysis pass that computes BPI to the new pass manager.
>
> There is a slight difference in printer output -- the header line
> format is different. This should be revisited later.
The port LGTM, but I find the output confusing since it doesn't have a
banner at all. Why not make PrinterPass::run() itself emit a banner,
like we do in DominatorTreePrinterPass or a few other of the ports?
> http://reviews.llvm.org/D19839
>
> Files:
> include/llvm/Analysis/BranchProbabilityInfo.h
> lib/Analysis/BranchProbabilityInfo.cpp
> lib/Passes/PassBuilder.cpp
> lib/Passes/PassRegistry.def
> test/Analysis/BranchProbabilityInfo/basic.ll
> test/Analysis/BranchProbabilityInfo/deopt-intrinsic.ll
> test/Analysis/BranchProbabilityInfo/loop.ll
> test/Analysis/BranchProbabilityInfo/noreturn.ll
> test/Analysis/BranchProbabilityInfo/pr18705.ll
> test/Analysis/BranchProbabilityInfo/pr22718.ll
>
> Index: test/Analysis/BranchProbabilityInfo/pr22718.ll
> ===================================================================
> --- test/Analysis/BranchProbabilityInfo/pr22718.ll
> +++ test/Analysis/BranchProbabilityInfo/pr22718.ll
> @@ -1,4 +1,5 @@
> ; RUN: opt < %s -analyze -branch-prob | FileCheck %s
> +; RUN: opt < %s -passes='print<branch-prob>' -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
> Index: test/Analysis/BranchProbabilityInfo/pr18705.ll
> ===================================================================
> --- test/Analysis/BranchProbabilityInfo/pr18705.ll
> +++ test/Analysis/BranchProbabilityInfo/pr18705.ll
> @@ -1,4 +1,5 @@
> ; RUN: opt < %s -analyze -branch-prob | FileCheck %s
> +; RUN: opt < %s -passes='print<branch-prob>' -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.
> Index: test/Analysis/BranchProbabilityInfo/noreturn.ll
> ===================================================================
> --- test/Analysis/BranchProbabilityInfo/noreturn.ll
> +++ test/Analysis/BranchProbabilityInfo/noreturn.ll
> @@ -1,10 +1,11 @@
> ; Test the static branch probability heuristics for no-return functions.
> -; RUN: opt < %s -analyze -branch-prob | FileCheck %s
> +; RUN: opt < %s -analyze -branch-prob | FileCheck %s --check-prefix=CHECK --check-prefix=HEADER
> +; RUN: opt < %s -passes='print<branch-prob>' -disable-output 2>&1 | FileCheck %s
>
> declare void @abort() noreturn
>
> define i32 @test1(i32 %a, i32 %b) {
> -; CHECK: Printing analysis {{.*}} for function 'test1'
> +; HEADER: Printing analysis {{.*}} for function 'test1'
> entry:
> %cond = icmp eq i32 %a, 42
> br i1 %cond, label %exit, label %abort
> @@ -20,7 +21,7 @@
> }
>
> define i32 @test2(i32 %a, i32 %b) {
> -; CHECK: Printing analysis {{.*}} for function 'test2'
> +; HEADER: Printing analysis {{.*}} for function 'test2'
> entry:
> switch i32 %a, label %exit [i32 1, label %case_a
> i32 2, label %case_b
> @@ -50,7 +51,7 @@
> }
>
> define i32 @test3(i32 %a, i32 %b) {
> -; CHECK: Printing analysis {{.*}} for function 'test3'
> +; HEADER: Printing analysis {{.*}} for function 'test3'
> ; Make sure we unify across multiple conditional branches.
> entry:
> %cond1 = icmp eq i32 %a, 42
> @@ -80,7 +81,7 @@
>
> @_ZTIi = external global i8*
>
> -; CHECK-LABEL: throwSmallException
> +; HEADER-LABEL: throwSmallException
> ; CHECK-NOT: invoke i32 @smallFunction
> define i32 @throwSmallException(i32 %idx, i32 %limit) #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
> entry:
> Index: test/Analysis/BranchProbabilityInfo/loop.ll
> ===================================================================
> --- test/Analysis/BranchProbabilityInfo/loop.ll
> +++ 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<branch-prob>' --disable-output 2>&1 | FileCheck %s
>
> declare void @g1()
> declare void @g2()
> Index: test/Analysis/BranchProbabilityInfo/deopt-intrinsic.ll
> ===================================================================
> --- test/Analysis/BranchProbabilityInfo/deopt-intrinsic.ll
> +++ test/Analysis/BranchProbabilityInfo/deopt-intrinsic.ll
> @@ -1,9 +1,10 @@
> -; RUN: opt -analyze -branch-prob < %s | FileCheck %s
> +; RUN: opt -analyze -branch-prob < %s | FileCheck %s --check-prefix=CHECK --check-prefix=HEADER
> +; RUN: opt < %s -passes='print<branch-prob>' -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':
> +; HEADER-LABEL: Printing analysis 'Branch Probability Analysis' for function 'test1':
> entry:
> %cond = icmp eq i32 %a, 42
> br i1 %cond, label %exit, label %deopt
> Index: test/Analysis/BranchProbabilityInfo/basic.ll
> ===================================================================
> --- test/Analysis/BranchProbabilityInfo/basic.ll
> +++ test/Analysis/BranchProbabilityInfo/basic.ll
> @@ -1,7 +1,8 @@
> -; RUN: opt < %s -analyze -branch-prob | FileCheck %s
> +; RUN: opt < %s -analyze -branch-prob | FileCheck %s --check-prefix=CHECK --check-prefix=HEADER
> +; RUN: opt < %s -passes='print<branch-prob>' -disable-output 2>&1 | FileCheck %s
>
> define i32 @test1(i32 %i, i32* %a) {
> -; CHECK: Printing analysis {{.*}} for function 'test1'
> +; HEADER: Printing analysis {{.*}} for function 'test1'
> entry:
> br label %body
> ; CHECK: edge entry -> body probability is 0x80000000 / 0x80000000 = 100.00% [HOT edge]
> @@ -23,7 +24,7 @@
> }
>
> define i32 @test2(i32 %i, i32 %a, i32 %b) {
> -; CHECK: Printing analysis {{.*}} for function 'test2'
> +; HEADER: Printing analysis {{.*}} for function 'test2'
> entry:
> %cond = icmp ult i32 %i, 42
> br i1 %cond, label %then, label %else, !prof !0
> @@ -46,7 +47,7 @@
> !0 = !{!"branch_weights", i32 64, i32 4}
>
> define i32 @test3(i32 %i, i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
> -; CHECK: Printing analysis {{.*}} for function 'test3'
> +; HEADER: Printing analysis {{.*}} for function 'test3'
> entry:
> switch i32 %i, label %case_a [ i32 1, label %case_b
> i32 2, label %case_c
> @@ -90,7 +91,7 @@
> !1 = !{!"branch_weights", i32 4, i32 4, i32 64, i32 4, i32 4}
>
> define i32 @test4(i32 %x) nounwind uwtable readnone ssp {
> -; CHECK: Printing analysis {{.*}} for function 'test4'
> +; HEADER: Printing analysis {{.*}} for function 'test4'
> entry:
> %conv = sext i32 %x to i64
> switch i64 %conv, label %return [
> @@ -119,7 +120,7 @@
> declare void @coldfunc() cold
>
> define i32 @test5(i32 %a, i32 %b, i1 %flag) {
> -; CHECK: Printing analysis {{.*}} for function 'test5'
> +; HEADER: Printing analysis {{.*}} for function 'test5'
> entry:
> br i1 %flag, label %then, label %else
> ; CHECK: edge entry -> then probability is 0x07878788 / 0x80000000 = 5.88%
> @@ -148,7 +149,7 @@
> ; they are currently being merged. Convert this into a code generation test
> ; after that is fixed.
>
> -; CHECK: Printing analysis {{.*}} for function 'test_cold_call_sites'
> +; HEADER: Printing analysis {{.*}} for function 'test_cold_call_sites'
> ; CHECK: edge entry -> then probability is 0x07878788 / 0x80000000 = 5.88%
> ; CHECK: edge entry -> else probability is 0x78787878 / 0x80000000 = 94.12% [HOT edge]
>
> @@ -175,7 +176,7 @@
> }
>
> define i32 @zero1(i32 %i, i32 %a, i32 %b) {
> -; CHECK: Printing analysis {{.*}} for function 'zero1'
> +; HEADER: Printing analysis {{.*}} for function 'zero1'
> entry:
> %cond = icmp eq i32 %i, 0
> br i1 %cond, label %then, label %else
> @@ -194,7 +195,7 @@
> }
>
> define i32 @zero2(i32 %i, i32 %a, i32 %b) {
> -; CHECK: Printing analysis {{.*}} for function 'zero2'
> +; HEADER: Printing analysis {{.*}} for function 'zero2'
> entry:
> %cond = icmp ne i32 %i, -1
> br i1 %cond, label %then, label %else
> @@ -213,7 +214,7 @@
> }
>
> define i32 @zero3(i32 %i, i32 %a, i32 %b) {
> -; CHECK: Printing analysis {{.*}} for function 'zero3'
> +; HEADER: Printing analysis {{.*}} for function 'zero3'
> entry:
> ; AND'ing with a single bit bitmask essentially leads to a bool comparison,
> ; meaning we don't have probability information.
> Index: lib/Passes/PassRegistry.def
> ===================================================================
> --- lib/Passes/PassRegistry.def
> +++ lib/Passes/PassRegistry.def
> @@ -68,6 +68,7 @@
> #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())
> @@ -107,6 +108,7 @@
> FUNCTION_PASS("gvn", GVN())
> FUNCTION_PASS("print", PrintFunctionPass(dbgs()))
> FUNCTION_PASS("print<assumptions>", AssumptionPrinterPass(dbgs()))
> +FUNCTION_PASS("print<branch-prob>", BranchProbabilityPrinterPass(dbgs()))
> FUNCTION_PASS("print<domtree>", DominatorTreePrinterPass(dbgs()))
> FUNCTION_PASS("print<postdomtree>", PostDominatorTreePrinterPass(dbgs()))
> FUNCTION_PASS("print<demanded-bits>", DemandedBitsPrinterPass(dbgs()))
> Index: lib/Passes/PassBuilder.cpp
> ===================================================================
> --- lib/Passes/PassBuilder.cpp
> +++ 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"
> Index: lib/Analysis/BranchProbabilityInfo.cpp
> ===================================================================
> --- lib/Analysis/BranchProbabilityInfo.cpp
> +++ lib/Analysis/BranchProbabilityInfo.cpp
> @@ -689,3 +689,17 @@
> const Module *) const {
> BPI.print(OS);
> }
> +
> +char BranchProbabilityAnalysis::PassID;
> +BranchProbabilityInfo
> +BranchProbabilityAnalysis::run(Function &F, AnalysisManager<Function> &AM) {
> + BranchProbabilityInfo BPI;
> + BPI.calculate(F, AM.getResult<LoopAnalysis>(F));
> + return BPI;
> +}
> +
> +PreservedAnalyses
> +BranchProbabilityPrinterPass::run(Function &F, AnalysisManager<Function> &AM) {
> + AM.getResult<BranchProbabilityAnalysis>(F).print(OS);
> + return PreservedAnalyses::all();
> +}
> Index: include/llvm/Analysis/BranchProbabilityInfo.h
> ===================================================================
> --- include/llvm/Analysis/BranchProbabilityInfo.h
> +++ 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 @@
> 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 @@
> 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<const BasicBlock *, unsigned> Edge;
> @@ -136,6 +153,30 @@
> bool calcInvokeHeuristics(const BasicBlock *BB);
> };
>
> +/// \brief Analysis pass which computes \c BranchProbabilityInfo.
> +class BranchProbabilityAnalysis
> + : public AnalysisInfoMixin<BranchProbabilityAnalysis> {
> + friend AnalysisInfoMixin<BranchProbabilityAnalysis>;
> + 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<Function> &AM);
> +};
> +
> +/// \brief Printer pass for the \c BranchProbabilityAnalysis results.
> +class BranchProbabilityPrinterPass
> + : public PassInfoMixin<BranchProbabilityPrinterPass> {
> + raw_ostream &OS;
> +
> +public:
> + explicit BranchProbabilityPrinterPass(raw_ostream &OS) : OS(OS) {}
> + PreservedAnalyses run(Function &F, AnalysisManager<Function> &AM);
> +};
> +
> /// \brief Legacy analysis pass which computes \c BranchProbabilityInfo.
> class BranchProbabilityInfoWrapperPass : public FunctionPass {
> BranchProbabilityInfo BPI;
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list