138c02bc7SEugene Zelenko //===- BranchProbabilityInfo.cpp - Branch Probability Analysis ------------===//
249371f3fSAndrew Trick //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
649371f3fSAndrew Trick //
749371f3fSAndrew Trick //===----------------------------------------------------------------------===//
849371f3fSAndrew Trick //
949371f3fSAndrew Trick // Loops should be simplified before this analysis.
1049371f3fSAndrew Trick //
1149371f3fSAndrew Trick //===----------------------------------------------------------------------===//
1249371f3fSAndrew Trick
13ed0881b2SChandler Carruth #include "llvm/Analysis/BranchProbabilityInfo.h"
14ed0881b2SChandler Carruth #include "llvm/ADT/PostOrderIterator.h"
15eed6531eSGeoff Berry #include "llvm/ADT/SCCIterator.h"
1638c02bc7SEugene Zelenko #include "llvm/ADT/STLExtras.h"
1738c02bc7SEugene Zelenko #include "llvm/ADT/SmallVector.h"
18f93cd562SNikita Popov #include "llvm/Analysis/ConstantFolding.h"
19ed0881b2SChandler Carruth #include "llvm/Analysis/LoopInfo.h"
202da205d4STaewook Oh #include "llvm/Analysis/PostDominators.h"
21da4a68a1SJohn Brawn #include "llvm/Analysis/TargetLibraryInfo.h"
2238c02bc7SEugene Zelenko #include "llvm/IR/Attributes.h"
2338c02bc7SEugene Zelenko #include "llvm/IR/BasicBlock.h"
241305dc33SChandler Carruth #include "llvm/IR/CFG.h"
259fb823bbSChandler Carruth #include "llvm/IR/Constants.h"
262ca16899SMikael Holmen #include "llvm/IR/Dominators.h"
279fb823bbSChandler Carruth #include "llvm/IR/Function.h"
2838c02bc7SEugene Zelenko #include "llvm/IR/InstrTypes.h"
2938c02bc7SEugene Zelenko #include "llvm/IR/Instruction.h"
309fb823bbSChandler Carruth #include "llvm/IR/Instructions.h"
319fb823bbSChandler Carruth #include "llvm/IR/LLVMContext.h"
329fb823bbSChandler Carruth #include "llvm/IR/Metadata.h"
3338c02bc7SEugene Zelenko #include "llvm/IR/PassManager.h"
3438c02bc7SEugene Zelenko #include "llvm/IR/Type.h"
3538c02bc7SEugene Zelenko #include "llvm/IR/Value.h"
3605da2fe5SReid Kleckner #include "llvm/InitializePasses.h"
3738c02bc7SEugene Zelenko #include "llvm/Pass.h"
3838c02bc7SEugene Zelenko #include "llvm/Support/BranchProbability.h"
3938c02bc7SEugene Zelenko #include "llvm/Support/Casting.h"
404c1a1d3cSReid Kleckner #include "llvm/Support/CommandLine.h"
413d4e64b0SAndrew Trick #include "llvm/Support/Debug.h"
4216132e6fSBenjamin Kramer #include "llvm/Support/raw_ostream.h"
4338c02bc7SEugene Zelenko #include <cassert>
4438c02bc7SEugene Zelenko #include <cstdint>
4538c02bc7SEugene Zelenko #include <iterator>
46d8bff13aSNikita Popov #include <map>
4738c02bc7SEugene Zelenko #include <utility>
4849371f3fSAndrew Trick
4949371f3fSAndrew Trick using namespace llvm;
5049371f3fSAndrew Trick
51f1221bd0SChandler Carruth #define DEBUG_TYPE "branch-prob"
52f1221bd0SChandler Carruth
5363e17ebfSHiroshi Yamauchi static cl::opt<bool> PrintBranchProb(
5463e17ebfSHiroshi Yamauchi "print-bpi", cl::init(false), cl::Hidden,
5563e17ebfSHiroshi Yamauchi cl::desc("Print the branch probability info."));
5663e17ebfSHiroshi Yamauchi
5763e17ebfSHiroshi Yamauchi cl::opt<std::string> PrintBranchProbFuncName(
5863e17ebfSHiroshi Yamauchi "print-bpi-func-name", cl::Hidden,
5963e17ebfSHiroshi Yamauchi cl::desc("The option to specify the name of the function "
6063e17ebfSHiroshi Yamauchi "whose branch probability info is printed."));
6163e17ebfSHiroshi Yamauchi
62ab23bfbcSCong Hou INITIALIZE_PASS_BEGIN(BranchProbabilityInfoWrapperPass, "branch-prob",
6349371f3fSAndrew Trick "Branch Probability Analysis", false, true)
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)644f8f307cSChandler Carruth INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
65da4a68a1SJohn Brawn INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
669fb074e7SEvgeniy Brevnov INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
673e68a667SEvgeniy Brevnov INITIALIZE_PASS_DEPENDENCY(PostDominatorTreeWrapperPass)
68ab23bfbcSCong Hou INITIALIZE_PASS_END(BranchProbabilityInfoWrapperPass, "branch-prob",
6949371f3fSAndrew Trick "Branch Probability Analysis", false, true)
7049371f3fSAndrew Trick
7105da2fe5SReid Kleckner BranchProbabilityInfoWrapperPass::BranchProbabilityInfoWrapperPass()
7205da2fe5SReid Kleckner : FunctionPass(ID) {
7305da2fe5SReid Kleckner initializeBranchProbabilityInfoWrapperPassPass(
7405da2fe5SReid Kleckner *PassRegistry::getPassRegistry());
7505da2fe5SReid Kleckner }
7605da2fe5SReid Kleckner
77ab23bfbcSCong Hou char BranchProbabilityInfoWrapperPass::ID = 0;
7849371f3fSAndrew Trick
7949371f3fSAndrew Trick // Weights are for internal use only. They are used by heuristics to help to
8049371f3fSAndrew Trick // estimate edges' probability. Example:
8149371f3fSAndrew Trick //
8249371f3fSAndrew Trick // Using "Loop Branch Heuristics" we predict weights of edges for the
8349371f3fSAndrew Trick // block BB2.
8449371f3fSAndrew Trick // ...
8549371f3fSAndrew Trick // |
8649371f3fSAndrew Trick // V
8749371f3fSAndrew Trick // BB1<-+
8849371f3fSAndrew Trick // | |
89eec01ccbSJakub Staszak // | | (Weight = 124)
9049371f3fSAndrew Trick // V |
9149371f3fSAndrew Trick // BB2--+
9249371f3fSAndrew Trick // |
9349371f3fSAndrew Trick // | (Weight = 4)
9449371f3fSAndrew Trick // V
9549371f3fSAndrew Trick // BB3
9649371f3fSAndrew Trick //
97eec01ccbSJakub Staszak // Probability of the edge BB2->BB1 = 124 / (124 + 4) = 0.96875
98eec01ccbSJakub Staszak // Probability of the edge BB2->BB3 = 4 / (124 + 4) = 0.03125
99eec01ccbSJakub Staszak static const uint32_t LBH_TAKEN_WEIGHT = 124;
1003d4e64b0SAndrew Trick static const uint32_t LBH_NONTAKEN_WEIGHT = 4;
10149371f3fSAndrew Trick
1025f8f34e4SAdrian Prantl /// Unreachable-terminating branch taken probability.
1037111f456SChandler Carruth ///
104ba831f78SSerguei Katkov /// This is the probability for a branch being taken to a block that terminates
1057111f456SChandler Carruth /// (eventually) in unreachable. These are predicted as unlikely as possible.
10607239c73SYevgeny Rouban /// All reachable probability will proportionally share the remaining part.
107ba831f78SSerguei Katkov static const BranchProbability UR_TAKEN_PROB = BranchProbability::getRaw(1);
1082616bbb1SSerguei Katkov
1094d21b644SSjoerd Meijer /// Heuristics and lookup tables for non-loop branches:
1104d21b644SSjoerd Meijer /// Pointer Heuristics (PH)
11109784268SJakub Staszak static const uint32_t PH_TAKEN_WEIGHT = 20;
11209784268SJakub Staszak static const uint32_t PH_NONTAKEN_WEIGHT = 12;
1134d21b644SSjoerd Meijer static const BranchProbability
1144d21b644SSjoerd Meijer PtrTakenProb(PH_TAKEN_WEIGHT, PH_TAKEN_WEIGHT + PH_NONTAKEN_WEIGHT);
1154d21b644SSjoerd Meijer static const BranchProbability
1164d21b644SSjoerd Meijer PtrUntakenProb(PH_NONTAKEN_WEIGHT, PH_TAKEN_WEIGHT + PH_NONTAKEN_WEIGHT);
11709784268SJakub Staszak
1184d21b644SSjoerd Meijer using ProbabilityList = SmallVector<BranchProbability>;
1194d21b644SSjoerd Meijer using ProbabilityTable = std::map<CmpInst::Predicate, ProbabilityList>;
1204d21b644SSjoerd Meijer
1214d21b644SSjoerd Meijer /// Pointer comparisons:
1224d21b644SSjoerd Meijer static const ProbabilityTable PointerTable{
1234d21b644SSjoerd Meijer {ICmpInst::ICMP_NE, {PtrTakenProb, PtrUntakenProb}}, /// p != q -> Likely
1244d21b644SSjoerd Meijer {ICmpInst::ICMP_EQ, {PtrUntakenProb, PtrTakenProb}}, /// p == q -> Unlikely
1254d21b644SSjoerd Meijer };
1264d21b644SSjoerd Meijer
1274d21b644SSjoerd Meijer /// Zero Heuristics (ZH)
1280f14b2e6SDávid Bolvanský static const uint32_t ZH_TAKEN_WEIGHT = 20;
1290f14b2e6SDávid Bolvanský static const uint32_t ZH_NONTAKEN_WEIGHT = 12;
1304d21b644SSjoerd Meijer static const BranchProbability
1314d21b644SSjoerd Meijer ZeroTakenProb(ZH_TAKEN_WEIGHT, ZH_TAKEN_WEIGHT + ZH_NONTAKEN_WEIGHT);
1324d21b644SSjoerd Meijer static const BranchProbability
1334d21b644SSjoerd Meijer ZeroUntakenProb(ZH_NONTAKEN_WEIGHT, ZH_TAKEN_WEIGHT + ZH_NONTAKEN_WEIGHT);
13417af66a6SJakub Staszak
1354d21b644SSjoerd Meijer /// Integer compares with 0:
1364d21b644SSjoerd Meijer static const ProbabilityTable ICmpWithZeroTable{
1374d21b644SSjoerd Meijer {CmpInst::ICMP_EQ, {ZeroUntakenProb, ZeroTakenProb}}, /// X == 0 -> Unlikely
1384d21b644SSjoerd Meijer {CmpInst::ICMP_NE, {ZeroTakenProb, ZeroUntakenProb}}, /// X != 0 -> Likely
1394d21b644SSjoerd Meijer {CmpInst::ICMP_SLT, {ZeroUntakenProb, ZeroTakenProb}}, /// X < 0 -> Unlikely
1404d21b644SSjoerd Meijer {CmpInst::ICMP_SGT, {ZeroTakenProb, ZeroUntakenProb}}, /// X > 0 -> Likely
1414d21b644SSjoerd Meijer };
1424d21b644SSjoerd Meijer
1434d21b644SSjoerd Meijer /// Integer compares with -1:
1444d21b644SSjoerd Meijer static const ProbabilityTable ICmpWithMinusOneTable{
1454d21b644SSjoerd Meijer {CmpInst::ICMP_EQ, {ZeroUntakenProb, ZeroTakenProb}}, /// X == -1 -> Unlikely
1464d21b644SSjoerd Meijer {CmpInst::ICMP_NE, {ZeroTakenProb, ZeroUntakenProb}}, /// X != -1 -> Likely
1474d21b644SSjoerd Meijer // InstCombine canonicalizes X >= 0 into X > -1
1484d21b644SSjoerd Meijer {CmpInst::ICMP_SGT, {ZeroTakenProb, ZeroUntakenProb}}, /// X >= 0 -> Likely
1494d21b644SSjoerd Meijer };
1504d21b644SSjoerd Meijer
1514d21b644SSjoerd Meijer /// Integer compares with 1:
1524d21b644SSjoerd Meijer static const ProbabilityTable ICmpWithOneTable{
1534d21b644SSjoerd Meijer // InstCombine canonicalizes X <= 0 into X < 1
1544d21b644SSjoerd Meijer {CmpInst::ICMP_SLT, {ZeroUntakenProb, ZeroTakenProb}}, /// X <= 0 -> Unlikely
1554d21b644SSjoerd Meijer };
1564d21b644SSjoerd Meijer
1574d21b644SSjoerd Meijer /// strcmp and similar functions return zero, negative, or positive, if the
1584d21b644SSjoerd Meijer /// first string is equal, less, or greater than the second. We consider it
1594d21b644SSjoerd Meijer /// likely that the strings are not equal, so a comparison with zero is
1604d21b644SSjoerd Meijer /// probably false, but also a comparison with any other number is also
1614d21b644SSjoerd Meijer /// probably false given that what exactly is returned for nonzero values is
1624d21b644SSjoerd Meijer /// not specified. Any kind of comparison other than equality we know
1634d21b644SSjoerd Meijer /// nothing about.
1644d21b644SSjoerd Meijer static const ProbabilityTable ICmpWithLibCallTable{
1654d21b644SSjoerd Meijer {CmpInst::ICMP_EQ, {ZeroUntakenProb, ZeroTakenProb}},
1664d21b644SSjoerd Meijer {CmpInst::ICMP_NE, {ZeroTakenProb, ZeroUntakenProb}},
1674d21b644SSjoerd Meijer };
1684d21b644SSjoerd Meijer
1694d21b644SSjoerd Meijer // Floating-Point Heuristics (FPH)
1701e731a10SBenjamin Kramer static const uint32_t FPH_TAKEN_WEIGHT = 20;
1711e731a10SBenjamin Kramer static const uint32_t FPH_NONTAKEN_WEIGHT = 12;
1721e731a10SBenjamin Kramer
173b329e072SGuozhi Wei /// This is the probability for an ordered floating point comparison.
174b329e072SGuozhi Wei static const uint32_t FPH_ORD_WEIGHT = 1024 * 1024 - 1;
175b329e072SGuozhi Wei /// This is the probability for an unordered floating point comparison, it means
176b329e072SGuozhi Wei /// one or two of the operands are NaN. Usually it is used to test for an
177b329e072SGuozhi Wei /// exceptional case, so the result is unlikely.
178b329e072SGuozhi Wei static const uint32_t FPH_UNO_WEIGHT = 1;
179b329e072SGuozhi Wei
1804d21b644SSjoerd Meijer static const BranchProbability FPOrdTakenProb(FPH_ORD_WEIGHT,
1814d21b644SSjoerd Meijer FPH_ORD_WEIGHT + FPH_UNO_WEIGHT);
1824d21b644SSjoerd Meijer static const BranchProbability
1834d21b644SSjoerd Meijer FPOrdUntakenProb(FPH_UNO_WEIGHT, FPH_ORD_WEIGHT + FPH_UNO_WEIGHT);
1844d21b644SSjoerd Meijer static const BranchProbability
1854d21b644SSjoerd Meijer FPTakenProb(FPH_TAKEN_WEIGHT, FPH_TAKEN_WEIGHT + FPH_NONTAKEN_WEIGHT);
1864d21b644SSjoerd Meijer static const BranchProbability
1874d21b644SSjoerd Meijer FPUntakenProb(FPH_NONTAKEN_WEIGHT, FPH_TAKEN_WEIGHT + FPH_NONTAKEN_WEIGHT);
1884d21b644SSjoerd Meijer
1894d21b644SSjoerd Meijer /// Floating-Point compares:
1904d21b644SSjoerd Meijer static const ProbabilityTable FCmpTable{
1914d21b644SSjoerd Meijer {FCmpInst::FCMP_ORD, {FPOrdTakenProb, FPOrdUntakenProb}}, /// !isnan -> Likely
1924d21b644SSjoerd Meijer {FCmpInst::FCMP_UNO, {FPOrdUntakenProb, FPOrdTakenProb}}, /// isnan -> Unlikely
1934d21b644SSjoerd Meijer };
1944d21b644SSjoerd Meijer
1959fb074e7SEvgeniy Brevnov /// Set of dedicated "absolute" execution weights for a block. These weights are
1969fb074e7SEvgeniy Brevnov /// meaningful relative to each other and their derivatives only.
1979fb074e7SEvgeniy Brevnov enum class BlockExecWeight : std::uint32_t {
1989fb074e7SEvgeniy Brevnov /// Special weight used for cases with exact zero probability.
1999fb074e7SEvgeniy Brevnov ZERO = 0x0,
2009fb074e7SEvgeniy Brevnov /// Minimal possible non zero weight.
2019fb074e7SEvgeniy Brevnov LOWEST_NON_ZERO = 0x1,
2029fb074e7SEvgeniy Brevnov /// Weight to an 'unreachable' block.
2039fb074e7SEvgeniy Brevnov UNREACHABLE = ZERO,
2049fb074e7SEvgeniy Brevnov /// Weight to a block containing non returning call.
2059fb074e7SEvgeniy Brevnov NORETURN = LOWEST_NON_ZERO,
2069fb074e7SEvgeniy Brevnov /// Weight to 'unwind' block of an invoke instruction.
2079fb074e7SEvgeniy Brevnov UNWIND = LOWEST_NON_ZERO,
2089fb074e7SEvgeniy Brevnov /// Weight to a 'cold' block. Cold blocks are the ones containing calls marked
2099fb074e7SEvgeniy Brevnov /// with attribute 'cold'.
2109fb074e7SEvgeniy Brevnov COLD = 0xffff,
2119fb074e7SEvgeniy Brevnov /// Default weight is used in cases when there is no dedicated execution
2129fb074e7SEvgeniy Brevnov /// weight set. It is not propagated through the domination line either.
2139fb074e7SEvgeniy Brevnov DEFAULT = 0xfffff
2149fb074e7SEvgeniy Brevnov };
215e1c54262SBill Wendling
SccInfo(const Function & F)2163a2b05f9SEvgeniy Brevnov BranchProbabilityInfo::SccInfo::SccInfo(const Function &F) {
2173a2b05f9SEvgeniy Brevnov // Record SCC numbers of blocks in the CFG to identify irreducible loops.
2183a2b05f9SEvgeniy Brevnov // FIXME: We could only calculate this if the CFG is known to be irreducible
2193a2b05f9SEvgeniy Brevnov // (perhaps cache this info in LoopInfo if we can easily calculate it there?).
2203a2b05f9SEvgeniy Brevnov int SccNum = 0;
2213a2b05f9SEvgeniy Brevnov for (scc_iterator<const Function *> It = scc_begin(&F); !It.isAtEnd();
2223a2b05f9SEvgeniy Brevnov ++It, ++SccNum) {
2233a2b05f9SEvgeniy Brevnov // Ignore single-block SCCs since they either aren't loops or LoopInfo will
2243a2b05f9SEvgeniy Brevnov // catch them.
2253a2b05f9SEvgeniy Brevnov const std::vector<const BasicBlock *> &Scc = *It;
2263a2b05f9SEvgeniy Brevnov if (Scc.size() == 1)
2273a2b05f9SEvgeniy Brevnov continue;
2283a2b05f9SEvgeniy Brevnov
2293a2b05f9SEvgeniy Brevnov LLVM_DEBUG(dbgs() << "BPI: SCC " << SccNum << ":");
2303a2b05f9SEvgeniy Brevnov for (const auto *BB : Scc) {
2313a2b05f9SEvgeniy Brevnov LLVM_DEBUG(dbgs() << " " << BB->getName());
2323a2b05f9SEvgeniy Brevnov SccNums[BB] = SccNum;
2333a2b05f9SEvgeniy Brevnov calculateSccBlockType(BB, SccNum);
2343a2b05f9SEvgeniy Brevnov }
2353a2b05f9SEvgeniy Brevnov LLVM_DEBUG(dbgs() << "\n");
2363a2b05f9SEvgeniy Brevnov }
2373a2b05f9SEvgeniy Brevnov }
2383a2b05f9SEvgeniy Brevnov
getSCCNum(const BasicBlock * BB) const2393a2b05f9SEvgeniy Brevnov int BranchProbabilityInfo::SccInfo::getSCCNum(const BasicBlock *BB) const {
2403a2b05f9SEvgeniy Brevnov auto SccIt = SccNums.find(BB);
2413a2b05f9SEvgeniy Brevnov if (SccIt == SccNums.end())
2423a2b05f9SEvgeniy Brevnov return -1;
2433a2b05f9SEvgeniy Brevnov return SccIt->second;
2443a2b05f9SEvgeniy Brevnov }
2453a2b05f9SEvgeniy Brevnov
getSccEnterBlocks(int SccNum,SmallVectorImpl<BasicBlock * > & Enters) const2463a2b05f9SEvgeniy Brevnov void BranchProbabilityInfo::SccInfo::getSccEnterBlocks(
2473a2b05f9SEvgeniy Brevnov int SccNum, SmallVectorImpl<BasicBlock *> &Enters) const {
2483a2b05f9SEvgeniy Brevnov
2493a2b05f9SEvgeniy Brevnov for (auto MapIt : SccBlocks[SccNum]) {
2503a2b05f9SEvgeniy Brevnov const auto *BB = MapIt.first;
2513a2b05f9SEvgeniy Brevnov if (isSCCHeader(BB, SccNum))
2523a2b05f9SEvgeniy Brevnov for (const auto *Pred : predecessors(BB))
2533a2b05f9SEvgeniy Brevnov if (getSCCNum(Pred) != SccNum)
2543a2b05f9SEvgeniy Brevnov Enters.push_back(const_cast<BasicBlock *>(BB));
2553a2b05f9SEvgeniy Brevnov }
2563a2b05f9SEvgeniy Brevnov }
2573a2b05f9SEvgeniy Brevnov
getSccExitBlocks(int SccNum,SmallVectorImpl<BasicBlock * > & Exits) const2583a2b05f9SEvgeniy Brevnov void BranchProbabilityInfo::SccInfo::getSccExitBlocks(
2593a2b05f9SEvgeniy Brevnov int SccNum, SmallVectorImpl<BasicBlock *> &Exits) const {
2603a2b05f9SEvgeniy Brevnov for (auto MapIt : SccBlocks[SccNum]) {
2613a2b05f9SEvgeniy Brevnov const auto *BB = MapIt.first;
2623a2b05f9SEvgeniy Brevnov if (isSCCExitingBlock(BB, SccNum))
2633a2b05f9SEvgeniy Brevnov for (const auto *Succ : successors(BB))
2643a2b05f9SEvgeniy Brevnov if (getSCCNum(Succ) != SccNum)
265bf76e648SBin Cheng Exits.push_back(const_cast<BasicBlock *>(Succ));
2663a2b05f9SEvgeniy Brevnov }
2673a2b05f9SEvgeniy Brevnov }
2683a2b05f9SEvgeniy Brevnov
getSccBlockType(const BasicBlock * BB,int SccNum) const2693a2b05f9SEvgeniy Brevnov uint32_t BranchProbabilityInfo::SccInfo::getSccBlockType(const BasicBlock *BB,
2703a2b05f9SEvgeniy Brevnov int SccNum) const {
2713a2b05f9SEvgeniy Brevnov assert(getSCCNum(BB) == SccNum);
2723a2b05f9SEvgeniy Brevnov
2733a2b05f9SEvgeniy Brevnov assert(SccBlocks.size() > static_cast<unsigned>(SccNum) && "Unknown SCC");
2743a2b05f9SEvgeniy Brevnov const auto &SccBlockTypes = SccBlocks[SccNum];
2753a2b05f9SEvgeniy Brevnov
2763a2b05f9SEvgeniy Brevnov auto It = SccBlockTypes.find(BB);
2773a2b05f9SEvgeniy Brevnov if (It != SccBlockTypes.end()) {
2783a2b05f9SEvgeniy Brevnov return It->second;
2793a2b05f9SEvgeniy Brevnov }
2803a2b05f9SEvgeniy Brevnov return Inner;
2813a2b05f9SEvgeniy Brevnov }
2823a2b05f9SEvgeniy Brevnov
calculateSccBlockType(const BasicBlock * BB,int SccNum)2833a2b05f9SEvgeniy Brevnov void BranchProbabilityInfo::SccInfo::calculateSccBlockType(const BasicBlock *BB,
2843a2b05f9SEvgeniy Brevnov int SccNum) {
2853a2b05f9SEvgeniy Brevnov assert(getSCCNum(BB) == SccNum);
2863a2b05f9SEvgeniy Brevnov uint32_t BlockType = Inner;
2873a2b05f9SEvgeniy Brevnov
288c5cc2d8bSKazu Hirata if (llvm::any_of(predecessors(BB), [&](const BasicBlock *Pred) {
2893a2b05f9SEvgeniy Brevnov // Consider any block that is an entry point to the SCC as
2903a2b05f9SEvgeniy Brevnov // a header.
2913a2b05f9SEvgeniy Brevnov return getSCCNum(Pred) != SccNum;
2923a2b05f9SEvgeniy Brevnov }))
2933a2b05f9SEvgeniy Brevnov BlockType |= Header;
2943a2b05f9SEvgeniy Brevnov
295c5cc2d8bSKazu Hirata if (llvm::any_of(successors(BB), [&](const BasicBlock *Succ) {
296c5cc2d8bSKazu Hirata return getSCCNum(Succ) != SccNum;
297c5cc2d8bSKazu Hirata }))
2983a2b05f9SEvgeniy Brevnov BlockType |= Exiting;
2993a2b05f9SEvgeniy Brevnov
3003a2b05f9SEvgeniy Brevnov // Lazily compute the set of headers for a given SCC and cache the results
3013a2b05f9SEvgeniy Brevnov // in the SccHeaderMap.
3023a2b05f9SEvgeniy Brevnov if (SccBlocks.size() <= static_cast<unsigned>(SccNum))
3033a2b05f9SEvgeniy Brevnov SccBlocks.resize(SccNum + 1);
3043a2b05f9SEvgeniy Brevnov auto &SccBlockTypes = SccBlocks[SccNum];
3053a2b05f9SEvgeniy Brevnov
3063a2b05f9SEvgeniy Brevnov if (BlockType != Inner) {
3073a2b05f9SEvgeniy Brevnov bool IsInserted;
3083a2b05f9SEvgeniy Brevnov std::tie(std::ignore, IsInserted) =
3093a2b05f9SEvgeniy Brevnov SccBlockTypes.insert(std::make_pair(BB, BlockType));
3103a2b05f9SEvgeniy Brevnov assert(IsInserted && "Duplicated block in SCC");
3113a2b05f9SEvgeniy Brevnov }
3123a2b05f9SEvgeniy Brevnov }
3133a2b05f9SEvgeniy Brevnov
LoopBlock(const BasicBlock * BB,const LoopInfo & LI,const SccInfo & SccI)31402a629daSEvgeniy Brevnov BranchProbabilityInfo::LoopBlock::LoopBlock(const BasicBlock *BB,
31502a629daSEvgeniy Brevnov const LoopInfo &LI,
31602a629daSEvgeniy Brevnov const SccInfo &SccI)
31702a629daSEvgeniy Brevnov : BB(BB) {
31802a629daSEvgeniy Brevnov LD.first = LI.getLoopFor(BB);
31902a629daSEvgeniy Brevnov if (!LD.first) {
32002a629daSEvgeniy Brevnov LD.second = SccI.getSCCNum(BB);
32102a629daSEvgeniy Brevnov }
32202a629daSEvgeniy Brevnov }
32302a629daSEvgeniy Brevnov
isLoopEnteringEdge(const LoopEdge & Edge) const32402a629daSEvgeniy Brevnov bool BranchProbabilityInfo::isLoopEnteringEdge(const LoopEdge &Edge) const {
32502a629daSEvgeniy Brevnov const auto &SrcBlock = Edge.first;
32602a629daSEvgeniy Brevnov const auto &DstBlock = Edge.second;
32702a629daSEvgeniy Brevnov return (DstBlock.getLoop() &&
32802a629daSEvgeniy Brevnov !DstBlock.getLoop()->contains(SrcBlock.getLoop())) ||
32902a629daSEvgeniy Brevnov // Assume that SCCs can't be nested.
33002a629daSEvgeniy Brevnov (DstBlock.getSccNum() != -1 &&
33102a629daSEvgeniy Brevnov SrcBlock.getSccNum() != DstBlock.getSccNum());
33202a629daSEvgeniy Brevnov }
33302a629daSEvgeniy Brevnov
isLoopExitingEdge(const LoopEdge & Edge) const33402a629daSEvgeniy Brevnov bool BranchProbabilityInfo::isLoopExitingEdge(const LoopEdge &Edge) const {
33502a629daSEvgeniy Brevnov return isLoopEnteringEdge({Edge.second, Edge.first});
33602a629daSEvgeniy Brevnov }
33702a629daSEvgeniy Brevnov
isLoopEnteringExitingEdge(const LoopEdge & Edge) const33802a629daSEvgeniy Brevnov bool BranchProbabilityInfo::isLoopEnteringExitingEdge(
33902a629daSEvgeniy Brevnov const LoopEdge &Edge) const {
34002a629daSEvgeniy Brevnov return isLoopEnteringEdge(Edge) || isLoopExitingEdge(Edge);
34102a629daSEvgeniy Brevnov }
34202a629daSEvgeniy Brevnov
isLoopBackEdge(const LoopEdge & Edge) const34302a629daSEvgeniy Brevnov bool BranchProbabilityInfo::isLoopBackEdge(const LoopEdge &Edge) const {
34402a629daSEvgeniy Brevnov const auto &SrcBlock = Edge.first;
34502a629daSEvgeniy Brevnov const auto &DstBlock = Edge.second;
34602a629daSEvgeniy Brevnov return SrcBlock.belongsToSameLoop(DstBlock) &&
34702a629daSEvgeniy Brevnov ((DstBlock.getLoop() &&
34802a629daSEvgeniy Brevnov DstBlock.getLoop()->getHeader() == DstBlock.getBlock()) ||
34902a629daSEvgeniy Brevnov (DstBlock.getSccNum() != -1 &&
35002a629daSEvgeniy Brevnov SccI->isSCCHeader(DstBlock.getBlock(), DstBlock.getSccNum())));
35102a629daSEvgeniy Brevnov }
35202a629daSEvgeniy Brevnov
getLoopEnterBlocks(const LoopBlock & LB,SmallVectorImpl<BasicBlock * > & Enters) const35302a629daSEvgeniy Brevnov void BranchProbabilityInfo::getLoopEnterBlocks(
35402a629daSEvgeniy Brevnov const LoopBlock &LB, SmallVectorImpl<BasicBlock *> &Enters) const {
35502a629daSEvgeniy Brevnov if (LB.getLoop()) {
35602a629daSEvgeniy Brevnov auto *Header = LB.getLoop()->getHeader();
35702a629daSEvgeniy Brevnov Enters.append(pred_begin(Header), pred_end(Header));
35802a629daSEvgeniy Brevnov } else {
35902a629daSEvgeniy Brevnov assert(LB.getSccNum() != -1 && "LB doesn't belong to any loop?");
36002a629daSEvgeniy Brevnov SccI->getSccEnterBlocks(LB.getSccNum(), Enters);
36102a629daSEvgeniy Brevnov }
36202a629daSEvgeniy Brevnov }
36302a629daSEvgeniy Brevnov
getLoopExitBlocks(const LoopBlock & LB,SmallVectorImpl<BasicBlock * > & Exits) const36402a629daSEvgeniy Brevnov void BranchProbabilityInfo::getLoopExitBlocks(
36502a629daSEvgeniy Brevnov const LoopBlock &LB, SmallVectorImpl<BasicBlock *> &Exits) const {
36602a629daSEvgeniy Brevnov if (LB.getLoop()) {
36702a629daSEvgeniy Brevnov LB.getLoop()->getExitBlocks(Exits);
36802a629daSEvgeniy Brevnov } else {
36902a629daSEvgeniy Brevnov assert(LB.getSccNum() != -1 && "LB doesn't belong to any loop?");
37002a629daSEvgeniy Brevnov SccI->getSccExitBlocks(LB.getSccNum(), Exits);
37102a629daSEvgeniy Brevnov }
37202a629daSEvgeniy Brevnov }
37302a629daSEvgeniy Brevnov
374d27a7a94SChandler Carruth // Propagate existing explicit probabilities from either profile data or
3752616bbb1SSerguei Katkov // 'expect' intrinsic processing. Examine metadata against unreachable
3762616bbb1SSerguei Katkov // heuristic. The probability of the edge coming to unreachable block is
3772616bbb1SSerguei Katkov // set to min of metadata and unreachable heuristic.
calcMetadataWeights(const BasicBlock * BB)378a797877aSMehdi Amini bool BranchProbabilityInfo::calcMetadataWeights(const BasicBlock *BB) {
379edb12a83SChandler Carruth const Instruction *TI = BB->getTerminator();
38011d9c4f6SSerguei Katkov assert(TI->getNumSuccessors() > 1 && "expected more than one successor!");
381dcfa78a4SYevgeny Rouban if (!(isa<BranchInst>(TI) || isa<SwitchInst>(TI) || isa<IndirectBrInst>(TI) ||
382dcfa78a4SYevgeny Rouban isa<InvokeInst>(TI)))
383d27a7a94SChandler Carruth return false;
384d27a7a94SChandler Carruth
385de36e804SDuncan P. N. Exon Smith MDNode *WeightsNode = TI->getMetadata(LLVMContext::MD_prof);
386deac50cbSChandler Carruth if (!WeightsNode)
387d27a7a94SChandler Carruth return false;
388d27a7a94SChandler Carruth
389de5b8016SDiego Novillo // Check that the number of successors is manageable.
390de5b8016SDiego Novillo assert(TI->getNumSuccessors() < UINT32_MAX && "Too many successors");
391de5b8016SDiego Novillo
392deac50cbSChandler Carruth // Ensure there are weights for all of the successors. Note that the first
393deac50cbSChandler Carruth // operand to the metadata node is a name, not a weight.
394deac50cbSChandler Carruth if (WeightsNode->getNumOperands() != TI->getNumSuccessors() + 1)
395d27a7a94SChandler Carruth return false;
396d27a7a94SChandler Carruth
397de5b8016SDiego Novillo // Build up the final weights that will be used in a temporary buffer.
3985c31b8b9SArthur Eubanks // Compute the sum of all weights to later decide whether they need to
3995c31b8b9SArthur Eubanks // be scaled to fit in 32 bits.
4005c31b8b9SArthur Eubanks uint64_t WeightSum = 0;
4015c31b8b9SArthur Eubanks SmallVector<uint32_t, 2> Weights;
4022616bbb1SSerguei Katkov SmallVector<unsigned, 2> UnreachableIdxs;
4032616bbb1SSerguei Katkov SmallVector<unsigned, 2> ReachableIdxs;
404deac50cbSChandler Carruth Weights.reserve(TI->getNumSuccessors());
4053bb0d95fSYevgeny Rouban for (unsigned I = 1, E = WeightsNode->getNumOperands(); I != E; ++I) {
4065bf8fef5SDuncan P. N. Exon Smith ConstantInt *Weight =
4073bb0d95fSYevgeny Rouban mdconst::dyn_extract<ConstantInt>(WeightsNode->getOperand(I));
408deac50cbSChandler Carruth if (!Weight)
409deac50cbSChandler Carruth return false;
4105c31b8b9SArthur Eubanks assert(Weight->getValue().getActiveBits() <= 32 &&
4115c31b8b9SArthur Eubanks "Too many bits for uint32_t");
4125c31b8b9SArthur Eubanks Weights.push_back(Weight->getZExtValue());
4135c31b8b9SArthur Eubanks WeightSum += Weights.back();
4149fb074e7SEvgeniy Brevnov const LoopBlock SrcLoopBB = getLoopBlock(BB);
4159fb074e7SEvgeniy Brevnov const LoopBlock DstLoopBB = getLoopBlock(TI->getSuccessor(I - 1));
4169fb074e7SEvgeniy Brevnov auto EstimatedWeight = getEstimatedEdgeWeight({SrcLoopBB, DstLoopBB});
4179fb074e7SEvgeniy Brevnov if (EstimatedWeight &&
4187a47ee51SKazu Hirata *EstimatedWeight <= static_cast<uint32_t>(BlockExecWeight::UNREACHABLE))
4193bb0d95fSYevgeny Rouban UnreachableIdxs.push_back(I - 1);
4202616bbb1SSerguei Katkov else
4213bb0d95fSYevgeny Rouban ReachableIdxs.push_back(I - 1);
422deac50cbSChandler Carruth }
423deac50cbSChandler Carruth assert(Weights.size() == TI->getNumSuccessors() && "Checked above");
424de5b8016SDiego Novillo
4255c31b8b9SArthur Eubanks // If the sum of weights does not fit in 32 bits, scale every weight down
4265c31b8b9SArthur Eubanks // accordingly.
4275c31b8b9SArthur Eubanks uint64_t ScalingFactor =
4285c31b8b9SArthur Eubanks (WeightSum > UINT32_MAX) ? WeightSum / UINT32_MAX + 1 : 1;
4295c31b8b9SArthur Eubanks
4305c31b8b9SArthur Eubanks if (ScalingFactor > 1) {
4315c31b8b9SArthur Eubanks WeightSum = 0;
4325c31b8b9SArthur Eubanks for (unsigned I = 0, E = TI->getNumSuccessors(); I != E; ++I) {
4335c31b8b9SArthur Eubanks Weights[I] /= ScalingFactor;
4345c31b8b9SArthur Eubanks WeightSum += Weights[I];
4355c31b8b9SArthur Eubanks }
4365c31b8b9SArthur Eubanks }
4375c31b8b9SArthur Eubanks assert(WeightSum <= UINT32_MAX &&
4385c31b8b9SArthur Eubanks "Expected weights to scale down to 32 bits");
439e93b8e15SCong Hou
4402616bbb1SSerguei Katkov if (WeightSum == 0 || ReachableIdxs.size() == 0) {
4413bb0d95fSYevgeny Rouban for (unsigned I = 0, E = TI->getNumSuccessors(); I != E; ++I)
4423bb0d95fSYevgeny Rouban Weights[I] = 1;
4432616bbb1SSerguei Katkov WeightSum = TI->getNumSuccessors();
4442616bbb1SSerguei Katkov }
4452616bbb1SSerguei Katkov
4462616bbb1SSerguei Katkov // Set the probability.
4472616bbb1SSerguei Katkov SmallVector<BranchProbability, 2> BP;
4483bb0d95fSYevgeny Rouban for (unsigned I = 0, E = TI->getNumSuccessors(); I != E; ++I)
4495c31b8b9SArthur Eubanks BP.push_back({ Weights[I], static_cast<uint32_t>(WeightSum) });
4502616bbb1SSerguei Katkov
4512616bbb1SSerguei Katkov // Examine the metadata against unreachable heuristic.
4522616bbb1SSerguei Katkov // If the unreachable heuristic is more strong then we use it for this edge.
45307239c73SYevgeny Rouban if (UnreachableIdxs.size() == 0 || ReachableIdxs.size() == 0) {
45407239c73SYevgeny Rouban setEdgeProbability(BB, BP);
45507239c73SYevgeny Rouban return true;
45607239c73SYevgeny Rouban }
45707239c73SYevgeny Rouban
458ba831f78SSerguei Katkov auto UnreachableProb = UR_TAKEN_PROB;
4593bb0d95fSYevgeny Rouban for (auto I : UnreachableIdxs)
4603bb0d95fSYevgeny Rouban if (UnreachableProb < BP[I]) {
4613bb0d95fSYevgeny Rouban BP[I] = UnreachableProb;
4622616bbb1SSerguei Katkov }
4632616bbb1SSerguei Katkov
46407239c73SYevgeny Rouban // Sum of all edge probabilities must be 1.0. If we modified the probability
46507239c73SYevgeny Rouban // of some edges then we must distribute the introduced difference over the
46607239c73SYevgeny Rouban // reachable blocks.
46707239c73SYevgeny Rouban //
46807239c73SYevgeny Rouban // Proportional distribution: the relation between probabilities of the
46907239c73SYevgeny Rouban // reachable edges is kept unchanged. That is for any reachable edges i and j:
47007239c73SYevgeny Rouban // newBP[i] / newBP[j] == oldBP[i] / oldBP[j] =>
47107239c73SYevgeny Rouban // newBP[i] / oldBP[i] == newBP[j] / oldBP[j] == K
47207239c73SYevgeny Rouban // Where K is independent of i,j.
47307239c73SYevgeny Rouban // newBP[i] == oldBP[i] * K
47407239c73SYevgeny Rouban // We need to find K.
47507239c73SYevgeny Rouban // Make sum of all reachables of the left and right parts:
47607239c73SYevgeny Rouban // sum_of_reachable(newBP) == K * sum_of_reachable(oldBP)
47707239c73SYevgeny Rouban // Sum of newBP must be equal to 1.0:
47807239c73SYevgeny Rouban // sum_of_reachable(newBP) + sum_of_unreachable(newBP) == 1.0 =>
47907239c73SYevgeny Rouban // sum_of_reachable(newBP) = 1.0 - sum_of_unreachable(newBP)
48007239c73SYevgeny Rouban // Where sum_of_unreachable(newBP) is what has been just changed.
48107239c73SYevgeny Rouban // Finally:
48207239c73SYevgeny Rouban // K == sum_of_reachable(newBP) / sum_of_reachable(oldBP) =>
48307239c73SYevgeny Rouban // K == (1.0 - sum_of_unreachable(newBP)) / sum_of_reachable(oldBP)
48407239c73SYevgeny Rouban BranchProbability NewUnreachableSum = BranchProbability::getZero();
48507239c73SYevgeny Rouban for (auto I : UnreachableIdxs)
48607239c73SYevgeny Rouban NewUnreachableSum += BP[I];
48781384874SYevgeny Rouban
48807239c73SYevgeny Rouban BranchProbability NewReachableSum =
48907239c73SYevgeny Rouban BranchProbability::getOne() - NewUnreachableSum;
49007239c73SYevgeny Rouban
49107239c73SYevgeny Rouban BranchProbability OldReachableSum = BranchProbability::getZero();
4923bb0d95fSYevgeny Rouban for (auto I : ReachableIdxs)
49307239c73SYevgeny Rouban OldReachableSum += BP[I];
49407239c73SYevgeny Rouban
49507239c73SYevgeny Rouban if (OldReachableSum != NewReachableSum) { // Anything to dsitribute?
49607239c73SYevgeny Rouban if (OldReachableSum.isZero()) {
49707239c73SYevgeny Rouban // If all oldBP[i] are zeroes then the proportional distribution results
49807239c73SYevgeny Rouban // in all zero probabilities and the error stays big. In this case we
49907239c73SYevgeny Rouban // evenly spread NewReachableSum over the reachable edges.
50007239c73SYevgeny Rouban BranchProbability PerEdge = NewReachableSum / ReachableIdxs.size();
50107239c73SYevgeny Rouban for (auto I : ReachableIdxs)
50207239c73SYevgeny Rouban BP[I] = PerEdge;
50307239c73SYevgeny Rouban } else {
50407239c73SYevgeny Rouban for (auto I : ReachableIdxs) {
50507239c73SYevgeny Rouban // We use uint64_t to avoid double rounding error of the following
50607239c73SYevgeny Rouban // calculation: BP[i] = BP[i] * NewReachableSum / OldReachableSum
50707239c73SYevgeny Rouban // The formula is taken from the private constructor
50807239c73SYevgeny Rouban // BranchProbability(uint32_t Numerator, uint32_t Denominator)
50907239c73SYevgeny Rouban uint64_t Mul = static_cast<uint64_t>(NewReachableSum.getNumerator()) *
51007239c73SYevgeny Rouban BP[I].getNumerator();
51107239c73SYevgeny Rouban uint32_t Div = static_cast<uint32_t>(
51207239c73SYevgeny Rouban divideNearest(Mul, OldReachableSum.getNumerator()));
51307239c73SYevgeny Rouban BP[I] = BranchProbability::getRaw(Div);
51407239c73SYevgeny Rouban }
51507239c73SYevgeny Rouban }
5162616bbb1SSerguei Katkov }
5172616bbb1SSerguei Katkov
51881384874SYevgeny Rouban setEdgeProbability(BB, BP);
5192616bbb1SSerguei Katkov
520d27a7a94SChandler Carruth return true;
521d27a7a94SChandler Carruth }
522d27a7a94SChandler Carruth
5231a8456daSVedant Kumar // Calculate Edge Weights using "Pointer Heuristics". Predict a comparison
52449371f3fSAndrew Trick // between two pointer or pointer and NULL will fail.
calcPointerHeuristics(const BasicBlock * BB)525a797877aSMehdi Amini bool BranchProbabilityInfo::calcPointerHeuristics(const BasicBlock *BB) {
526a797877aSMehdi Amini const BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator());
52749371f3fSAndrew Trick if (!BI || !BI->isConditional())
528d07b2e15SJakub Staszak return false;
52949371f3fSAndrew Trick
53049371f3fSAndrew Trick Value *Cond = BI->getCondition();
53149371f3fSAndrew Trick ICmpInst *CI = dyn_cast<ICmpInst>(Cond);
532abb236feSJakub Staszak if (!CI || !CI->isEquality())
533d07b2e15SJakub Staszak return false;
53449371f3fSAndrew Trick
53549371f3fSAndrew Trick Value *LHS = CI->getOperand(0);
53649371f3fSAndrew Trick
53749371f3fSAndrew Trick if (!LHS->getType()->isPointerTy())
538d07b2e15SJakub Staszak return false;
53949371f3fSAndrew Trick
54075b20538SNick Lewycky assert(CI->getOperand(1)->getType()->isPointerTy());
54149371f3fSAndrew Trick
5424d21b644SSjoerd Meijer auto Search = PointerTable.find(CI->getPredicate());
5434d21b644SSjoerd Meijer if (Search == PointerTable.end())
5444d21b644SSjoerd Meijer return false;
5454d21b644SSjoerd Meijer setEdgeProbability(BB, Search->second);
546d07b2e15SJakub Staszak return true;
54749371f3fSAndrew Trick }
54849371f3fSAndrew Trick
54929bbed36SJohn Brawn // Compute the unlikely successors to the block BB in the loop L, specifically
55029bbed36SJohn Brawn // those that are unlikely because this is a loop, and add them to the
55129bbed36SJohn Brawn // UnlikelyBlocks set.
55229bbed36SJohn Brawn static void
computeUnlikelySuccessors(const BasicBlock * BB,Loop * L,SmallPtrSetImpl<const BasicBlock * > & UnlikelyBlocks)55329bbed36SJohn Brawn computeUnlikelySuccessors(const BasicBlock *BB, Loop *L,
55429bbed36SJohn Brawn SmallPtrSetImpl<const BasicBlock*> &UnlikelyBlocks) {
55529bbed36SJohn Brawn // Sometimes in a loop we have a branch whose condition is made false by
55629bbed36SJohn Brawn // taking it. This is typically something like
55729bbed36SJohn Brawn // int n = 0;
55829bbed36SJohn Brawn // while (...) {
55929bbed36SJohn Brawn // if (++n >= MAX) {
56029bbed36SJohn Brawn // n = 0;
56129bbed36SJohn Brawn // }
56229bbed36SJohn Brawn // }
56329bbed36SJohn Brawn // In this sort of situation taking the branch means that at the very least it
56429bbed36SJohn Brawn // won't be taken again in the next iteration of the loop, so we should
56529bbed36SJohn Brawn // consider it less likely than a typical branch.
56629bbed36SJohn Brawn //
56729bbed36SJohn Brawn // We detect this by looking back through the graph of PHI nodes that sets the
56829bbed36SJohn Brawn // value that the condition depends on, and seeing if we can reach a successor
56929bbed36SJohn Brawn // block which can be determined to make the condition false.
57029bbed36SJohn Brawn //
57129bbed36SJohn Brawn // FIXME: We currently consider unlikely blocks to be half as likely as other
57229bbed36SJohn Brawn // blocks, but if we consider the example above the likelyhood is actually
57329bbed36SJohn Brawn // 1/MAX. We could therefore be more precise in how unlikely we consider
57429bbed36SJohn Brawn // blocks to be, but it would require more careful examination of the form
57529bbed36SJohn Brawn // of the comparison expression.
57629bbed36SJohn Brawn const BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator());
57729bbed36SJohn Brawn if (!BI || !BI->isConditional())
57829bbed36SJohn Brawn return;
57929bbed36SJohn Brawn
58029bbed36SJohn Brawn // Check if the branch is based on an instruction compared with a constant
58129bbed36SJohn Brawn CmpInst *CI = dyn_cast<CmpInst>(BI->getCondition());
58229bbed36SJohn Brawn if (!CI || !isa<Instruction>(CI->getOperand(0)) ||
58329bbed36SJohn Brawn !isa<Constant>(CI->getOperand(1)))
58429bbed36SJohn Brawn return;
58529bbed36SJohn Brawn
58629bbed36SJohn Brawn // Either the instruction must be a PHI, or a chain of operations involving
58729bbed36SJohn Brawn // constants that ends in a PHI which we can then collapse into a single value
58829bbed36SJohn Brawn // if the PHI value is known.
58929bbed36SJohn Brawn Instruction *CmpLHS = dyn_cast<Instruction>(CI->getOperand(0));
59029bbed36SJohn Brawn PHINode *CmpPHI = dyn_cast<PHINode>(CmpLHS);
59129bbed36SJohn Brawn Constant *CmpConst = dyn_cast<Constant>(CI->getOperand(1));
59229bbed36SJohn Brawn // Collect the instructions until we hit a PHI
5937f68a309SBenjamin Kramer SmallVector<BinaryOperator *, 1> InstChain;
59429bbed36SJohn Brawn while (!CmpPHI && CmpLHS && isa<BinaryOperator>(CmpLHS) &&
59529bbed36SJohn Brawn isa<Constant>(CmpLHS->getOperand(1))) {
59629bbed36SJohn Brawn // Stop if the chain extends outside of the loop
59729bbed36SJohn Brawn if (!L->contains(CmpLHS))
59829bbed36SJohn Brawn return;
5997f68a309SBenjamin Kramer InstChain.push_back(cast<BinaryOperator>(CmpLHS));
60029bbed36SJohn Brawn CmpLHS = dyn_cast<Instruction>(CmpLHS->getOperand(0));
60129bbed36SJohn Brawn if (CmpLHS)
60229bbed36SJohn Brawn CmpPHI = dyn_cast<PHINode>(CmpLHS);
60329bbed36SJohn Brawn }
60429bbed36SJohn Brawn if (!CmpPHI || !L->contains(CmpPHI))
60529bbed36SJohn Brawn return;
60629bbed36SJohn Brawn
60729bbed36SJohn Brawn // Trace the phi node to find all values that come from successors of BB
60829bbed36SJohn Brawn SmallPtrSet<PHINode*, 8> VisitedInsts;
60929bbed36SJohn Brawn SmallVector<PHINode*, 8> WorkList;
61029bbed36SJohn Brawn WorkList.push_back(CmpPHI);
61129bbed36SJohn Brawn VisitedInsts.insert(CmpPHI);
61229bbed36SJohn Brawn while (!WorkList.empty()) {
6137a37d981SKazu Hirata PHINode *P = WorkList.pop_back_val();
61429bbed36SJohn Brawn for (BasicBlock *B : P->blocks()) {
61529bbed36SJohn Brawn // Skip blocks that aren't part of the loop
61629bbed36SJohn Brawn if (!L->contains(B))
61729bbed36SJohn Brawn continue;
61829bbed36SJohn Brawn Value *V = P->getIncomingValueForBlock(B);
61929bbed36SJohn Brawn // If the source is a PHI add it to the work list if we haven't
62029bbed36SJohn Brawn // already visited it.
62129bbed36SJohn Brawn if (PHINode *PN = dyn_cast<PHINode>(V)) {
62229bbed36SJohn Brawn if (VisitedInsts.insert(PN).second)
62329bbed36SJohn Brawn WorkList.push_back(PN);
62429bbed36SJohn Brawn continue;
62529bbed36SJohn Brawn }
62629bbed36SJohn Brawn // If this incoming value is a constant and B is a successor of BB, then
62729bbed36SJohn Brawn // we can constant-evaluate the compare to see if it makes the branch be
62829bbed36SJohn Brawn // taken or not.
62929bbed36SJohn Brawn Constant *CmpLHSConst = dyn_cast<Constant>(V);
63060434989SKazu Hirata if (!CmpLHSConst || !llvm::is_contained(successors(BB), B))
63129bbed36SJohn Brawn continue;
63229bbed36SJohn Brawn // First collapse InstChain
633f93cd562SNikita Popov const DataLayout &DL = BB->getModule()->getDataLayout();
6347f68a309SBenjamin Kramer for (Instruction *I : llvm::reverse(InstChain)) {
635f93cd562SNikita Popov CmpLHSConst = ConstantFoldBinaryOpOperands(
636f93cd562SNikita Popov I->getOpcode(), CmpLHSConst, cast<Constant>(I->getOperand(1)), DL);
63729bbed36SJohn Brawn if (!CmpLHSConst)
63829bbed36SJohn Brawn break;
63929bbed36SJohn Brawn }
64029bbed36SJohn Brawn if (!CmpLHSConst)
64129bbed36SJohn Brawn continue;
64229bbed36SJohn Brawn // Now constant-evaluate the compare
64329bbed36SJohn Brawn Constant *Result = ConstantExpr::getCompare(CI->getPredicate(),
64429bbed36SJohn Brawn CmpLHSConst, CmpConst, true);
64529bbed36SJohn Brawn // If the result means we don't branch to the block then that block is
64629bbed36SJohn Brawn // unlikely.
64729bbed36SJohn Brawn if (Result &&
64829bbed36SJohn Brawn ((Result->isZeroValue() && B == BI->getSuccessor(0)) ||
64929bbed36SJohn Brawn (Result->isOneValue() && B == BI->getSuccessor(1))))
65029bbed36SJohn Brawn UnlikelyBlocks.insert(B);
65129bbed36SJohn Brawn }
65229bbed36SJohn Brawn }
65329bbed36SJohn Brawn }
65429bbed36SJohn Brawn
6559fb074e7SEvgeniy Brevnov Optional<uint32_t>
getEstimatedBlockWeight(const BasicBlock * BB) const6569fb074e7SEvgeniy Brevnov BranchProbabilityInfo::getEstimatedBlockWeight(const BasicBlock *BB) const {
6579fb074e7SEvgeniy Brevnov auto WeightIt = EstimatedBlockWeight.find(BB);
6589fb074e7SEvgeniy Brevnov if (WeightIt == EstimatedBlockWeight.end())
6599fb074e7SEvgeniy Brevnov return None;
6609fb074e7SEvgeniy Brevnov return WeightIt->second;
6619fb074e7SEvgeniy Brevnov }
6629fb074e7SEvgeniy Brevnov
6639fb074e7SEvgeniy Brevnov Optional<uint32_t>
getEstimatedLoopWeight(const LoopData & L) const6649fb074e7SEvgeniy Brevnov BranchProbabilityInfo::getEstimatedLoopWeight(const LoopData &L) const {
6659fb074e7SEvgeniy Brevnov auto WeightIt = EstimatedLoopWeight.find(L);
6669fb074e7SEvgeniy Brevnov if (WeightIt == EstimatedLoopWeight.end())
6679fb074e7SEvgeniy Brevnov return None;
6689fb074e7SEvgeniy Brevnov return WeightIt->second;
6699fb074e7SEvgeniy Brevnov }
6709fb074e7SEvgeniy Brevnov
6719fb074e7SEvgeniy Brevnov Optional<uint32_t>
getEstimatedEdgeWeight(const LoopEdge & Edge) const6729fb074e7SEvgeniy Brevnov BranchProbabilityInfo::getEstimatedEdgeWeight(const LoopEdge &Edge) const {
6739fb074e7SEvgeniy Brevnov // For edges entering a loop take weight of a loop rather than an individual
6749fb074e7SEvgeniy Brevnov // block in the loop.
6759fb074e7SEvgeniy Brevnov return isLoopEnteringEdge(Edge)
6769fb074e7SEvgeniy Brevnov ? getEstimatedLoopWeight(Edge.second.getLoopData())
6779fb074e7SEvgeniy Brevnov : getEstimatedBlockWeight(Edge.second.getBlock());
6789fb074e7SEvgeniy Brevnov }
6799fb074e7SEvgeniy Brevnov
6809fb074e7SEvgeniy Brevnov template <class IterT>
getMaxEstimatedEdgeWeight(const LoopBlock & SrcLoopBB,iterator_range<IterT> Successors) const6819fb074e7SEvgeniy Brevnov Optional<uint32_t> BranchProbabilityInfo::getMaxEstimatedEdgeWeight(
6829fb074e7SEvgeniy Brevnov const LoopBlock &SrcLoopBB, iterator_range<IterT> Successors) const {
6839fb074e7SEvgeniy Brevnov SmallVector<uint32_t, 4> Weights;
6849fb074e7SEvgeniy Brevnov Optional<uint32_t> MaxWeight;
6859fb074e7SEvgeniy Brevnov for (const BasicBlock *DstBB : Successors) {
6869fb074e7SEvgeniy Brevnov const LoopBlock DstLoopBB = getLoopBlock(DstBB);
6879fb074e7SEvgeniy Brevnov auto Weight = getEstimatedEdgeWeight({SrcLoopBB, DstLoopBB});
6889fb074e7SEvgeniy Brevnov
6899fb074e7SEvgeniy Brevnov if (!Weight)
6909fb074e7SEvgeniy Brevnov return None;
6919fb074e7SEvgeniy Brevnov
6927a47ee51SKazu Hirata if (!MaxWeight || *MaxWeight < *Weight)
6939fb074e7SEvgeniy Brevnov MaxWeight = Weight;
6949fb074e7SEvgeniy Brevnov }
6959fb074e7SEvgeniy Brevnov
6969fb074e7SEvgeniy Brevnov return MaxWeight;
6979fb074e7SEvgeniy Brevnov }
6989fb074e7SEvgeniy Brevnov
6999fb074e7SEvgeniy Brevnov // Updates \p LoopBB's weight and returns true. If \p LoopBB has already
7009fb074e7SEvgeniy Brevnov // an associated weight it is unchanged and false is returned.
7019fb074e7SEvgeniy Brevnov //
7029fb074e7SEvgeniy Brevnov // Please note by the algorithm the weight is not expected to change once set
7039fb074e7SEvgeniy Brevnov // thus 'false' status is used to track visited blocks.
updateEstimatedBlockWeight(LoopBlock & LoopBB,uint32_t BBWeight,SmallVectorImpl<BasicBlock * > & BlockWorkList,SmallVectorImpl<LoopBlock> & LoopWorkList)7049fb074e7SEvgeniy Brevnov bool BranchProbabilityInfo::updateEstimatedBlockWeight(
7059fb074e7SEvgeniy Brevnov LoopBlock &LoopBB, uint32_t BBWeight,
7069fb074e7SEvgeniy Brevnov SmallVectorImpl<BasicBlock *> &BlockWorkList,
7079fb074e7SEvgeniy Brevnov SmallVectorImpl<LoopBlock> &LoopWorkList) {
7089fb074e7SEvgeniy Brevnov BasicBlock *BB = LoopBB.getBlock();
7099fb074e7SEvgeniy Brevnov
7109fb074e7SEvgeniy Brevnov // In general, weight is assigned to a block when it has final value and
7119fb074e7SEvgeniy Brevnov // can't/shouldn't be changed. However, there are cases when a block
7129fb074e7SEvgeniy Brevnov // inherently has several (possibly "contradicting") weights. For example,
7139fb074e7SEvgeniy Brevnov // "unwind" block may also contain "cold" call. In that case the first
7149fb074e7SEvgeniy Brevnov // set weight is favored and all consequent weights are ignored.
7159fb074e7SEvgeniy Brevnov if (!EstimatedBlockWeight.insert({BB, BBWeight}).second)
716d07b2e15SJakub Staszak return false;
71749371f3fSAndrew Trick
7189fb074e7SEvgeniy Brevnov for (BasicBlock *PredBlock : predecessors(BB)) {
7199fb074e7SEvgeniy Brevnov LoopBlock PredLoop = getLoopBlock(PredBlock);
7209fb074e7SEvgeniy Brevnov // Add affected block/loop to a working list.
7219fb074e7SEvgeniy Brevnov if (isLoopExitingEdge({PredLoop, LoopBB})) {
7229fb074e7SEvgeniy Brevnov if (!EstimatedLoopWeight.count(PredLoop.getLoopData()))
7239fb074e7SEvgeniy Brevnov LoopWorkList.push_back(PredLoop);
7249fb074e7SEvgeniy Brevnov } else if (!EstimatedBlockWeight.count(PredBlock))
7259fb074e7SEvgeniy Brevnov BlockWorkList.push_back(PredBlock);
7269fb074e7SEvgeniy Brevnov }
7279fb074e7SEvgeniy Brevnov return true;
7289fb074e7SEvgeniy Brevnov }
7299fb074e7SEvgeniy Brevnov
7309fb074e7SEvgeniy Brevnov // Starting from \p BB traverse through dominator blocks and assign \p BBWeight
7319fb074e7SEvgeniy Brevnov // to all such blocks that are post dominated by \BB. In other words to all
7329fb074e7SEvgeniy Brevnov // blocks that the one is executed if and only if another one is executed.
7339fb074e7SEvgeniy Brevnov // Importantly, we skip loops here for two reasons. First weights of blocks in
7349fb074e7SEvgeniy Brevnov // a loop should be scaled by trip count (yet possibly unknown). Second there is
7359fb074e7SEvgeniy Brevnov // no any value in doing that because that doesn't give any additional
7369fb074e7SEvgeniy Brevnov // information regarding distribution of probabilities inside the loop.
7379fb074e7SEvgeniy Brevnov // Exception is loop 'enter' and 'exit' edges that are handled in a special way
7389fb074e7SEvgeniy Brevnov // at calcEstimatedHeuristics.
7399fb074e7SEvgeniy Brevnov //
7409fb074e7SEvgeniy Brevnov // In addition, \p WorkList is populated with basic blocks if at leas one
7419fb074e7SEvgeniy Brevnov // successor has updated estimated weight.
propagateEstimatedBlockWeight(const LoopBlock & LoopBB,DominatorTree * DT,PostDominatorTree * PDT,uint32_t BBWeight,SmallVectorImpl<BasicBlock * > & BlockWorkList,SmallVectorImpl<LoopBlock> & LoopWorkList)7429fb074e7SEvgeniy Brevnov void BranchProbabilityInfo::propagateEstimatedBlockWeight(
7439fb074e7SEvgeniy Brevnov const LoopBlock &LoopBB, DominatorTree *DT, PostDominatorTree *PDT,
7449fb074e7SEvgeniy Brevnov uint32_t BBWeight, SmallVectorImpl<BasicBlock *> &BlockWorkList,
7459fb074e7SEvgeniy Brevnov SmallVectorImpl<LoopBlock> &LoopWorkList) {
7469fb074e7SEvgeniy Brevnov const BasicBlock *BB = LoopBB.getBlock();
7479fb074e7SEvgeniy Brevnov const auto *DTStartNode = DT->getNode(BB);
7489fb074e7SEvgeniy Brevnov const auto *PDTStartNode = PDT->getNode(BB);
7499fb074e7SEvgeniy Brevnov
7509fb074e7SEvgeniy Brevnov // TODO: Consider propagating weight down the domination line as well.
7519fb074e7SEvgeniy Brevnov for (const auto *DTNode = DTStartNode; DTNode != nullptr;
7529fb074e7SEvgeniy Brevnov DTNode = DTNode->getIDom()) {
7539fb074e7SEvgeniy Brevnov auto *DomBB = DTNode->getBlock();
7549fb074e7SEvgeniy Brevnov // Consider blocks which lie on one 'line'.
7559fb074e7SEvgeniy Brevnov if (!PDT->dominates(PDTStartNode, PDT->getNode(DomBB)))
7569fb074e7SEvgeniy Brevnov // If BB doesn't post dominate DomBB it will not post dominate dominators
7579fb074e7SEvgeniy Brevnov // of DomBB as well.
7589fb074e7SEvgeniy Brevnov break;
7599fb074e7SEvgeniy Brevnov
7609fb074e7SEvgeniy Brevnov LoopBlock DomLoopBB = getLoopBlock(DomBB);
7619fb074e7SEvgeniy Brevnov const LoopEdge Edge{DomLoopBB, LoopBB};
7629fb074e7SEvgeniy Brevnov // Don't propagate weight to blocks belonging to different loops.
7639fb074e7SEvgeniy Brevnov if (!isLoopEnteringExitingEdge(Edge)) {
7649fb074e7SEvgeniy Brevnov if (!updateEstimatedBlockWeight(DomLoopBB, BBWeight, BlockWorkList,
7659fb074e7SEvgeniy Brevnov LoopWorkList))
7669fb074e7SEvgeniy Brevnov // If DomBB has weight set then all it's predecessors are already
7679fb074e7SEvgeniy Brevnov // processed (since we propagate weight up to the top of IR each time).
7689fb074e7SEvgeniy Brevnov break;
7699fb074e7SEvgeniy Brevnov } else if (isLoopExitingEdge(Edge)) {
7709fb074e7SEvgeniy Brevnov LoopWorkList.push_back(DomLoopBB);
7719fb074e7SEvgeniy Brevnov }
7729fb074e7SEvgeniy Brevnov }
7739fb074e7SEvgeniy Brevnov }
7749fb074e7SEvgeniy Brevnov
getInitialEstimatedBlockWeight(const BasicBlock * BB)7759fb074e7SEvgeniy Brevnov Optional<uint32_t> BranchProbabilityInfo::getInitialEstimatedBlockWeight(
7769fb074e7SEvgeniy Brevnov const BasicBlock *BB) {
7779fb074e7SEvgeniy Brevnov // Returns true if \p BB has call marked with "NoReturn" attribute.
7789fb074e7SEvgeniy Brevnov auto hasNoReturn = [&](const BasicBlock *BB) {
7799fb074e7SEvgeniy Brevnov for (const auto &I : reverse(*BB))
7809fb074e7SEvgeniy Brevnov if (const CallInst *CI = dyn_cast<CallInst>(&I))
7819fb074e7SEvgeniy Brevnov if (CI->hasFnAttr(Attribute::NoReturn))
7829fb074e7SEvgeniy Brevnov return true;
7839fb074e7SEvgeniy Brevnov
7849fb074e7SEvgeniy Brevnov return false;
7859fb074e7SEvgeniy Brevnov };
7869fb074e7SEvgeniy Brevnov
7879fb074e7SEvgeniy Brevnov // Important note regarding the order of checks. They are ordered by weight
7889fb074e7SEvgeniy Brevnov // from lowest to highest. Doing that allows to avoid "unstable" results
7899fb074e7SEvgeniy Brevnov // when several conditions heuristics can be applied simultaneously.
7909fb074e7SEvgeniy Brevnov if (isa<UnreachableInst>(BB->getTerminator()) ||
7919fb074e7SEvgeniy Brevnov // If this block is terminated by a call to
7929fb074e7SEvgeniy Brevnov // @llvm.experimental.deoptimize then treat it like an unreachable
7939fb074e7SEvgeniy Brevnov // since it is expected to practically never execute.
7949fb074e7SEvgeniy Brevnov // TODO: Should we actually treat as never returning call?
7959fb074e7SEvgeniy Brevnov BB->getTerminatingDeoptimizeCall())
7969fb074e7SEvgeniy Brevnov return hasNoReturn(BB)
7979fb074e7SEvgeniy Brevnov ? static_cast<uint32_t>(BlockExecWeight::NORETURN)
7989fb074e7SEvgeniy Brevnov : static_cast<uint32_t>(BlockExecWeight::UNREACHABLE);
7999fb074e7SEvgeniy Brevnov
8009fb074e7SEvgeniy Brevnov // Check if the block is 'unwind' handler of some invoke instruction.
8019fb074e7SEvgeniy Brevnov for (const auto *Pred : predecessors(BB))
8029fb074e7SEvgeniy Brevnov if (Pred)
8039fb074e7SEvgeniy Brevnov if (const auto *II = dyn_cast<InvokeInst>(Pred->getTerminator()))
8049fb074e7SEvgeniy Brevnov if (II->getUnwindDest() == BB)
8059fb074e7SEvgeniy Brevnov return static_cast<uint32_t>(BlockExecWeight::UNWIND);
8069fb074e7SEvgeniy Brevnov
8079fb074e7SEvgeniy Brevnov // Check if the block contains 'cold' call.
8089fb074e7SEvgeniy Brevnov for (const auto &I : *BB)
8099fb074e7SEvgeniy Brevnov if (const CallInst *CI = dyn_cast<CallInst>(&I))
8109fb074e7SEvgeniy Brevnov if (CI->hasFnAttr(Attribute::Cold))
8119fb074e7SEvgeniy Brevnov return static_cast<uint32_t>(BlockExecWeight::COLD);
8129fb074e7SEvgeniy Brevnov
8139fb074e7SEvgeniy Brevnov return None;
8149fb074e7SEvgeniy Brevnov }
8159fb074e7SEvgeniy Brevnov
8169fb074e7SEvgeniy Brevnov // Does RPO traversal over all blocks in \p F and assigns weights to
8179fb074e7SEvgeniy Brevnov // 'unreachable', 'noreturn', 'cold', 'unwind' blocks. In addition it does its
8189fb074e7SEvgeniy Brevnov // best to propagate the weight to up/down the IR.
computeEestimateBlockWeight(const Function & F,DominatorTree * DT,PostDominatorTree * PDT)8199fb074e7SEvgeniy Brevnov void BranchProbabilityInfo::computeEestimateBlockWeight(
8209fb074e7SEvgeniy Brevnov const Function &F, DominatorTree *DT, PostDominatorTree *PDT) {
8219fb074e7SEvgeniy Brevnov SmallVector<BasicBlock *, 8> BlockWorkList;
8229fb074e7SEvgeniy Brevnov SmallVector<LoopBlock, 8> LoopWorkList;
8239fb074e7SEvgeniy Brevnov
8249fb074e7SEvgeniy Brevnov // By doing RPO we make sure that all predecessors already have weights
8259fb074e7SEvgeniy Brevnov // calculated before visiting theirs successors.
8269fb074e7SEvgeniy Brevnov ReversePostOrderTraversal<const Function *> RPOT(&F);
8279fb074e7SEvgeniy Brevnov for (const auto *BB : RPOT)
8289fb074e7SEvgeniy Brevnov if (auto BBWeight = getInitialEstimatedBlockWeight(BB))
8299fb074e7SEvgeniy Brevnov // If we were able to find estimated weight for the block set it to this
8309fb074e7SEvgeniy Brevnov // block and propagate up the IR.
831611ffcf4SKazu Hirata propagateEstimatedBlockWeight(getLoopBlock(BB), DT, PDT, BBWeight.value(),
832611ffcf4SKazu Hirata BlockWorkList, LoopWorkList);
8339fb074e7SEvgeniy Brevnov
8349fb074e7SEvgeniy Brevnov // BlockWorklist/LoopWorkList contains blocks/loops with at least one
8359fb074e7SEvgeniy Brevnov // successor/exit having estimated weight. Try to propagate weight to such
8369fb074e7SEvgeniy Brevnov // blocks/loops from successors/exits.
8379fb074e7SEvgeniy Brevnov // Process loops and blocks. Order is not important.
8389fb074e7SEvgeniy Brevnov do {
8399fb074e7SEvgeniy Brevnov while (!LoopWorkList.empty()) {
8409fb074e7SEvgeniy Brevnov const LoopBlock LoopBB = LoopWorkList.pop_back_val();
8419fb074e7SEvgeniy Brevnov
8429fb074e7SEvgeniy Brevnov if (EstimatedLoopWeight.count(LoopBB.getLoopData()))
8439fb074e7SEvgeniy Brevnov continue;
8449fb074e7SEvgeniy Brevnov
8459fb074e7SEvgeniy Brevnov SmallVector<BasicBlock *, 4> Exits;
8469fb074e7SEvgeniy Brevnov getLoopExitBlocks(LoopBB, Exits);
8479fb074e7SEvgeniy Brevnov auto LoopWeight = getMaxEstimatedEdgeWeight(
8489fb074e7SEvgeniy Brevnov LoopBB, make_range(Exits.begin(), Exits.end()));
8499fb074e7SEvgeniy Brevnov
8509fb074e7SEvgeniy Brevnov if (LoopWeight) {
8519fb074e7SEvgeniy Brevnov // If we never exit the loop then we can enter it once at maximum.
8529fb074e7SEvgeniy Brevnov if (LoopWeight <= static_cast<uint32_t>(BlockExecWeight::UNREACHABLE))
8539fb074e7SEvgeniy Brevnov LoopWeight = static_cast<uint32_t>(BlockExecWeight::LOWEST_NON_ZERO);
8549fb074e7SEvgeniy Brevnov
8557a47ee51SKazu Hirata EstimatedLoopWeight.insert({LoopBB.getLoopData(), *LoopWeight});
8569fb074e7SEvgeniy Brevnov // Add all blocks entering the loop into working list.
8579fb074e7SEvgeniy Brevnov getLoopEnterBlocks(LoopBB, BlockWorkList);
8589fb074e7SEvgeniy Brevnov }
8599fb074e7SEvgeniy Brevnov }
8609fb074e7SEvgeniy Brevnov
8619fb074e7SEvgeniy Brevnov while (!BlockWorkList.empty()) {
8629fb074e7SEvgeniy Brevnov // We can reach here only if BlockWorkList is not empty.
8639fb074e7SEvgeniy Brevnov const BasicBlock *BB = BlockWorkList.pop_back_val();
8649fb074e7SEvgeniy Brevnov if (EstimatedBlockWeight.count(BB))
8659fb074e7SEvgeniy Brevnov continue;
8669fb074e7SEvgeniy Brevnov
8679fb074e7SEvgeniy Brevnov // We take maximum over all weights of successors. In other words we take
8689fb074e7SEvgeniy Brevnov // weight of "hot" path. In theory we can probably find a better function
8699fb074e7SEvgeniy Brevnov // which gives higher accuracy results (comparing to "maximum") but I
8709fb074e7SEvgeniy Brevnov // can't
8719fb074e7SEvgeniy Brevnov // think of any right now. And I doubt it will make any difference in
8729fb074e7SEvgeniy Brevnov // practice.
8739fb074e7SEvgeniy Brevnov const LoopBlock LoopBB = getLoopBlock(BB);
8749fb074e7SEvgeniy Brevnov auto MaxWeight = getMaxEstimatedEdgeWeight(LoopBB, successors(BB));
8759fb074e7SEvgeniy Brevnov
8769fb074e7SEvgeniy Brevnov if (MaxWeight)
8777a47ee51SKazu Hirata propagateEstimatedBlockWeight(LoopBB, DT, PDT, *MaxWeight,
8789fb074e7SEvgeniy Brevnov BlockWorkList, LoopWorkList);
8799fb074e7SEvgeniy Brevnov }
8809fb074e7SEvgeniy Brevnov } while (!BlockWorkList.empty() || !LoopWorkList.empty());
8819fb074e7SEvgeniy Brevnov }
8829fb074e7SEvgeniy Brevnov
8839fb074e7SEvgeniy Brevnov // Calculate edge probabilities based on block's estimated weight.
8849fb074e7SEvgeniy Brevnov // Note that gathered weights were not scaled for loops. Thus edges entering
8859fb074e7SEvgeniy Brevnov // and exiting loops requires special processing.
calcEstimatedHeuristics(const BasicBlock * BB)8869fb074e7SEvgeniy Brevnov bool BranchProbabilityInfo::calcEstimatedHeuristics(const BasicBlock *BB) {
8879fb074e7SEvgeniy Brevnov assert(BB->getTerminator()->getNumSuccessors() > 1 &&
8889fb074e7SEvgeniy Brevnov "expected more than one successor!");
8899fb074e7SEvgeniy Brevnov
8909fb074e7SEvgeniy Brevnov const LoopBlock LoopBB = getLoopBlock(BB);
8919fb074e7SEvgeniy Brevnov
89229bbed36SJohn Brawn SmallPtrSet<const BasicBlock *, 8> UnlikelyBlocks;
8939fb074e7SEvgeniy Brevnov uint32_t TC = LBH_TAKEN_WEIGHT / LBH_NONTAKEN_WEIGHT;
8949fb074e7SEvgeniy Brevnov if (LoopBB.getLoop())
8959fb074e7SEvgeniy Brevnov computeUnlikelySuccessors(BB, LoopBB.getLoop(), UnlikelyBlocks);
89629bbed36SJohn Brawn
8979fb074e7SEvgeniy Brevnov // Changed to 'true' if at least one successor has estimated weight.
8989fb074e7SEvgeniy Brevnov bool FoundEstimatedWeight = false;
8999fb074e7SEvgeniy Brevnov SmallVector<uint32_t, 4> SuccWeights;
9009fb074e7SEvgeniy Brevnov uint64_t TotalWeight = 0;
9019fb074e7SEvgeniy Brevnov // Go over all successors of BB and put their weights into SuccWeights.
90228d31320SKazu Hirata for (const BasicBlock *SuccBB : successors(BB)) {
9039fb074e7SEvgeniy Brevnov Optional<uint32_t> Weight;
9049fb074e7SEvgeniy Brevnov const LoopBlock SuccLoopBB = getLoopBlock(SuccBB);
9059fb074e7SEvgeniy Brevnov const LoopEdge Edge{LoopBB, SuccLoopBB};
90602a629daSEvgeniy Brevnov
9079fb074e7SEvgeniy Brevnov Weight = getEstimatedEdgeWeight(Edge);
9089fb074e7SEvgeniy Brevnov
9099fb074e7SEvgeniy Brevnov if (isLoopExitingEdge(Edge) &&
9109fb074e7SEvgeniy Brevnov // Avoid adjustment of ZERO weight since it should remain unchanged.
9119fb074e7SEvgeniy Brevnov Weight != static_cast<uint32_t>(BlockExecWeight::ZERO)) {
9129fb074e7SEvgeniy Brevnov // Scale down loop exiting weight by trip count.
9139fb074e7SEvgeniy Brevnov Weight = std::max(
9149fb074e7SEvgeniy Brevnov static_cast<uint32_t>(BlockExecWeight::LOWEST_NON_ZERO),
915129b531cSKazu Hirata Weight.value_or(static_cast<uint32_t>(BlockExecWeight::DEFAULT)) /
9169fb074e7SEvgeniy Brevnov TC);
917eed6531eSGeoff Berry }
9189fb074e7SEvgeniy Brevnov bool IsUnlikelyEdge = LoopBB.getLoop() && UnlikelyBlocks.contains(SuccBB);
9199fb074e7SEvgeniy Brevnov if (IsUnlikelyEdge &&
9209fb074e7SEvgeniy Brevnov // Avoid adjustment of ZERO weight since it should remain unchanged.
9219fb074e7SEvgeniy Brevnov Weight != static_cast<uint32_t>(BlockExecWeight::ZERO)) {
9229fb074e7SEvgeniy Brevnov // 'Unlikely' blocks have twice lower weight.
9239fb074e7SEvgeniy Brevnov Weight = std::max(
9249fb074e7SEvgeniy Brevnov static_cast<uint32_t>(BlockExecWeight::LOWEST_NON_ZERO),
925129b531cSKazu Hirata Weight.value_or(static_cast<uint32_t>(BlockExecWeight::DEFAULT)) / 2);
92649371f3fSAndrew Trick }
92749371f3fSAndrew Trick
9289fb074e7SEvgeniy Brevnov if (Weight)
9299fb074e7SEvgeniy Brevnov FoundEstimatedWeight = true;
9309fb074e7SEvgeniy Brevnov
9319fb074e7SEvgeniy Brevnov auto WeightVal =
932129b531cSKazu Hirata Weight.value_or(static_cast<uint32_t>(BlockExecWeight::DEFAULT));
9339fb074e7SEvgeniy Brevnov TotalWeight += WeightVal;
9349fb074e7SEvgeniy Brevnov SuccWeights.push_back(WeightVal);
9359fb074e7SEvgeniy Brevnov }
9369fb074e7SEvgeniy Brevnov
9379fb074e7SEvgeniy Brevnov // If non of blocks have estimated weight bail out.
9389fb074e7SEvgeniy Brevnov // If TotalWeight is 0 that means weight of each successor is 0 as well and
9399fb074e7SEvgeniy Brevnov // equally likely. Bail out early to not deal with devision by zero.
9409fb074e7SEvgeniy Brevnov if (!FoundEstimatedWeight || TotalWeight == 0)
9415638b899SAkira Hatanaka return false;
9425638b899SAkira Hatanaka
9439fb074e7SEvgeniy Brevnov assert(SuccWeights.size() == succ_size(BB) && "Missed successor?");
9449fb074e7SEvgeniy Brevnov const unsigned SuccCount = SuccWeights.size();
94549371f3fSAndrew Trick
9469fb074e7SEvgeniy Brevnov // If the sum of weights does not fit in 32 bits, scale every weight down
9479fb074e7SEvgeniy Brevnov // accordingly.
9489fb074e7SEvgeniy Brevnov if (TotalWeight > UINT32_MAX) {
9499fb074e7SEvgeniy Brevnov uint64_t ScalingFactor = TotalWeight / UINT32_MAX + 1;
9509fb074e7SEvgeniy Brevnov TotalWeight = 0;
9519fb074e7SEvgeniy Brevnov for (unsigned Idx = 0; Idx < SuccCount; ++Idx) {
9529fb074e7SEvgeniy Brevnov SuccWeights[Idx] /= ScalingFactor;
9539fb074e7SEvgeniy Brevnov if (SuccWeights[Idx] == static_cast<uint32_t>(BlockExecWeight::ZERO))
9549fb074e7SEvgeniy Brevnov SuccWeights[Idx] =
9559fb074e7SEvgeniy Brevnov static_cast<uint32_t>(BlockExecWeight::LOWEST_NON_ZERO);
9569fb074e7SEvgeniy Brevnov TotalWeight += SuccWeights[Idx];
9579fb074e7SEvgeniy Brevnov }
9589fb074e7SEvgeniy Brevnov assert(TotalWeight <= UINT32_MAX && "Total weight overflows");
9599fb074e7SEvgeniy Brevnov }
9609fb074e7SEvgeniy Brevnov
9619fb074e7SEvgeniy Brevnov // Finally set probabilities to edges according to estimated block weights.
96281384874SYevgeny Rouban SmallVector<BranchProbability, 4> EdgeProbabilities(
9639fb074e7SEvgeniy Brevnov SuccCount, BranchProbability::getUnknown());
96449371f3fSAndrew Trick
9659fb074e7SEvgeniy Brevnov for (unsigned Idx = 0; Idx < SuccCount; ++Idx) {
9669fb074e7SEvgeniy Brevnov EdgeProbabilities[Idx] =
9679fb074e7SEvgeniy Brevnov BranchProbability(SuccWeights[Idx], (uint32_t)TotalWeight);
968bcb3c65bSJakub Staszak }
96981384874SYevgeny Rouban setEdgeProbability(BB, EdgeProbabilities);
970d07b2e15SJakub Staszak return true;
97149371f3fSAndrew Trick }
97249371f3fSAndrew Trick
calcZeroHeuristics(const BasicBlock * BB,const TargetLibraryInfo * TLI)9730f14b2e6SDávid Bolvanský bool BranchProbabilityInfo::calcZeroHeuristics(const BasicBlock *BB,
974da4a68a1SJohn Brawn const TargetLibraryInfo *TLI) {
975a797877aSMehdi Amini const BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator());
97617af66a6SJakub Staszak if (!BI || !BI->isConditional())
97717af66a6SJakub Staszak return false;
97817af66a6SJakub Staszak
97917af66a6SJakub Staszak Value *Cond = BI->getCondition();
98017af66a6SJakub Staszak ICmpInst *CI = dyn_cast<ICmpInst>(Cond);
98117af66a6SJakub Staszak if (!CI)
98217af66a6SJakub Staszak return false;
98317af66a6SJakub Staszak
9840b53e845SSam Parker auto GetConstantInt = [](Value *V) {
9850b53e845SSam Parker if (auto *I = dyn_cast<BitCastInst>(V))
9860b53e845SSam Parker return dyn_cast<ConstantInt>(I->getOperand(0));
9870b53e845SSam Parker return dyn_cast<ConstantInt>(V);
9880b53e845SSam Parker };
9890b53e845SSam Parker
99017af66a6SJakub Staszak Value *RHS = CI->getOperand(1);
9910b53e845SSam Parker ConstantInt *CV = GetConstantInt(RHS);
9920f14b2e6SDávid Bolvanský if (!CV)
9930f14b2e6SDávid Bolvanský return false;
99417af66a6SJakub Staszak
995a73f3d51SDaniel Jasper // If the LHS is the result of AND'ing a value with a single bit bitmask,
996a73f3d51SDaniel Jasper // we don't have information about probabilities.
997a73f3d51SDaniel Jasper if (Instruction *LHS = dyn_cast<Instruction>(CI->getOperand(0)))
998a73f3d51SDaniel Jasper if (LHS->getOpcode() == Instruction::And)
9993279347dSWei Wang if (ConstantInt *AndRHS = GetConstantInt(LHS->getOperand(1)))
10004e22ee67SCraig Topper if (AndRHS->getValue().isPowerOf2())
1001a73f3d51SDaniel Jasper return false;
1002a73f3d51SDaniel Jasper
1003da4a68a1SJohn Brawn // Check if the LHS is the return value of a library function
1004da4a68a1SJohn Brawn LibFunc Func = NumLibFuncs;
1005da4a68a1SJohn Brawn if (TLI)
1006da4a68a1SJohn Brawn if (CallInst *Call = dyn_cast<CallInst>(CI->getOperand(0)))
1007da4a68a1SJohn Brawn if (Function *CalledFn = Call->getCalledFunction())
1008da4a68a1SJohn Brawn TLI->getLibFunc(*CalledFn, Func);
1009da4a68a1SJohn Brawn
10104d21b644SSjoerd Meijer ProbabilityTable::const_iterator Search;
1011da4a68a1SJohn Brawn if (Func == LibFunc_strcasecmp ||
1012da4a68a1SJohn Brawn Func == LibFunc_strcmp ||
1013da4a68a1SJohn Brawn Func == LibFunc_strncasecmp ||
1014da4a68a1SJohn Brawn Func == LibFunc_strncmp ||
1015d68a2859SDávid Bolvanský Func == LibFunc_memcmp ||
1016d68a2859SDávid Bolvanský Func == LibFunc_bcmp) {
10174d21b644SSjoerd Meijer Search = ICmpWithLibCallTable.find(CI->getPredicate());
10184d21b644SSjoerd Meijer if (Search == ICmpWithLibCallTable.end())
1019da4a68a1SJohn Brawn return false;
1020da4a68a1SJohn Brawn } else if (CV->isZero()) {
10214d21b644SSjoerd Meijer Search = ICmpWithZeroTable.find(CI->getPredicate());
10224d21b644SSjoerd Meijer if (Search == ICmpWithZeroTable.end())
102317af66a6SJakub Staszak return false;
10244d21b644SSjoerd Meijer } else if (CV->isOne()) {
10254d21b644SSjoerd Meijer Search = ICmpWithOneTable.find(CI->getPredicate());
10264d21b644SSjoerd Meijer if (Search == ICmpWithOneTable.end())
10274d21b644SSjoerd Meijer return false;
102879ab643dSCraig Topper } else if (CV->isMinusOne()) {
10294d21b644SSjoerd Meijer Search = ICmpWithMinusOneTable.find(CI->getPredicate());
10304d21b644SSjoerd Meijer if (Search == ICmpWithMinusOneTable.end())
10314d94930bSHal Finkel return false;
10320ca1ad07SBenjamin Kramer } else {
10330ca1ad07SBenjamin Kramer return false;
10340ca1ad07SBenjamin Kramer }
103517af66a6SJakub Staszak
10364d21b644SSjoerd Meijer setEdgeProbability(BB, Search->second);
103717af66a6SJakub Staszak return true;
103817af66a6SJakub Staszak }
103917af66a6SJakub Staszak
calcFloatingPointHeuristics(const BasicBlock * BB)1040a797877aSMehdi Amini bool BranchProbabilityInfo::calcFloatingPointHeuristics(const BasicBlock *BB) {
1041a797877aSMehdi Amini const BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator());
10421e731a10SBenjamin Kramer if (!BI || !BI->isConditional())
10431e731a10SBenjamin Kramer return false;
10441e731a10SBenjamin Kramer
10451e731a10SBenjamin Kramer Value *Cond = BI->getCondition();
10461e731a10SBenjamin Kramer FCmpInst *FCmp = dyn_cast<FCmpInst>(Cond);
1047606a50a9SBenjamin Kramer if (!FCmp)
10481e731a10SBenjamin Kramer return false;
10491e731a10SBenjamin Kramer
10504d21b644SSjoerd Meijer ProbabilityList ProbList;
1051606a50a9SBenjamin Kramer if (FCmp->isEquality()) {
10524d21b644SSjoerd Meijer ProbList = !FCmp->isTrueWhenEqual() ?
1053606a50a9SBenjamin Kramer // f1 == f2 -> Unlikely
10544d21b644SSjoerd Meijer ProbabilityList({FPTakenProb, FPUntakenProb}) :
1055606a50a9SBenjamin Kramer // f1 != f2 -> Likely
10564d21b644SSjoerd Meijer ProbabilityList({FPUntakenProb, FPTakenProb});
1057606a50a9SBenjamin Kramer } else {
10584d21b644SSjoerd Meijer auto Search = FCmpTable.find(FCmp->getPredicate());
10594d21b644SSjoerd Meijer if (Search == FCmpTable.end())
1060606a50a9SBenjamin Kramer return false;
10614d21b644SSjoerd Meijer ProbList = Search->second;
1062606a50a9SBenjamin Kramer }
1063606a50a9SBenjamin Kramer
10644d21b644SSjoerd Meijer setEdgeProbability(BB, ProbList);
10651e731a10SBenjamin Kramer return true;
10661e731a10SBenjamin Kramer }
106717af66a6SJakub Staszak
releaseMemory()1068b9d2e34aSPete Cooper void BranchProbabilityInfo::releaseMemory() {
1069e93b8e15SCong Hou Probs.clear();
1070fe8abbf4SNikita Popov Handles.clear();
1071b9d2e34aSPete Cooper }
1072b9d2e34aSPete Cooper
invalidate(Function &,const PreservedAnalyses & PA,FunctionAnalysisManager::Invalidator &)107362a50a95SAlina Sbirlea bool BranchProbabilityInfo::invalidate(Function &, const PreservedAnalyses &PA,
107462a50a95SAlina Sbirlea FunctionAnalysisManager::Invalidator &) {
107562a50a95SAlina Sbirlea // Check whether the analysis, all analyses on functions, or the function's
107662a50a95SAlina Sbirlea // CFG have been preserved.
107762a50a95SAlina Sbirlea auto PAC = PA.getChecker<BranchProbabilityAnalysis>();
107862a50a95SAlina Sbirlea return !(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>() ||
107962a50a95SAlina Sbirlea PAC.preservedSet<CFGAnalyses>());
108062a50a95SAlina Sbirlea }
108162a50a95SAlina Sbirlea
print(raw_ostream & OS) const1082ab23bfbcSCong Hou void BranchProbabilityInfo::print(raw_ostream &OS) const {
10831c8ace0eSChandler Carruth OS << "---- Branch Probabilities ----\n";
10841c8ace0eSChandler Carruth // We print the probabilities from the last function the analysis ran over,
10851c8ace0eSChandler Carruth // or the function it is currently running over.
10861c8ace0eSChandler Carruth assert(LastF && "Cannot print prior to running over a function");
10875a82c916SDuncan P. N. Exon Smith for (const auto &BI : *LastF) {
108828d31320SKazu Hirata for (const BasicBlock *Succ : successors(&BI))
108928d31320SKazu Hirata printEdgeProbability(OS << " ", &BI, Succ);
10906c99015fSDuncan P. N. Exon Smith }
10911c8ace0eSChandler Carruth }
10921c8ace0eSChandler Carruth
1093efd94c8fSJakub Staszak bool BranchProbabilityInfo::
isEdgeHot(const BasicBlock * Src,const BasicBlock * Dst) const1094efd94c8fSJakub Staszak isEdgeHot(const BasicBlock *Src, const BasicBlock *Dst) const {
10953d4e64b0SAndrew Trick // Hot probability is at least 4/5 = 80%
1096929f53f6SBenjamin Kramer // FIXME: Compare against a static "hot" BranchProbability.
1097929f53f6SBenjamin Kramer return getEdgeProbability(Src, Dst) > BranchProbability(4, 5);
109849371f3fSAndrew Trick }
109949371f3fSAndrew Trick
1100e93b8e15SCong Hou /// Get the raw edge probability for the edge. If can't find it, return a
1101e93b8e15SCong Hou /// default probability 1/N where N is the number of successors. Here an edge is
1102e93b8e15SCong Hou /// specified using PredBlock and an
1103e93b8e15SCong Hou /// index to the successors.
1104e93b8e15SCong Hou BranchProbability
getEdgeProbability(const BasicBlock * Src,unsigned IndexInSuccessors) const1105e93b8e15SCong Hou BranchProbabilityInfo::getEdgeProbability(const BasicBlock *Src,
1106e93b8e15SCong Hou unsigned IndexInSuccessors) const {
110721fbe2eeSKazu Hirata auto I = Probs.find(std::make_pair(Src, IndexInSuccessors));
110821fbe2eeSKazu Hirata assert((Probs.end() == Probs.find(std::make_pair(Src, 0))) ==
110921fbe2eeSKazu Hirata (Probs.end() == I) &&
111021fbe2eeSKazu Hirata "Probability for I-th successor must always be defined along with the "
111121fbe2eeSKazu Hirata "probability for the first successor");
11122f1038c7SKazu Hirata
111321fbe2eeSKazu Hirata if (I != Probs.end())
111421fbe2eeSKazu Hirata return I->second;
111521fbe2eeSKazu Hirata
111621fbe2eeSKazu Hirata return {1, static_cast<uint32_t>(succ_size(Src))};
11173d4e64b0SAndrew Trick }
11183d4e64b0SAndrew Trick
1119d97c100dSCong Hou BranchProbability
getEdgeProbability(const BasicBlock * Src,const_succ_iterator Dst) const1120d97c100dSCong Hou BranchProbabilityInfo::getEdgeProbability(const BasicBlock *Src,
11213abcbf99SAlina Sbirlea const_succ_iterator Dst) const {
1122d97c100dSCong Hou return getEdgeProbability(Src, Dst.getSuccessorIndex());
1123d97c100dSCong Hou }
1124d97c100dSCong Hou
1125e93b8e15SCong Hou /// Get the raw edge probability calculated for the block pair. This returns the
1126e93b8e15SCong Hou /// sum of all raw edge probabilities from Src to Dst.
1127e93b8e15SCong Hou BranchProbability
getEdgeProbability(const BasicBlock * Src,const BasicBlock * Dst) const1128e93b8e15SCong Hou BranchProbabilityInfo::getEdgeProbability(const BasicBlock *Src,
1129e93b8e15SCong Hou const BasicBlock *Dst) const {
113021fbe2eeSKazu Hirata if (!Probs.count(std::make_pair(Src, 0)))
1131118c3f3cSKazu Hirata return BranchProbability(llvm::count(successors(Src), Dst), succ_size(Src));
1132118c3f3cSKazu Hirata
1133e93b8e15SCong Hou auto Prob = BranchProbability::getZero();
11343abcbf99SAlina Sbirlea for (const_succ_iterator I = succ_begin(Src), E = succ_end(Src); I != E; ++I)
1135118c3f3cSKazu Hirata if (*I == Dst)
113621fbe2eeSKazu Hirata Prob += Probs.find(std::make_pair(Src, I.getSuccessorIndex()))->second;
1137118c3f3cSKazu Hirata
1138118c3f3cSKazu Hirata return Prob;
1139e93b8e15SCong Hou }
1140e93b8e15SCong Hou
114181384874SYevgeny Rouban /// Set the edge probability for all edges at once.
setEdgeProbability(const BasicBlock * Src,const SmallVectorImpl<BranchProbability> & Probs)114281384874SYevgeny Rouban void BranchProbabilityInfo::setEdgeProbability(
114381384874SYevgeny Rouban const BasicBlock *Src, const SmallVectorImpl<BranchProbability> &Probs) {
114481384874SYevgeny Rouban assert(Src->getTerminator()->getNumSuccessors() == Probs.size());
11454931158dSYevgeny Rouban eraseBlock(Src); // Erase stale data if any.
114681384874SYevgeny Rouban if (Probs.size() == 0)
114781384874SYevgeny Rouban return; // Nothing to set.
114881384874SYevgeny Rouban
1149e38c8e75SYevgeny Rouban Handles.insert(BasicBlockCallbackVH(Src, this));
115081384874SYevgeny Rouban uint64_t TotalNumerator = 0;
115181384874SYevgeny Rouban for (unsigned SuccIdx = 0; SuccIdx < Probs.size(); ++SuccIdx) {
115221fbe2eeSKazu Hirata this->Probs[std::make_pair(Src, SuccIdx)] = Probs[SuccIdx];
11534931158dSYevgeny Rouban LLVM_DEBUG(dbgs() << "set edge " << Src->getName() << " -> " << SuccIdx
11544931158dSYevgeny Rouban << " successor probability to " << Probs[SuccIdx]
11554931158dSYevgeny Rouban << "\n");
115681384874SYevgeny Rouban TotalNumerator += Probs[SuccIdx].getNumerator();
115781384874SYevgeny Rouban }
115881384874SYevgeny Rouban
115981384874SYevgeny Rouban // Because of rounding errors the total probability cannot be checked to be
116081384874SYevgeny Rouban // 1.0 exactly. That is TotalNumerator == BranchProbability::getDenominator.
116181384874SYevgeny Rouban // Instead, every single probability in Probs must be as accurate as possible.
116281384874SYevgeny Rouban // This results in error 1/denominator at most, thus the total absolute error
116381384874SYevgeny Rouban // should be within Probs.size / BranchProbability::getDenominator.
116481384874SYevgeny Rouban assert(TotalNumerator <= BranchProbability::getDenominator() + Probs.size());
116581384874SYevgeny Rouban assert(TotalNumerator >= BranchProbability::getDenominator() - Probs.size());
116606e7de79SFangrui Song (void)TotalNumerator;
116781384874SYevgeny Rouban }
116881384874SYevgeny Rouban
copyEdgeProbabilities(BasicBlock * Src,BasicBlock * Dst)1169681d6c71SYevgeny Rouban void BranchProbabilityInfo::copyEdgeProbabilities(BasicBlock *Src,
1170681d6c71SYevgeny Rouban BasicBlock *Dst) {
1171681d6c71SYevgeny Rouban eraseBlock(Dst); // Erase stale data if any.
1172681d6c71SYevgeny Rouban unsigned NumSuccessors = Src->getTerminator()->getNumSuccessors();
1173681d6c71SYevgeny Rouban assert(NumSuccessors == Dst->getTerminator()->getNumSuccessors());
1174681d6c71SYevgeny Rouban if (NumSuccessors == 0)
1175681d6c71SYevgeny Rouban return; // Nothing to set.
117621fbe2eeSKazu Hirata if (this->Probs.find(std::make_pair(Src, 0)) == this->Probs.end())
1177681d6c71SYevgeny Rouban return; // No probability is set for edges from Src. Keep the same for Dst.
1178681d6c71SYevgeny Rouban
1179681d6c71SYevgeny Rouban Handles.insert(BasicBlockCallbackVH(Dst, this));
118021fbe2eeSKazu Hirata for (unsigned SuccIdx = 0; SuccIdx < NumSuccessors; ++SuccIdx) {
118121fbe2eeSKazu Hirata auto Prob = this->Probs[std::make_pair(Src, SuccIdx)];
118221fbe2eeSKazu Hirata this->Probs[std::make_pair(Dst, SuccIdx)] = Prob;
1183681d6c71SYevgeny Rouban LLVM_DEBUG(dbgs() << "set edge " << Dst->getName() << " -> " << SuccIdx
118421fbe2eeSKazu Hirata << " successor probability to " << Prob << "\n");
118521fbe2eeSKazu Hirata }
1186681d6c71SYevgeny Rouban }
1187681d6c71SYevgeny Rouban
118849371f3fSAndrew Trick raw_ostream &
printEdgeProbability(raw_ostream & OS,const BasicBlock * Src,const BasicBlock * Dst) const11891c8ace0eSChandler Carruth BranchProbabilityInfo::printEdgeProbability(raw_ostream &OS,
11901c8ace0eSChandler Carruth const BasicBlock *Src,
11911c8ace0eSChandler Carruth const BasicBlock *Dst) const {
119212a43bddSJakub Staszak const BranchProbability Prob = getEdgeProbability(Src, Dst);
11931f97a5a6SBenjamin Kramer OS << "edge " << Src->getName() << " -> " << Dst->getName()
11943d4e64b0SAndrew Trick << " probability is " << Prob
11953d4e64b0SAndrew Trick << (isEdgeHot(Src, Dst) ? " [HOT edge]\n" : "\n");
119649371f3fSAndrew Trick
119749371f3fSAndrew Trick return OS;
119849371f3fSAndrew Trick }
1199ab23bfbcSCong Hou
eraseBlock(const BasicBlock * BB)1200ee40d1e8SIgor Laevsky void BranchProbabilityInfo::eraseBlock(const BasicBlock *BB) {
1201147ccc84SKazu Hirata LLVM_DEBUG(dbgs() << "eraseBlock " << BB->getName() << "\n");
1202147ccc84SKazu Hirata
120321fbe2eeSKazu Hirata // Note that we cannot use successors of BB because the terminator of BB may
120421fbe2eeSKazu Hirata // have changed when eraseBlock is called as a BasicBlockCallbackVH callback.
120521fbe2eeSKazu Hirata // Instead we remove prob data for the block by iterating successors by their
120621fbe2eeSKazu Hirata // indices from 0 till the last which exists. There could not be prob data for
120721fbe2eeSKazu Hirata // a pair (BB, N) if there is no data for (BB, N-1) because the data is always
120821fbe2eeSKazu Hirata // set for all successors from 0 to M at once by the method
120921fbe2eeSKazu Hirata // setEdgeProbability().
1210e38c8e75SYevgeny Rouban Handles.erase(BasicBlockCallbackVH(BB, this));
121121fbe2eeSKazu Hirata for (unsigned I = 0;; ++I) {
121221fbe2eeSKazu Hirata auto MapI = Probs.find(std::make_pair(BB, I));
121321fbe2eeSKazu Hirata if (MapI == Probs.end()) {
121421fbe2eeSKazu Hirata assert(Probs.count(std::make_pair(BB, I + 1)) == 0 &&
121521fbe2eeSKazu Hirata "Must be no more successors");
121621fbe2eeSKazu Hirata return;
121721fbe2eeSKazu Hirata }
121821fbe2eeSKazu Hirata Probs.erase(MapI);
121921fbe2eeSKazu Hirata }
1220ee40d1e8SIgor Laevsky }
1221ee40d1e8SIgor Laevsky
calculate(const Function & F,const LoopInfo & LoopI,const TargetLibraryInfo * TLI,DominatorTree * DT,PostDominatorTree * PDT)12229fb074e7SEvgeniy Brevnov void BranchProbabilityInfo::calculate(const Function &F, const LoopInfo &LoopI,
12233e68a667SEvgeniy Brevnov const TargetLibraryInfo *TLI,
12249fb074e7SEvgeniy Brevnov DominatorTree *DT,
12253e68a667SEvgeniy Brevnov PostDominatorTree *PDT) {
1226d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "---- Branch Probability Info : " << F.getName()
1227ab23bfbcSCong Hou << " ----\n\n");
1228ab23bfbcSCong Hou LastF = &F; // Store the last function we ran on for printing.
12299fb074e7SEvgeniy Brevnov LI = &LoopI;
1230ab23bfbcSCong Hou
12313a2b05f9SEvgeniy Brevnov SccI = std::make_unique<SccInfo>(F);
1232eed6531eSGeoff Berry
12339fb074e7SEvgeniy Brevnov assert(EstimatedBlockWeight.empty());
12349fb074e7SEvgeniy Brevnov assert(EstimatedLoopWeight.empty());
12359fb074e7SEvgeniy Brevnov
12369fb074e7SEvgeniy Brevnov std::unique_ptr<DominatorTree> DTPtr;
12373e68a667SEvgeniy Brevnov std::unique_ptr<PostDominatorTree> PDTPtr;
12383e68a667SEvgeniy Brevnov
12399fb074e7SEvgeniy Brevnov if (!DT) {
12409fb074e7SEvgeniy Brevnov DTPtr = std::make_unique<DominatorTree>(const_cast<Function &>(F));
12419fb074e7SEvgeniy Brevnov DT = DTPtr.get();
12429fb074e7SEvgeniy Brevnov }
12439fb074e7SEvgeniy Brevnov
12443e68a667SEvgeniy Brevnov if (!PDT) {
12453e68a667SEvgeniy Brevnov PDTPtr = std::make_unique<PostDominatorTree>(const_cast<Function &>(F));
12463e68a667SEvgeniy Brevnov PDT = PDTPtr.get();
12473e68a667SEvgeniy Brevnov }
12483e68a667SEvgeniy Brevnov
12499fb074e7SEvgeniy Brevnov computeEestimateBlockWeight(F, DT, PDT);
12502da205d4STaewook Oh
1251ab23bfbcSCong Hou // Walk the basic blocks in post-order so that we can build up state about
1252ab23bfbcSCong Hou // the successors of a block iteratively.
1253*601b3a13SKazu Hirata for (const auto *BB : post_order(&F.getEntryBlock())) {
1254d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Computing probabilities for " << BB->getName()
1255d34e60caSNicola Zaghen << "\n");
125611d9c4f6SSerguei Katkov // If there is no at least two successors, no sense to set probability.
125711d9c4f6SSerguei Katkov if (BB->getTerminator()->getNumSuccessors() < 2)
125811d9c4f6SSerguei Katkov continue;
1259ab23bfbcSCong Hou if (calcMetadataWeights(BB))
1260ab23bfbcSCong Hou continue;
12619fb074e7SEvgeniy Brevnov if (calcEstimatedHeuristics(BB))
1262ab23bfbcSCong Hou continue;
1263ab23bfbcSCong Hou if (calcPointerHeuristics(BB))
1264ab23bfbcSCong Hou continue;
12650f14b2e6SDávid Bolvanský if (calcZeroHeuristics(BB, TLI))
1266ab23bfbcSCong Hou continue;
1267ab23bfbcSCong Hou if (calcFloatingPointHeuristics(BB))
1268ab23bfbcSCong Hou continue;
1269ab23bfbcSCong Hou }
1270ab23bfbcSCong Hou
12719fb074e7SEvgeniy Brevnov EstimatedLoopWeight.clear();
12729fb074e7SEvgeniy Brevnov EstimatedBlockWeight.clear();
1273412b3932SEvgeniy Brevnov SccI.reset();
127463e17ebfSHiroshi Yamauchi
127563e17ebfSHiroshi Yamauchi if (PrintBranchProb &&
127663e17ebfSHiroshi Yamauchi (PrintBranchProbFuncName.empty() ||
127763e17ebfSHiroshi Yamauchi F.getName().equals(PrintBranchProbFuncName))) {
127863e17ebfSHiroshi Yamauchi print(dbgs());
127963e17ebfSHiroshi Yamauchi }
1280ab23bfbcSCong Hou }
1281ab23bfbcSCong Hou
getAnalysisUsage(AnalysisUsage & AU) const1282ab23bfbcSCong Hou void BranchProbabilityInfoWrapperPass::getAnalysisUsage(
1283ab23bfbcSCong Hou AnalysisUsage &AU) const {
12842ca16899SMikael Holmen // We require DT so it's available when LI is available. The LI updating code
12852ca16899SMikael Holmen // asserts that DT is also present so if we don't make sure that we have DT
12862ca16899SMikael Holmen // here, that assert will trigger.
12872ca16899SMikael Holmen AU.addRequired<DominatorTreeWrapperPass>();
1288ab23bfbcSCong Hou AU.addRequired<LoopInfoWrapperPass>();
1289da4a68a1SJohn Brawn AU.addRequired<TargetLibraryInfoWrapperPass>();
12909fb074e7SEvgeniy Brevnov AU.addRequired<DominatorTreeWrapperPass>();
12913e68a667SEvgeniy Brevnov AU.addRequired<PostDominatorTreeWrapperPass>();
1292ab23bfbcSCong Hou AU.setPreservesAll();
1293ab23bfbcSCong Hou }
1294ab23bfbcSCong Hou
runOnFunction(Function & F)1295ab23bfbcSCong Hou bool BranchProbabilityInfoWrapperPass::runOnFunction(Function &F) {
1296ab23bfbcSCong Hou const LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
12979c27b59cSTeresa Johnson const TargetLibraryInfo &TLI =
12989c27b59cSTeresa Johnson getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
12999fb074e7SEvgeniy Brevnov DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
13003e68a667SEvgeniy Brevnov PostDominatorTree &PDT =
13013e68a667SEvgeniy Brevnov getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
13029fb074e7SEvgeniy Brevnov BPI.calculate(F, LI, &TLI, &DT, &PDT);
1303ab23bfbcSCong Hou return false;
1304ab23bfbcSCong Hou }
1305ab23bfbcSCong Hou
releaseMemory()1306ab23bfbcSCong Hou void BranchProbabilityInfoWrapperPass::releaseMemory() { BPI.releaseMemory(); }
1307ab23bfbcSCong Hou
print(raw_ostream & OS,const Module *) const1308ab23bfbcSCong Hou void BranchProbabilityInfoWrapperPass::print(raw_ostream &OS,
1309ab23bfbcSCong Hou const Module *) const {
1310ab23bfbcSCong Hou BPI.print(OS);
1311ab23bfbcSCong Hou }
13126e5dd414SXinliang David Li
1313dab4eae2SChandler Carruth AnalysisKey BranchProbabilityAnalysis::Key;
13146e5dd414SXinliang David Li BranchProbabilityInfo
run(Function & F,FunctionAnalysisManager & AM)131536e0d01eSSean Silva BranchProbabilityAnalysis::run(Function &F, FunctionAnalysisManager &AM) {
13166e5dd414SXinliang David Li BranchProbabilityInfo BPI;
13173e68a667SEvgeniy Brevnov BPI.calculate(F, AM.getResult<LoopAnalysis>(F),
13183e68a667SEvgeniy Brevnov &AM.getResult<TargetLibraryAnalysis>(F),
13199fb074e7SEvgeniy Brevnov &AM.getResult<DominatorTreeAnalysis>(F),
13203e68a667SEvgeniy Brevnov &AM.getResult<PostDominatorTreeAnalysis>(F));
13216e5dd414SXinliang David Li return BPI;
13226e5dd414SXinliang David Li }
13236e5dd414SXinliang David Li
13246e5dd414SXinliang David Li PreservedAnalyses
run(Function & F,FunctionAnalysisManager & AM)132536e0d01eSSean Silva BranchProbabilityPrinterPass::run(Function &F, FunctionAnalysisManager &AM) {
13266e5dd414SXinliang David Li OS << "Printing analysis results of BPI for function "
13276e5dd414SXinliang David Li << "'" << F.getName() << "':"
13286e5dd414SXinliang David Li << "\n";
13296e5dd414SXinliang David Li AM.getResult<BranchProbabilityAnalysis>(F).print(OS);
13306e5dd414SXinliang David Li return PreservedAnalyses::all();
13316e5dd414SXinliang David Li }
1332