1//===- LazyBranchProbabilityInfo.h - Lazy Branch Probability ----*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This is an alternative analysis pass to BranchProbabilityInfoWrapperPass. 10// The difference is that with this pass the branch probabilities are not 11// computed when the analysis pass is executed but rather when the BPI results 12// is explicitly requested by the analysis client. 13// 14//===----------------------------------------------------------------------===// 15 16#ifndef LLVM_ANALYSIS_LAZYBRANCHPROBABILITYINFO_H 17#define LLVM_ANALYSIS_LAZYBRANCHPROBABILITYINFO_H 18 19#include "llvm/Analysis/BranchProbabilityInfo.h" 20#include "llvm/Pass.h" 21 22namespace llvm { 23class AnalysisUsage; 24class Function; 25class LoopInfo; 26class TargetLibraryInfo; 27 28/// This is an alternative analysis pass to 29/// BranchProbabilityInfoWrapperPass. The difference is that with this pass the 30/// branch probabilities are not computed when the analysis pass is executed but 31/// rather when the BPI results is explicitly requested by the analysis client. 32/// 33/// There are some additional requirements for any client pass that wants to use 34/// the analysis: 35/// 36/// 1. The pass needs to initialize dependent passes with: 37/// 38/// INITIALIZE_PASS_DEPENDENCY(LazyBPIPass) 39/// 40/// 2. Similarly, getAnalysisUsage should call: 41/// 42/// LazyBranchProbabilityInfoPass::getLazyBPIAnalysisUsage(AU) 43/// 44/// 3. The computed BPI should be requested with 45/// getAnalysis<LazyBranchProbabilityInfoPass>().getBPI() before LoopInfo 46/// could be invalidated for example by changing the CFG. 47/// 48/// Note that it is expected that we wouldn't need this functionality for the 49/// new PM since with the new PM, analyses are executed on demand. 50class LazyBranchProbabilityInfoPass : public FunctionPass { 51 52 /// Wraps a BPI to allow lazy computation of the branch probabilities. 53 /// 54 /// A pass that only conditionally uses BPI can uncondtionally require the 55 /// analysis without paying for the overhead if BPI doesn't end up being used. 56 class LazyBranchProbabilityInfo { 57 public: 58 LazyBranchProbabilityInfo(const Function *F, const LoopInfo *LI, 59 const TargetLibraryInfo *TLI) 60 : Calculated(false), F(F), LI(LI), TLI(TLI) {} 61 62 /// Retrieve the BPI with the branch probabilities computed. 63 BranchProbabilityInfo &getCalculated() { 64 if (!Calculated) { 65 assert(F && LI && "call setAnalysis"); 66 BPI.calculate(*F, *LI, TLI, nullptr, nullptr); 67 Calculated = true; 68 } 69 return BPI; 70 } 71 72 const BranchProbabilityInfo &getCalculated() const { 73 return const_cast<LazyBranchProbabilityInfo *>(this)->getCalculated(); 74 } 75 76 private: 77 BranchProbabilityInfo BPI; 78 bool Calculated; 79 const Function *F; 80 const LoopInfo *LI; 81 const TargetLibraryInfo *TLI; 82 }; 83 84 std::unique_ptr<LazyBranchProbabilityInfo> LBPI; 85 86public: 87 static char ID; 88 89 LazyBranchProbabilityInfoPass(); 90 91 /// Compute and return the branch probabilities. 92 BranchProbabilityInfo &getBPI() { return LBPI->getCalculated(); } 93 94 /// Compute and return the branch probabilities. 95 const BranchProbabilityInfo &getBPI() const { return LBPI->getCalculated(); } 96 97 void getAnalysisUsage(AnalysisUsage &AU) const override; 98 99 /// Helper for client passes to set up the analysis usage on behalf of this 100 /// pass. 101 static void getLazyBPIAnalysisUsage(AnalysisUsage &AU); 102 103 bool runOnFunction(Function &F) override; 104 void releaseMemory() override; 105 void print(raw_ostream &OS, const Module *M) const override; 106}; 107 108/// Helper for client passes to initialize dependent passes for LBPI. 109void initializeLazyBPIPassPass(PassRegistry &Registry); 110 111/// Simple trait class that provides a mapping between BPI passes and the 112/// corresponding BPInfo. 113template <typename PassT> struct BPIPassTrait { 114 static PassT &getBPI(PassT *P) { return *P; } 115}; 116 117template <> struct BPIPassTrait<LazyBranchProbabilityInfoPass> { 118 static BranchProbabilityInfo &getBPI(LazyBranchProbabilityInfoPass *P) { 119 return P->getBPI(); 120 } 121}; 122} 123#endif 124