LLVM API Documentation

MachineBlockFrequencyInfo.cpp
Go to the documentation of this file.
00001 //===- MachineBlockFrequencyInfo.cpp - MBB Frequency Analysis -------------===//
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 // Loops should be simplified before this analysis.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
00015 #include "llvm/Analysis/BlockFrequencyInfoImpl.h"
00016 #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
00017 #include "llvm/CodeGen/MachineFunction.h"
00018 #include "llvm/CodeGen/MachineLoopInfo.h"
00019 #include "llvm/CodeGen/Passes.h"
00020 #include "llvm/InitializePasses.h"
00021 #include "llvm/Support/CommandLine.h"
00022 #include "llvm/Support/Debug.h"
00023 #include "llvm/Support/GraphWriter.h"
00024 
00025 using namespace llvm;
00026 
00027 #define DEBUG_TYPE "block-freq"
00028 
00029 #ifndef NDEBUG
00030 enum GVDAGType {
00031   GVDT_None,
00032   GVDT_Fraction,
00033   GVDT_Integer
00034 };
00035 
00036 static cl::opt<GVDAGType>
00037 ViewMachineBlockFreqPropagationDAG("view-machine-block-freq-propagation-dags",
00038                                    cl::Hidden,
00039           cl::desc("Pop up a window to show a dag displaying how machine block "
00040                    "frequencies propagate through the CFG."),
00041           cl::values(
00042             clEnumValN(GVDT_None, "none",
00043                        "do not display graphs."),
00044             clEnumValN(GVDT_Fraction, "fraction", "display a graph using the "
00045                        "fractional block frequency representation."),
00046             clEnumValN(GVDT_Integer, "integer", "display a graph using the raw "
00047                        "integer fractional block frequency representation."),
00048             clEnumValEnd));
00049 
00050 namespace llvm {
00051 
00052 template <>
00053 struct GraphTraits<MachineBlockFrequencyInfo *> {
00054   typedef const MachineBasicBlock NodeType;
00055   typedef MachineBasicBlock::const_succ_iterator ChildIteratorType;
00056   typedef MachineFunction::const_iterator nodes_iterator;
00057 
00058   static inline
00059   const NodeType *getEntryNode(const MachineBlockFrequencyInfo *G) {
00060     return G->getFunction()->begin();
00061   }
00062 
00063   static ChildIteratorType child_begin(const NodeType *N) {
00064     return N->succ_begin();
00065   }
00066 
00067   static ChildIteratorType child_end(const NodeType *N) {
00068     return N->succ_end();
00069   }
00070 
00071   static nodes_iterator nodes_begin(const MachineBlockFrequencyInfo *G) {
00072     return G->getFunction()->begin();
00073   }
00074 
00075   static nodes_iterator nodes_end(const MachineBlockFrequencyInfo *G) {
00076     return G->getFunction()->end();
00077   }
00078 };
00079 
00080 template<>
00081 struct DOTGraphTraits<MachineBlockFrequencyInfo*> :
00082     public DefaultDOTGraphTraits {
00083   explicit DOTGraphTraits(bool isSimple=false) :
00084     DefaultDOTGraphTraits(isSimple) {}
00085 
00086   static std::string getGraphName(const MachineBlockFrequencyInfo *G) {
00087     return G->getFunction()->getName();
00088   }
00089 
00090   std::string getNodeLabel(const MachineBasicBlock *Node,
00091                            const MachineBlockFrequencyInfo *Graph) {
00092     std::string Result;
00093     raw_string_ostream OS(Result);
00094 
00095     OS << Node->getName().str() << ":";
00096     switch (ViewMachineBlockFreqPropagationDAG) {
00097     case GVDT_Fraction:
00098       Graph->printBlockFreq(OS, Node);
00099       break;
00100     case GVDT_Integer:
00101       OS << Graph->getBlockFreq(Node).getFrequency();
00102       break;
00103     case GVDT_None:
00104       llvm_unreachable("If we are not supposed to render a graph we should "
00105                        "never reach this point.");
00106     }
00107 
00108     return Result;
00109   }
00110 };
00111 
00112 
00113 } // end namespace llvm
00114 #endif
00115 
00116 INITIALIZE_PASS_BEGIN(MachineBlockFrequencyInfo, "machine-block-freq",
00117                       "Machine Block Frequency Analysis", true, true)
00118 INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
00119 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
00120 INITIALIZE_PASS_END(MachineBlockFrequencyInfo, "machine-block-freq",
00121                     "Machine Block Frequency Analysis", true, true)
00122 
00123 char MachineBlockFrequencyInfo::ID = 0;
00124 
00125 
00126 MachineBlockFrequencyInfo::
00127 MachineBlockFrequencyInfo() :MachineFunctionPass(ID) {
00128   initializeMachineBlockFrequencyInfoPass(*PassRegistry::getPassRegistry());
00129 }
00130 
00131 MachineBlockFrequencyInfo::~MachineBlockFrequencyInfo() {}
00132 
00133 void MachineBlockFrequencyInfo::getAnalysisUsage(AnalysisUsage &AU) const {
00134   AU.addRequired<MachineBranchProbabilityInfo>();
00135   AU.addRequired<MachineLoopInfo>();
00136   AU.setPreservesAll();
00137   MachineFunctionPass::getAnalysisUsage(AU);
00138 }
00139 
00140 bool MachineBlockFrequencyInfo::runOnMachineFunction(MachineFunction &F) {
00141   MachineBranchProbabilityInfo &MBPI =
00142       getAnalysis<MachineBranchProbabilityInfo>();
00143   MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>();
00144   if (!MBFI)
00145     MBFI.reset(new ImplType);
00146   MBFI->doFunction(&F, &MBPI, &MLI);
00147 #ifndef NDEBUG
00148   if (ViewMachineBlockFreqPropagationDAG != GVDT_None) {
00149     view();
00150   }
00151 #endif
00152   return false;
00153 }
00154 
00155 void MachineBlockFrequencyInfo::releaseMemory() { MBFI.reset(); }
00156 
00157 /// Pop up a ghostview window with the current block frequency propagation
00158 /// rendered using dot.
00159 void MachineBlockFrequencyInfo::view() const {
00160 // This code is only for debugging.
00161 #ifndef NDEBUG
00162   ViewGraph(const_cast<MachineBlockFrequencyInfo *>(this),
00163             "MachineBlockFrequencyDAGs");
00164 #else
00165   errs() << "MachineBlockFrequencyInfo::view is only available in debug builds "
00166     "on systems with Graphviz or gv!\n";
00167 #endif // NDEBUG
00168 }
00169 
00170 BlockFrequency MachineBlockFrequencyInfo::
00171 getBlockFreq(const MachineBasicBlock *MBB) const {
00172   return MBFI ? MBFI->getBlockFreq(MBB) : 0;
00173 }
00174 
00175 const MachineFunction *MachineBlockFrequencyInfo::getFunction() const {
00176   return MBFI ? MBFI->getFunction() : nullptr;
00177 }
00178 
00179 raw_ostream &
00180 MachineBlockFrequencyInfo::printBlockFreq(raw_ostream &OS,
00181                                           const BlockFrequency Freq) const {
00182   return MBFI ? MBFI->printBlockFreq(OS, Freq) : OS;
00183 }
00184 
00185 raw_ostream &
00186 MachineBlockFrequencyInfo::printBlockFreq(raw_ostream &OS,
00187                                           const MachineBasicBlock *MBB) const {
00188   return MBFI ? MBFI->printBlockFreq(OS, MBB) : OS;
00189 }
00190 
00191 uint64_t MachineBlockFrequencyInfo::getEntryFreq() const {
00192   return MBFI ? MBFI->getEntryFreq() : 0;
00193 }