MachineBlockFrequencyInfo.cpp 8.8 KB

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