[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