LLVM API Documentation

MachineBranchProbabilityInfo.cpp
Go to the documentation of this file.
00001 //===- MachineBranchProbabilityInfo.cpp - Machine Branch Probability Info -===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This analysis uses probability info stored in Machine Basic Blocks.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
00015 #include "llvm/CodeGen/MachineBasicBlock.h"
00016 #include "llvm/IR/Instructions.h"
00017 #include "llvm/Support/Debug.h"
00018 #include "llvm/Support/raw_ostream.h"
00019 
00020 using namespace llvm;
00021 
00022 INITIALIZE_PASS_BEGIN(MachineBranchProbabilityInfo, "machine-branch-prob",
00023                       "Machine Branch Probability Analysis", false, true)
00024 INITIALIZE_PASS_END(MachineBranchProbabilityInfo, "machine-branch-prob",
00025                     "Machine Branch Probability Analysis", false, true)
00026 
00027 char MachineBranchProbabilityInfo::ID = 0;
00028 
00029 void MachineBranchProbabilityInfo::anchor() { }
00030 
00031 uint32_t MachineBranchProbabilityInfo::
00032 getSumForBlock(const MachineBasicBlock *MBB, uint32_t &Scale) const {
00033   // First we compute the sum with 64-bits of precision, ensuring that cannot
00034   // overflow by bounding the number of weights considered. Hopefully no one
00035   // actually needs 2^32 successors.
00036   assert(MBB->succ_size() < UINT32_MAX);
00037   uint64_t Sum = 0;
00038   Scale = 1;
00039   for (MachineBasicBlock::const_succ_iterator I = MBB->succ_begin(),
00040        E = MBB->succ_end(); I != E; ++I) {
00041     uint32_t Weight = getEdgeWeight(MBB, I);
00042     Sum += Weight;
00043   }
00044 
00045   // If the computed sum fits in 32-bits, we're done.
00046   if (Sum <= UINT32_MAX)
00047     return Sum;
00048 
00049   // Otherwise, compute the scale necessary to cause the weights to fit, and
00050   // re-sum with that scale applied.
00051   assert((Sum / UINT32_MAX) < UINT32_MAX);
00052   Scale = (Sum / UINT32_MAX) + 1;
00053   Sum = 0;
00054   for (MachineBasicBlock::const_succ_iterator I = MBB->succ_begin(),
00055        E = MBB->succ_end(); I != E; ++I) {
00056     uint32_t Weight = getEdgeWeight(MBB, I);
00057     Sum += Weight / Scale;
00058   }
00059   assert(Sum <= UINT32_MAX);
00060   return Sum;
00061 }
00062 
00063 uint32_t MachineBranchProbabilityInfo::
00064 getEdgeWeight(const MachineBasicBlock *Src,
00065               MachineBasicBlock::const_succ_iterator Dst) const {
00066   uint32_t Weight = Src->getSuccWeight(Dst);
00067   if (!Weight)
00068     return DEFAULT_WEIGHT;
00069   return Weight;
00070 }
00071 
00072 uint32_t MachineBranchProbabilityInfo::
00073 getEdgeWeight(const MachineBasicBlock *Src,
00074               const MachineBasicBlock *Dst) const {
00075   // This is a linear search. Try to use the const_succ_iterator version when
00076   // possible.
00077   return getEdgeWeight(Src, std::find(Src->succ_begin(), Src->succ_end(), Dst));
00078 }
00079 
00080 bool
00081 MachineBranchProbabilityInfo::isEdgeHot(const MachineBasicBlock *Src,
00082                                         const MachineBasicBlock *Dst) const {
00083   // Hot probability is at least 4/5 = 80%
00084   // FIXME: Compare against a static "hot" BranchProbability.
00085   return getEdgeProbability(Src, Dst) > BranchProbability(4, 5);
00086 }
00087 
00088 MachineBasicBlock *
00089 MachineBranchProbabilityInfo::getHotSucc(MachineBasicBlock *MBB) const {
00090   uint32_t MaxWeight = 0;
00091   MachineBasicBlock *MaxSucc = nullptr;
00092   for (MachineBasicBlock::const_succ_iterator I = MBB->succ_begin(),
00093        E = MBB->succ_end(); I != E; ++I) {
00094     uint32_t Weight = getEdgeWeight(MBB, I);
00095     if (Weight > MaxWeight) {
00096       MaxWeight = Weight;
00097       MaxSucc = *I;
00098     }
00099   }
00100 
00101   if (getEdgeProbability(MBB, MaxSucc) >= BranchProbability(4, 5))
00102     return MaxSucc;
00103 
00104   return nullptr;
00105 }
00106 
00107 BranchProbability MachineBranchProbabilityInfo::getEdgeProbability(
00108     const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const {
00109   uint32_t Scale = 1;
00110   uint32_t D = getSumForBlock(Src, Scale);
00111   uint32_t N = getEdgeWeight(Src, Dst) / Scale;
00112 
00113   return BranchProbability(N, D);
00114 }
00115 
00116 raw_ostream &MachineBranchProbabilityInfo::printEdgeProbability(
00117     raw_ostream &OS, const MachineBasicBlock *Src,
00118     const MachineBasicBlock *Dst) const {
00119 
00120   const BranchProbability Prob = getEdgeProbability(Src, Dst);
00121   OS << "edge MBB#" << Src->getNumber() << " -> MBB#" << Dst->getNumber()
00122      << " probability is " << Prob
00123      << (isEdgeHot(Src, Dst) ? " [HOT edge]\n" : "\n");
00124 
00125   return OS;
00126 }