Home | History | Annotate | Download | only in CodeGen
      1 //===- MachineBlockFrequencyInfo.cpp - MBB Frequency Analysis -------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // Loops should be simplified before this analysis.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
     15 #include "llvm/Analysis/BlockFrequencyInfoImpl.h"
     16 #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
     17 #include "llvm/CodeGen/MachineFunction.h"
     18 #include "llvm/CodeGen/MachineLoopInfo.h"
     19 #include "llvm/CodeGen/Passes.h"
     20 #include "llvm/InitializePasses.h"
     21 #include "llvm/Support/CommandLine.h"
     22 #include "llvm/Support/Debug.h"
     23 #include "llvm/Support/Format.h"
     24 #include "llvm/Support/GraphWriter.h"
     25 #include "llvm/Support/raw_ostream.h"
     26 
     27 using namespace llvm;
     28 
     29 #define DEBUG_TYPE "block-freq"
     30 
     31 #ifndef NDEBUG
     32 
     33 static cl::opt<GVDAGType> ViewMachineBlockFreqPropagationDAG(
     34     "view-machine-block-freq-propagation-dags", cl::Hidden,
     35     cl::desc("Pop up a window to show a dag displaying how machine block "
     36              "frequencies propagate through the CFG."),
     37     cl::values(clEnumValN(GVDT_None, "none", "do not display graphs."),
     38                clEnumValN(GVDT_Fraction, "fraction",
     39                           "display a graph using the "
     40                           "fractional block frequency representation."),
     41                clEnumValN(GVDT_Integer, "integer",
     42                           "display a graph using the raw "
     43                           "integer fractional block frequency representation."),
     44                clEnumValN(GVDT_Count, "count", "display a graph using the real "
     45                                                "profile count if available."),
     46 
     47                clEnumValEnd));
     48 
     49 extern cl::opt<std::string> ViewBlockFreqFuncName;
     50 extern cl::opt<unsigned> ViewHotFreqPercent;
     51 
     52 namespace llvm {
     53 
     54 template <> struct GraphTraits<MachineBlockFrequencyInfo *> {
     55   typedef const MachineBasicBlock NodeType;
     56   typedef MachineBasicBlock::const_succ_iterator ChildIteratorType;
     57   typedef MachineFunction::const_iterator nodes_iterator;
     58 
     59   static inline const NodeType *
     60   getEntryNode(const MachineBlockFrequencyInfo *G) {
     61     return &G->getFunction()->front();
     62   }
     63 
     64   static ChildIteratorType child_begin(const NodeType *N) {
     65     return N->succ_begin();
     66   }
     67 
     68   static ChildIteratorType child_end(const NodeType *N) {
     69     return N->succ_end();
     70   }
     71 
     72   static nodes_iterator nodes_begin(const MachineBlockFrequencyInfo *G) {
     73     return G->getFunction()->begin();
     74   }
     75 
     76   static nodes_iterator nodes_end(const MachineBlockFrequencyInfo *G) {
     77     return G->getFunction()->end();
     78   }
     79 };
     80 
     81 typedef BFIDOTGraphTraitsBase<MachineBlockFrequencyInfo,
     82                               MachineBranchProbabilityInfo>
     83     MBFIDOTGraphTraitsBase;
     84 template <>
     85 struct DOTGraphTraits<MachineBlockFrequencyInfo *>
     86     : public MBFIDOTGraphTraitsBase {
     87   explicit DOTGraphTraits(bool isSimple = false)
     88       : MBFIDOTGraphTraitsBase(isSimple) {}
     89 
     90   std::string getNodeLabel(const MachineBasicBlock *Node,
     91                            const MachineBlockFrequencyInfo *Graph) {
     92     return MBFIDOTGraphTraitsBase::getNodeLabel(
     93         Node, Graph, ViewMachineBlockFreqPropagationDAG);
     94   }
     95 
     96   std::string getNodeAttributes(const MachineBasicBlock *Node,
     97                                 const MachineBlockFrequencyInfo *Graph) {
     98     return MBFIDOTGraphTraitsBase::getNodeAttributes(Node, Graph,
     99                                                      ViewHotFreqPercent);
    100   }
    101 
    102   std::string getEdgeAttributes(const MachineBasicBlock *Node, EdgeIter EI,
    103                                 const MachineBlockFrequencyInfo *MBFI) {
    104     return MBFIDOTGraphTraitsBase::getEdgeAttributes(
    105         Node, EI, MBFI, MBFI->getMBPI(), ViewHotFreqPercent);
    106   }
    107 };
    108 
    109 } // end namespace llvm
    110 #endif
    111 
    112 INITIALIZE_PASS_BEGIN(MachineBlockFrequencyInfo, "machine-block-freq",
    113                       "Machine Block Frequency Analysis", true, true)
    114 INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
    115 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
    116 INITIALIZE_PASS_END(MachineBlockFrequencyInfo, "machine-block-freq",
    117                     "Machine Block Frequency Analysis", true, true)
    118 
    119 char MachineBlockFrequencyInfo::ID = 0;
    120 
    121 MachineBlockFrequencyInfo::MachineBlockFrequencyInfo()
    122     : MachineFunctionPass(ID) {
    123   initializeMachineBlockFrequencyInfoPass(*PassRegistry::getPassRegistry());
    124 }
    125 
    126 MachineBlockFrequencyInfo::~MachineBlockFrequencyInfo() {}
    127 
    128 void MachineBlockFrequencyInfo::getAnalysisUsage(AnalysisUsage &AU) const {
    129   AU.addRequired<MachineBranchProbabilityInfo>();
    130   AU.addRequired<MachineLoopInfo>();
    131   AU.setPreservesAll();
    132   MachineFunctionPass::getAnalysisUsage(AU);
    133 }
    134 
    135 bool MachineBlockFrequencyInfo::runOnMachineFunction(MachineFunction &F) {
    136   MachineBranchProbabilityInfo &MBPI =
    137       getAnalysis<MachineBranchProbabilityInfo>();
    138   MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>();
    139   if (!MBFI)
    140     MBFI.reset(new ImplType);
    141   MBFI->calculate(F, MBPI, MLI);
    142 #ifndef NDEBUG
    143   if (ViewMachineBlockFreqPropagationDAG != GVDT_None &&
    144       (ViewBlockFreqFuncName.empty() ||
    145        F.getName().equals(ViewBlockFreqFuncName))) {
    146     view();
    147   }
    148 #endif
    149   return false;
    150 }
    151 
    152 void MachineBlockFrequencyInfo::releaseMemory() { MBFI.reset(); }
    153 
    154 /// Pop up a ghostview window with the current block frequency propagation
    155 /// rendered using dot.
    156 void MachineBlockFrequencyInfo::view() const {
    157 // This code is only for debugging.
    158 #ifndef NDEBUG
    159   ViewGraph(const_cast<MachineBlockFrequencyInfo *>(this),
    160             "MachineBlockFrequencyDAGs");
    161 #else
    162   errs() << "MachineBlockFrequencyInfo::view is only available in debug builds "
    163             "on systems with Graphviz or gv!\n";
    164 #endif // NDEBUG
    165 }
    166 
    167 BlockFrequency
    168 MachineBlockFrequencyInfo::getBlockFreq(const MachineBasicBlock *MBB) const {
    169   return MBFI ? MBFI->getBlockFreq(MBB) : 0;
    170 }
    171 
    172 Optional<uint64_t> MachineBlockFrequencyInfo::getBlockProfileCount(
    173     const MachineBasicBlock *MBB) const {
    174   const Function *F = MBFI->getFunction()->getFunction();
    175   return MBFI ? MBFI->getBlockProfileCount(*F, MBB) : None;
    176 }
    177 
    178 const MachineFunction *MachineBlockFrequencyInfo::getFunction() const {
    179   return MBFI ? MBFI->getFunction() : nullptr;
    180 }
    181 
    182 const MachineBranchProbabilityInfo *MachineBlockFrequencyInfo::getMBPI() const {
    183   return MBFI ? &MBFI->getBPI() : nullptr;
    184 }
    185 
    186 raw_ostream &
    187 MachineBlockFrequencyInfo::printBlockFreq(raw_ostream &OS,
    188                                           const BlockFrequency Freq) const {
    189   return MBFI ? MBFI->printBlockFreq(OS, Freq) : OS;
    190 }
    191 
    192 raw_ostream &
    193 MachineBlockFrequencyInfo::printBlockFreq(raw_ostream &OS,
    194                                           const MachineBasicBlock *MBB) const {
    195   return MBFI ? MBFI->printBlockFreq(OS, MBB) : OS;
    196 }
    197 
    198 uint64_t MachineBlockFrequencyInfo::getEntryFreq() const {
    199   return MBFI ? MBFI->getEntryFreq() : 0;
    200 }
    201