LLVM API Documentation
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 }