diff options
Diffstat (limited to 'include/llvm/Analysis/BranchProbabilityInfo.h')
-rw-r--r-- | include/llvm/Analysis/BranchProbabilityInfo.h | 94 |
1 files changed, 79 insertions, 15 deletions
diff --git a/include/llvm/Analysis/BranchProbabilityInfo.h b/include/llvm/Analysis/BranchProbabilityInfo.h index cfdf218491bdb..6434ba962ebc1 100644 --- a/include/llvm/Analysis/BranchProbabilityInfo.h +++ b/include/llvm/Analysis/BranchProbabilityInfo.h @@ -15,8 +15,11 @@ #define LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/IR/CFG.h" +#include "llvm/IR/PassManager.h" +#include "llvm/IR/ValueHandle.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Support/BranchProbability.h" @@ -40,7 +43,22 @@ class raw_ostream; class BranchProbabilityInfo { public: BranchProbabilityInfo() {} - BranchProbabilityInfo(Function &F, const LoopInfo &LI) { calculate(F, LI); } + BranchProbabilityInfo(const Function &F, const LoopInfo &LI) { + 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(); @@ -74,7 +92,7 @@ public: /// /// Given a basic block, look through its successors and if one exists for /// which \see isEdgeHot would return true, return that successor block. - BasicBlock *getHotSucc(BasicBlock *BB) const; + const BasicBlock *getHotSucc(const BasicBlock *BB) const; /// \brief Print an edge's probability. /// @@ -98,9 +116,31 @@ public: return IsLikely ? LikelyProb : LikelyProb.getCompl(); } - void calculate(Function &F, const LoopInfo& LI); + void calculate(const Function &F, const LoopInfo &LI); + + /// Forget analysis results for the given basic block. + void eraseBlock(const BasicBlock *BB); private: + void operator=(const BranchProbabilityInfo &) = delete; + BranchProbabilityInfo(const BranchProbabilityInfo &) = delete; + + // We need to store CallbackVH's in order to correctly handle basic block + // removal. + class BasicBlockCallbackVH final : public CallbackVH { + BranchProbabilityInfo *BPI; + void deleted() override { + assert(BPI != nullptr); + BPI->eraseBlock(cast<BasicBlock>(getValPtr())); + BPI->Handles.erase(*this); + } + + public: + BasicBlockCallbackVH(const Value *V, BranchProbabilityInfo *BPI=nullptr) + : CallbackVH(const_cast<Value *>(V)), BPI(BPI) {} + }; + DenseSet<BasicBlockCallbackVH, DenseMapInfo<Value*>> Handles; + // 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; @@ -116,22 +156,46 @@ private: DenseMap<Edge, BranchProbability> Probs; /// \brief Track the last function we run over for printing. - Function *LastF; + const Function *LastF; /// \brief Track the set of blocks directly succeeded by a returning block. - SmallPtrSet<BasicBlock *, 16> PostDominatedByUnreachable; + SmallPtrSet<const BasicBlock *, 16> PostDominatedByUnreachable; /// \brief Track the set of blocks that always lead to a cold call. - SmallPtrSet<BasicBlock *, 16> PostDominatedByColdCall; - - bool calcUnreachableHeuristics(BasicBlock *BB); - bool calcMetadataWeights(BasicBlock *BB); - bool calcColdCallHeuristics(BasicBlock *BB); - bool calcPointerHeuristics(BasicBlock *BB); - bool calcLoopBranchHeuristics(BasicBlock *BB, const LoopInfo &LI); - bool calcZeroHeuristics(BasicBlock *BB); - bool calcFloatingPointHeuristics(BasicBlock *BB); - bool calcInvokeHeuristics(BasicBlock *BB); + SmallPtrSet<const BasicBlock *, 16> PostDominatedByColdCall; + + bool calcUnreachableHeuristics(const BasicBlock *BB); + bool calcMetadataWeights(const BasicBlock *BB); + bool calcColdCallHeuristics(const BasicBlock *BB); + bool calcPointerHeuristics(const BasicBlock *BB); + bool calcLoopBranchHeuristics(const BasicBlock *BB, const LoopInfo &LI); + bool calcZeroHeuristics(const BasicBlock *BB); + bool calcFloatingPointHeuristics(const BasicBlock *BB); + 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. |