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