Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line | 
|---|---|---|---|
| 14 | pmbaty | 1 | //===- BranchProbabilityInfo.h - Branch Probability Analysis ----*- 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 pass is used to evaluate branch probabilties. | ||
| 10 | // | ||
| 11 | //===----------------------------------------------------------------------===// | ||
| 12 | |||
| 13 | #ifndef LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H | ||
| 14 | #define LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H | ||
| 15 | |||
| 16 | #include "llvm/ADT/DenseMap.h" | ||
| 17 | #include "llvm/ADT/DenseMapInfo.h" | ||
| 18 | #include "llvm/ADT/DenseSet.h" | ||
| 19 | #include "llvm/IR/BasicBlock.h" | ||
| 20 | #include "llvm/IR/CFG.h" | ||
| 21 | #include "llvm/IR/PassManager.h" | ||
| 22 | #include "llvm/IR/ValueHandle.h" | ||
| 23 | #include "llvm/Pass.h" | ||
| 24 | #include "llvm/Support/BranchProbability.h" | ||
| 25 | #include <algorithm> | ||
| 26 | #include <cassert> | ||
| 27 | #include <cstdint> | ||
| 28 | #include <memory> | ||
| 29 | #include <utility> | ||
| 30 | |||
| 31 | namespace llvm { | ||
| 32 | |||
| 33 | class Function; | ||
| 34 | class Loop; | ||
| 35 | class LoopInfo; | ||
| 36 | class raw_ostream; | ||
| 37 | class DominatorTree; | ||
| 38 | class PostDominatorTree; | ||
| 39 | class TargetLibraryInfo; | ||
| 40 | class Value; | ||
| 41 | |||
| 42 | /// Analysis providing branch probability information. | ||
| 43 | /// | ||
| 44 | /// This is a function analysis which provides information on the relative | ||
| 45 | /// probabilities of each "edge" in the function's CFG where such an edge is | ||
| 46 | /// defined by a pair (PredBlock and an index in the successors). The | ||
| 47 | /// probability of an edge from one block is always relative to the | ||
| 48 | /// probabilities of other edges from the block. The probabilites of all edges | ||
| 49 | /// from a block sum to exactly one (100%). | ||
| 50 | /// We use a pair (PredBlock and an index in the successors) to uniquely | ||
| 51 | /// identify an edge, since we can have multiple edges from Src to Dst. | ||
| 52 | /// As an example, we can have a switch which jumps to Dst with value 0 and | ||
| 53 | /// value 10. | ||
| 54 | /// | ||
| 55 | /// Process of computing branch probabilities can be logically viewed as three | ||
| 56 | /// step process: | ||
| 57 | /// | ||
| 58 | ///   First, if there is a profile information associated with the branch then | ||
| 59 | /// it is trivially translated to branch probabilities. There is one exception | ||
| 60 | /// from this rule though. Probabilities for edges leading to "unreachable" | ||
| 61 | /// blocks (blocks with the estimated weight not greater than | ||
| 62 | /// UNREACHABLE_WEIGHT) are evaluated according to static estimation and | ||
| 63 | /// override profile information. If no branch probabilities were calculated | ||
| 64 | /// on this step then take the next one. | ||
| 65 | /// | ||
| 66 | ///   Second, estimate absolute execution weights for each block based on | ||
| 67 | /// statically known information. Roots of such information are "cold", | ||
| 68 | /// "unreachable", "noreturn" and "unwind" blocks. Those blocks get their | ||
| 69 | /// weights set to BlockExecWeight::COLD, BlockExecWeight::UNREACHABLE, | ||
| 70 | /// BlockExecWeight::NORETURN and BlockExecWeight::UNWIND respectively. Then the | ||
| 71 | /// weights are propagated to the other blocks up the domination line. In | ||
| 72 | /// addition, if all successors have estimated weights set then maximum of these | ||
| 73 | /// weights assigned to the block itself (while this is not ideal heuristic in | ||
| 74 | /// theory it's simple and works reasonably well in most cases) and the process | ||
| 75 | /// repeats. Once the process of weights propagation converges branch | ||
| 76 | /// probabilities are set for all such branches that have at least one successor | ||
| 77 | /// with the weight set. Default execution weight (BlockExecWeight::DEFAULT) is | ||
| 78 | /// used for any successors which doesn't have its weight set. For loop back | ||
| 79 | /// branches we use their weights scaled by loop trip count equal to | ||
| 80 | /// 'LBH_TAKEN_WEIGHT/LBH_NOTTAKEN_WEIGHT'. | ||
| 81 | /// | ||
| 82 | /// Here is a simple example demonstrating how the described algorithm works. | ||
| 83 | /// | ||
| 84 | ///          BB1 | ||
| 85 | ///         /   \ | ||
| 86 | ///        v     v | ||
| 87 | ///      BB2     BB3 | ||
| 88 | ///     /   \ | ||
| 89 | ///    v     v | ||
| 90 | ///  ColdBB  UnreachBB | ||
| 91 | /// | ||
| 92 | /// Initially, ColdBB is associated with COLD_WEIGHT and UnreachBB with | ||
| 93 | /// UNREACHABLE_WEIGHT. COLD_WEIGHT is set to BB2 as maximum between its | ||
| 94 | /// successors. BB1 and BB3 has no explicit estimated weights and assumed to | ||
| 95 | /// have DEFAULT_WEIGHT. Based on assigned weights branches will have the | ||
| 96 | /// following probabilities: | ||
| 97 | /// P(BB1->BB2) = COLD_WEIGHT/(COLD_WEIGHT + DEFAULT_WEIGHT) = | ||
| 98 | ///   0xffff / (0xffff + 0xfffff) = 0.0588(5.9%) | ||
| 99 | /// P(BB1->BB3) = DEFAULT_WEIGHT_WEIGHT/(COLD_WEIGHT + DEFAULT_WEIGHT) = | ||
| 100 | ///          0xfffff / (0xffff + 0xfffff) = 0.941(94.1%) | ||
| 101 | /// P(BB2->ColdBB) = COLD_WEIGHT/(COLD_WEIGHT + UNREACHABLE_WEIGHT) = 1(100%) | ||
| 102 | /// P(BB2->UnreachBB) = | ||
| 103 | ///   UNREACHABLE_WEIGHT/(COLD_WEIGHT+UNREACHABLE_WEIGHT) = 0(0%) | ||
| 104 | /// | ||
| 105 | /// If no branch probabilities were calculated on this step then take the next | ||
| 106 | /// one. | ||
| 107 | /// | ||
| 108 | ///   Third, apply different kinds of local heuristics for each individual | ||
| 109 | /// branch until first match. For example probability of a pointer to be null is | ||
| 110 | /// estimated as PH_TAKEN_WEIGHT/(PH_TAKEN_WEIGHT + PH_NONTAKEN_WEIGHT). If | ||
| 111 | /// no local heuristic has been matched then branch is left with no explicit | ||
| 112 | /// probability set and assumed to have default probability. | ||
| 113 | class BranchProbabilityInfo { | ||
| 114 | public: | ||
| 115 | BranchProbabilityInfo() = default; | ||
| 116 | |||
| 117 | BranchProbabilityInfo(const Function &F, const LoopInfo &LI, | ||
| 118 | const TargetLibraryInfo *TLI = nullptr, | ||
| 119 | DominatorTree *DT = nullptr, | ||
| 120 | PostDominatorTree *PDT = nullptr) { | ||
| 121 | calculate(F, LI, TLI, DT, PDT); | ||
| 122 |   } | ||
| 123 | |||
| 124 | BranchProbabilityInfo(BranchProbabilityInfo &&Arg) | ||
| 125 | : Probs(std::move(Arg.Probs)), LastF(Arg.LastF), | ||
| 126 | EstimatedBlockWeight(std::move(Arg.EstimatedBlockWeight)) {} | ||
| 127 | |||
| 128 | BranchProbabilityInfo(const BranchProbabilityInfo &) = delete; | ||
| 129 | BranchProbabilityInfo &operator=(const BranchProbabilityInfo &) = delete; | ||
| 130 | |||
| 131 | BranchProbabilityInfo &operator=(BranchProbabilityInfo &&RHS) { | ||
| 132 | releaseMemory(); | ||
| 133 | Probs = std::move(RHS.Probs); | ||
| 134 | EstimatedBlockWeight = std::move(RHS.EstimatedBlockWeight); | ||
| 135 | return *this; | ||
| 136 |   } | ||
| 137 | |||
| 138 | bool invalidate(Function &, const PreservedAnalyses &PA, | ||
| 139 | FunctionAnalysisManager::Invalidator &); | ||
| 140 | |||
| 141 | void releaseMemory(); | ||
| 142 | |||
| 143 | void print(raw_ostream &OS) const; | ||
| 144 | |||
| 145 |   /// Get an edge's probability, relative to other out-edges of the Src. | ||
| 146 |   /// | ||
| 147 |   /// This routine provides access to the fractional probability between zero | ||
| 148 |   /// (0%) and one (100%) of this edge executing, relative to other edges | ||
| 149 |   /// leaving the 'Src' block. The returned probability is never zero, and can | ||
| 150 |   /// only be one if the source block has only one successor. | ||
| 151 | BranchProbability getEdgeProbability(const BasicBlock *Src, | ||
| 152 | unsigned IndexInSuccessors) const; | ||
| 153 | |||
| 154 |   /// Get the probability of going from Src to Dst. | ||
| 155 |   /// | ||
| 156 |   /// It returns the sum of all probabilities for edges from Src to Dst. | ||
| 157 | BranchProbability getEdgeProbability(const BasicBlock *Src, | ||
| 158 | const BasicBlock *Dst) const; | ||
| 159 | |||
| 160 | BranchProbability getEdgeProbability(const BasicBlock *Src, | ||
| 161 | const_succ_iterator Dst) const; | ||
| 162 | |||
| 163 |   /// Test if an edge is hot relative to other out-edges of the Src. | ||
| 164 |   /// | ||
| 165 |   /// Check whether this edge out of the source block is 'hot'. We define hot | ||
| 166 |   /// as having a relative probability >= 80%. | ||
| 167 | bool isEdgeHot(const BasicBlock *Src, const BasicBlock *Dst) const; | ||
| 168 | |||
| 169 |   /// Print an edge's probability. | ||
| 170 |   /// | ||
| 171 |   /// Retrieves an edge's probability similarly to \see getEdgeProbability, but | ||
| 172 |   /// then prints that probability to the provided stream. That stream is then | ||
| 173 |   /// returned. | ||
| 174 | raw_ostream &printEdgeProbability(raw_ostream &OS, const BasicBlock *Src, | ||
| 175 | const BasicBlock *Dst) const; | ||
| 176 | |||
| 177 | public: | ||
| 178 |   /// Set the raw probabilities for all edges from the given block. | ||
| 179 |   /// | ||
| 180 |   /// This allows a pass to explicitly set edge probabilities for a block. It | ||
| 181 |   /// can be used when updating the CFG to update the branch probability | ||
| 182 |   /// information. | ||
| 183 | void setEdgeProbability(const BasicBlock *Src, | ||
| 184 | const SmallVectorImpl<BranchProbability> &Probs); | ||
| 185 | |||
| 186 |   /// Copy outgoing edge probabilities from \p Src to \p Dst. | ||
| 187 |   /// | ||
| 188 |   /// This allows to keep probabilities unset for the destination if they were | ||
| 189 |   /// unset for source. | ||
| 190 | void copyEdgeProbabilities(BasicBlock *Src, BasicBlock *Dst); | ||
| 191 | |||
| 192 | static BranchProbability getBranchProbStackProtector(bool IsLikely) { | ||
| 193 | static const BranchProbability LikelyProb((1u << 20) - 1, 1u << 20); | ||
| 194 | return IsLikely ? LikelyProb : LikelyProb.getCompl(); | ||
| 195 |   } | ||
| 196 | |||
| 197 | void calculate(const Function &F, const LoopInfo &LI, | ||
| 198 | const TargetLibraryInfo *TLI, DominatorTree *DT, | ||
| 199 | PostDominatorTree *PDT); | ||
| 200 | |||
| 201 |   /// Forget analysis results for the given basic block. | ||
| 202 | void eraseBlock(const BasicBlock *BB); | ||
| 203 | |||
| 204 |   // Data structure to track SCCs for handling irreducible loops. | ||
| 205 | class SccInfo { | ||
| 206 |     // Enum of types to classify basic blocks in SCC. Basic block belonging to | ||
| 207 |     // SCC is 'Inner' until it is either 'Header' or 'Exiting'. Note that a | ||
| 208 |     // basic block can be 'Header' and 'Exiting' at the same time. | ||
| 209 | enum SccBlockType { | ||
| 210 | Inner = 0x0, | ||
| 211 | Header = 0x1, | ||
| 212 | Exiting = 0x2, | ||
| 213 | }; | ||
| 214 |     // Map of basic blocks to SCC IDs they belong to. If basic block doesn't | ||
| 215 |     // belong to any SCC it is not in the map. | ||
| 216 | using SccMap = DenseMap<const BasicBlock *, int>; | ||
| 217 |     // Each basic block in SCC is attributed with one or several types from | ||
| 218 |     // SccBlockType. Map value has uint32_t type (instead of SccBlockType) | ||
| 219 |     // since basic block may be for example "Header" and "Exiting" at the same | ||
| 220 |     // time and we need to be able to keep more than one value from | ||
| 221 |     // SccBlockType. | ||
| 222 | using SccBlockTypeMap = DenseMap<const BasicBlock *, uint32_t>; | ||
| 223 |     // Vector containing classification of basic blocks for all  SCCs where i'th | ||
| 224 |     // vector element corresponds to SCC with ID equal to i. | ||
| 225 | using SccBlockTypeMaps = std::vector<SccBlockTypeMap>; | ||
| 226 | |||
| 227 |     SccMap SccNums; | ||
| 228 |     SccBlockTypeMaps SccBlocks; | ||
| 229 | |||
| 230 | public: | ||
| 231 | explicit SccInfo(const Function &F); | ||
| 232 | |||
| 233 |     /// If \p BB belongs to some SCC then ID of that SCC is returned, otherwise | ||
| 234 |     /// -1 is returned. If \p BB belongs to more than one SCC at the same time | ||
| 235 |     /// result is undefined. | ||
| 236 | int getSCCNum(const BasicBlock *BB) const; | ||
| 237 |     /// Returns true if \p BB is a 'header' block in SCC with \p SccNum ID, | ||
| 238 |     /// false otherwise. | ||
| 239 | bool isSCCHeader(const BasicBlock *BB, int SccNum) const { | ||
| 240 | return getSccBlockType(BB, SccNum) & Header; | ||
| 241 |     } | ||
| 242 |     /// Returns true if \p BB is an 'exiting' block in SCC with \p SccNum ID, | ||
| 243 |     /// false otherwise. | ||
| 244 | bool isSCCExitingBlock(const BasicBlock *BB, int SccNum) const { | ||
| 245 | return getSccBlockType(BB, SccNum) & Exiting; | ||
| 246 |     } | ||
| 247 |     /// Fills in \p Enters vector with all such blocks that don't belong to | ||
| 248 |     /// SCC with \p SccNum ID but there is an edge to a block belonging to the | ||
| 249 |     /// SCC. | ||
| 250 | void getSccEnterBlocks(int SccNum, | ||
| 251 | SmallVectorImpl<BasicBlock *> &Enters) const; | ||
| 252 |     /// Fills in \p Exits vector with all such blocks that don't belong to | ||
| 253 |     /// SCC with \p SccNum ID but there is an edge from a block belonging to the | ||
| 254 |     /// SCC. | ||
| 255 | void getSccExitBlocks(int SccNum, | ||
| 256 | SmallVectorImpl<BasicBlock *> &Exits) const; | ||
| 257 | |||
| 258 | private: | ||
| 259 |     /// Returns \p BB's type according to classification given by SccBlockType | ||
| 260 |     /// enum. Please note that \p BB must belong to SSC with \p SccNum ID. | ||
| 261 | uint32_t getSccBlockType(const BasicBlock *BB, int SccNum) const; | ||
| 262 |     /// Calculates \p BB's type and stores it in internal data structures for | ||
| 263 |     /// future use. Please note that \p BB must belong to SSC with \p SccNum ID. | ||
| 264 | void calculateSccBlockType(const BasicBlock *BB, int SccNum); | ||
| 265 | }; | ||
| 266 | |||
| 267 | private: | ||
| 268 |   // We need to store CallbackVH's in order to correctly handle basic block | ||
| 269 |   // removal. | ||
| 270 | class BasicBlockCallbackVH final : public CallbackVH { | ||
| 271 | BranchProbabilityInfo *BPI; | ||
| 272 | |||
| 273 | void deleted() override { | ||
| 274 | assert(BPI != nullptr); | ||
| 275 | BPI->eraseBlock(cast<BasicBlock>(getValPtr())); | ||
| 276 |     } | ||
| 277 | |||
| 278 | public: | ||
| 279 | BasicBlockCallbackVH(const Value *V, BranchProbabilityInfo *BPI = nullptr) | ||
| 280 | : CallbackVH(const_cast<Value *>(V)), BPI(BPI) {} | ||
| 281 | }; | ||
| 282 | |||
| 283 |   /// Pair of Loop and SCC ID number. Used to unify handling of normal and | ||
| 284 |   /// SCC based loop representations. | ||
| 285 | using LoopData = std::pair<Loop *, int>; | ||
| 286 |   /// Helper class to keep basic block along with its loop data information. | ||
| 287 | class LoopBlock { | ||
| 288 | public: | ||
| 289 | explicit LoopBlock(const BasicBlock *BB, const LoopInfo &LI, | ||
| 290 | const SccInfo &SccI); | ||
| 291 | |||
| 292 | const BasicBlock *getBlock() const { return BB; } | ||
| 293 | BasicBlock *getBlock() { return const_cast<BasicBlock *>(BB); } | ||
| 294 | LoopData getLoopData() const { return LD; } | ||
| 295 | Loop *getLoop() const { return LD.first; } | ||
| 296 | int getSccNum() const { return LD.second; } | ||
| 297 | |||
| 298 | bool belongsToLoop() const { return getLoop() || getSccNum() != -1; } | ||
| 299 | bool belongsToSameLoop(const LoopBlock &LB) const { | ||
| 300 | return (LB.getLoop() && getLoop() == LB.getLoop()) || | ||
| 301 | (LB.getSccNum() != -1 && getSccNum() == LB.getSccNum()); | ||
| 302 |     } | ||
| 303 | |||
| 304 | private: | ||
| 305 | const BasicBlock *const BB = nullptr; | ||
| 306 | LoopData LD = {nullptr, -1}; | ||
| 307 | }; | ||
| 308 | |||
| 309 |   // Pair of LoopBlocks representing an edge from first to second block. | ||
| 310 | using LoopEdge = std::pair<const LoopBlock &, const LoopBlock &>; | ||
| 311 | |||
| 312 | DenseSet<BasicBlockCallbackVH, DenseMapInfo<Value*>> Handles; | ||
| 313 | |||
| 314 |   // Since we allow duplicate edges from one basic block to another, we use | ||
| 315 |   // a pair (PredBlock and an index in the successors) to specify an edge. | ||
| 316 | using Edge = std::pair<const BasicBlock *, unsigned>; | ||
| 317 | |||
| 318 | DenseMap<Edge, BranchProbability> Probs; | ||
| 319 | |||
| 320 |   /// Track the last function we run over for printing. | ||
| 321 | const Function *LastF = nullptr; | ||
| 322 | |||
| 323 | const LoopInfo *LI = nullptr; | ||
| 324 | |||
| 325 |   /// Keeps information about all SCCs in a function. | ||
| 326 | std::unique_ptr<const SccInfo> SccI; | ||
| 327 | |||
| 328 |   /// Keeps mapping of a basic block to its estimated weight. | ||
| 329 | SmallDenseMap<const BasicBlock *, uint32_t> EstimatedBlockWeight; | ||
| 330 | |||
| 331 |   /// Keeps mapping of a loop to estimated weight to enter the loop. | ||
| 332 | SmallDenseMap<LoopData, uint32_t> EstimatedLoopWeight; | ||
| 333 | |||
| 334 |   /// Helper to construct LoopBlock for \p BB. | ||
| 335 | LoopBlock getLoopBlock(const BasicBlock *BB) const { | ||
| 336 | return LoopBlock(BB, *LI, *SccI.get()); | ||
| 337 |   } | ||
| 338 | |||
| 339 |   /// Returns true if destination block belongs to some loop and source block is | ||
| 340 |   /// either doesn't belong to any loop or belongs to a loop which is not inner | ||
| 341 |   /// relative to the destination block. | ||
| 342 | bool isLoopEnteringEdge(const LoopEdge &Edge) const; | ||
| 343 |   /// Returns true if source block belongs to some loop and destination block is | ||
| 344 |   /// either doesn't belong to any loop or belongs to a loop which is not inner | ||
| 345 |   /// relative to the source block. | ||
| 346 | bool isLoopExitingEdge(const LoopEdge &Edge) const; | ||
| 347 |   /// Returns true if \p Edge is either enters to or exits from some loop, false | ||
| 348 |   /// in all other cases. | ||
| 349 | bool isLoopEnteringExitingEdge(const LoopEdge &Edge) const; | ||
| 350 |   /// Returns true if source and destination blocks belongs to the same loop and | ||
| 351 |   /// destination block is loop header. | ||
| 352 | bool isLoopBackEdge(const LoopEdge &Edge) const; | ||
| 353 |   // Fills in \p Enters vector with all "enter" blocks to a loop \LB belongs to. | ||
| 354 | void getLoopEnterBlocks(const LoopBlock &LB, | ||
| 355 | SmallVectorImpl<BasicBlock *> &Enters) const; | ||
| 356 |   // Fills in \p Exits vector with all "exit" blocks from a loop \LB belongs to. | ||
| 357 | void getLoopExitBlocks(const LoopBlock &LB, | ||
| 358 | SmallVectorImpl<BasicBlock *> &Exits) const; | ||
| 359 | |||
| 360 |   /// Returns estimated weight for \p BB. std::nullopt if \p BB has no estimated | ||
| 361 |   /// weight. | ||
| 362 | std::optional<uint32_t> getEstimatedBlockWeight(const BasicBlock *BB) const; | ||
| 363 | |||
| 364 |   /// Returns estimated weight to enter \p L. In other words it is weight of | ||
| 365 |   /// loop's header block not scaled by trip count. Returns std::nullopt if \p L | ||
| 366 |   /// has no no estimated weight. | ||
| 367 | std::optional<uint32_t> getEstimatedLoopWeight(const LoopData &L) const; | ||
| 368 | |||
| 369 |   /// Return estimated weight for \p Edge. Returns std::nullopt if estimated | ||
| 370 |   /// weight is unknown. | ||
| 371 | std::optional<uint32_t> getEstimatedEdgeWeight(const LoopEdge &Edge) const; | ||
| 372 | |||
| 373 |   /// Iterates over all edges leading from \p SrcBB to \p Successors and | ||
| 374 |   /// returns maximum of all estimated weights. If at least one edge has unknown | ||
| 375 |   /// estimated weight std::nullopt is returned. | ||
| 376 | template <class IterT> | ||
| 377 | std::optional<uint32_t> | ||
| 378 | getMaxEstimatedEdgeWeight(const LoopBlock &SrcBB, | ||
| 379 | iterator_range<IterT> Successors) const; | ||
| 380 | |||
| 381 |   /// If \p LoopBB has no estimated weight then set it to \p BBWeight and | ||
| 382 |   /// return true. Otherwise \p BB's weight remains unchanged and false is | ||
| 383 |   /// returned. In addition all blocks/loops that might need their weight to be | ||
| 384 |   /// re-estimated are put into BlockWorkList/LoopWorkList. | ||
| 385 | bool updateEstimatedBlockWeight(LoopBlock &LoopBB, uint32_t BBWeight, | ||
| 386 | SmallVectorImpl<BasicBlock *> &BlockWorkList, | ||
| 387 | SmallVectorImpl<LoopBlock> &LoopWorkList); | ||
| 388 | |||
| 389 |   /// Starting from \p LoopBB (including \p LoopBB itself) propagate \p BBWeight | ||
| 390 |   /// up the domination tree. | ||
| 391 | void propagateEstimatedBlockWeight(const LoopBlock &LoopBB, DominatorTree *DT, | ||
| 392 | PostDominatorTree *PDT, uint32_t BBWeight, | ||
| 393 | SmallVectorImpl<BasicBlock *> &WorkList, | ||
| 394 | SmallVectorImpl<LoopBlock> &LoopWorkList); | ||
| 395 | |||
| 396 |   /// Returns block's weight encoded in the IR. | ||
| 397 | std::optional<uint32_t> getInitialEstimatedBlockWeight(const BasicBlock *BB); | ||
| 398 | |||
| 399 |   // Computes estimated weights for all blocks in \p F. | ||
| 400 | void computeEestimateBlockWeight(const Function &F, DominatorTree *DT, | ||
| 401 | PostDominatorTree *PDT); | ||
| 402 | |||
| 403 |   /// Based on computed weights by \p computeEstimatedBlockWeight set | ||
| 404 |   /// probabilities on branches. | ||
| 405 | bool calcEstimatedHeuristics(const BasicBlock *BB); | ||
| 406 | bool calcMetadataWeights(const BasicBlock *BB); | ||
| 407 | bool calcPointerHeuristics(const BasicBlock *BB); | ||
| 408 | bool calcZeroHeuristics(const BasicBlock *BB, const TargetLibraryInfo *TLI); | ||
| 409 | bool calcFloatingPointHeuristics(const BasicBlock *BB); | ||
| 410 | }; | ||
| 411 | |||
| 412 | /// Analysis pass which computes \c BranchProbabilityInfo. | ||
| 413 | class BranchProbabilityAnalysis | ||
| 414 | : public AnalysisInfoMixin<BranchProbabilityAnalysis> { | ||
| 415 | friend AnalysisInfoMixin<BranchProbabilityAnalysis>; | ||
| 416 | |||
| 417 | static AnalysisKey Key; | ||
| 418 | |||
| 419 | public: | ||
| 420 |   /// Provide the result type for this analysis pass. | ||
| 421 | using Result = BranchProbabilityInfo; | ||
| 422 | |||
| 423 |   /// Run the analysis pass over a function and produce BPI. | ||
| 424 | BranchProbabilityInfo run(Function &F, FunctionAnalysisManager &AM); | ||
| 425 | }; | ||
| 426 | |||
| 427 | /// Printer pass for the \c BranchProbabilityAnalysis results. | ||
| 428 | class BranchProbabilityPrinterPass | ||
| 429 | : public PassInfoMixin<BranchProbabilityPrinterPass> { | ||
| 430 | raw_ostream &OS; | ||
| 431 | |||
| 432 | public: | ||
| 433 | explicit BranchProbabilityPrinterPass(raw_ostream &OS) : OS(OS) {} | ||
| 434 | |||
| 435 | PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); | ||
| 436 | }; | ||
| 437 | |||
| 438 | /// Legacy analysis pass which computes \c BranchProbabilityInfo. | ||
| 439 | class BranchProbabilityInfoWrapperPass : public FunctionPass { | ||
| 440 |   BranchProbabilityInfo BPI; | ||
| 441 | |||
| 442 | public: | ||
| 443 | static char ID; | ||
| 444 | |||
| 445 | BranchProbabilityInfoWrapperPass(); | ||
| 446 | |||
| 447 | BranchProbabilityInfo &getBPI() { return BPI; } | ||
| 448 | const BranchProbabilityInfo &getBPI() const { return BPI; } | ||
| 449 | |||
| 450 | void getAnalysisUsage(AnalysisUsage &AU) const override; | ||
| 451 | bool runOnFunction(Function &F) override; | ||
| 452 | void releaseMemory() override; | ||
| 453 | void print(raw_ostream &OS, const Module *M = nullptr) const override; | ||
| 454 | }; | ||
| 455 | |||
| 456 | } // end namespace llvm | ||
| 457 | |||
| 458 | #endif // LLVM_ANALYSIS_BRANCHPROBABILITYINFO_H |