| //===- MachineBranchProbabilityInfo.cpp - Machine Branch Probability Info -===// | |
| // | |
| // The LLVM Compiler Infrastructure | |
| // | |
| // This file is distributed under the University of Illinois Open Source | |
| // License. See LICENSE.TXT for details. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // This analysis uses probability info stored in Machine Basic Blocks. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "llvm/Instructions.h" | |
| #include "llvm/CodeGen/MachineBranchProbabilityInfo.h" | |
| #include "llvm/CodeGen/MachineBasicBlock.h" | |
| #include "llvm/Support/Debug.h" | |
| #include "llvm/Support/raw_ostream.h" | |
| using namespace llvm; | |
| INITIALIZE_PASS_BEGIN(MachineBranchProbabilityInfo, "machine-branch-prob", | |
| "Machine Branch Probability Analysis", false, true) | |
| INITIALIZE_PASS_END(MachineBranchProbabilityInfo, "machine-branch-prob", | |
| "Machine Branch Probability Analysis", false, true) | |
| char MachineBranchProbabilityInfo::ID = 0; | |
| uint32_t MachineBranchProbabilityInfo:: | |
| getSumForBlock(MachineBasicBlock *MBB) const { | |
| uint32_t Sum = 0; | |
| for (MachineBasicBlock::const_succ_iterator I = MBB->succ_begin(), | |
| E = MBB->succ_end(); I != E; ++I) { | |
| MachineBasicBlock *Succ = *I; | |
| uint32_t Weight = getEdgeWeight(MBB, Succ); | |
| uint32_t PrevSum = Sum; | |
| Sum += Weight; | |
| assert(Sum > PrevSum); (void) PrevSum; | |
| } | |
| return Sum; | |
| } | |
| uint32_t | |
| MachineBranchProbabilityInfo::getEdgeWeight(MachineBasicBlock *Src, | |
| MachineBasicBlock *Dst) const { | |
| uint32_t Weight = Src->getSuccWeight(Dst); | |
| if (!Weight) | |
| return DEFAULT_WEIGHT; | |
| return Weight; | |
| } | |
| bool MachineBranchProbabilityInfo::isEdgeHot(MachineBasicBlock *Src, | |
| MachineBasicBlock *Dst) const { | |
| // Hot probability is at least 4/5 = 80% | |
| uint32_t Weight = getEdgeWeight(Src, Dst); | |
| uint32_t Sum = getSumForBlock(Src); | |
| // FIXME: Implement BranchProbability::compare then change this code to | |
| // compare this BranchProbability against a static "hot" BranchProbability. | |
| return (uint64_t)Weight * 5 > (uint64_t)Sum * 4; | |
| } | |
| MachineBasicBlock * | |
| MachineBranchProbabilityInfo::getHotSucc(MachineBasicBlock *MBB) const { | |
| uint32_t Sum = 0; | |
| uint32_t MaxWeight = 0; | |
| MachineBasicBlock *MaxSucc = 0; | |
| for (MachineBasicBlock::const_succ_iterator I = MBB->succ_begin(), | |
| E = MBB->succ_end(); I != E; ++I) { | |
| MachineBasicBlock *Succ = *I; | |
| uint32_t Weight = getEdgeWeight(MBB, Succ); | |
| uint32_t PrevSum = Sum; | |
| Sum += Weight; | |
| assert(Sum > PrevSum); (void) PrevSum; | |
| if (Weight > MaxWeight) { | |
| MaxWeight = Weight; | |
| MaxSucc = Succ; | |
| } | |
| } | |
| // FIXME: Use BranchProbability::compare. | |
| if ((uint64_t)MaxWeight * 5 >= (uint64_t)Sum * 4) | |
| return MaxSucc; | |
| return 0; | |
| } | |
| BranchProbability | |
| MachineBranchProbabilityInfo::getEdgeProbability(MachineBasicBlock *Src, | |
| MachineBasicBlock *Dst) const { | |
| uint32_t N = getEdgeWeight(Src, Dst); | |
| uint32_t D = getSumForBlock(Src); | |
| return BranchProbability(N, D); | |
| } | |
| raw_ostream &MachineBranchProbabilityInfo:: | |
| printEdgeProbability(raw_ostream &OS, MachineBasicBlock *Src, | |
| MachineBasicBlock *Dst) const { | |
| const BranchProbability Prob = getEdgeProbability(Src, Dst); | |
| OS << "edge MBB#" << Src->getNumber() << " -> MBB#" << Dst->getNumber() | |
| << " probability is " << Prob | |
| << (isEdgeHot(Src, Dst) ? " [HOT edge]\n" : "\n"); | |
| return OS; | |
| } |