MachineBlockFrequencyInfo.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. //===- MachineBlockFrequencyInfo.cpp - MBB Frequency Analysis -------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Loops should be simplified before this analysis.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
  13. #include "llvm/ADT/DenseMap.h"
  14. #include "llvm/ADT/None.h"
  15. #include "llvm/ADT/iterator.h"
  16. #include "llvm/Analysis/BlockFrequencyInfoImpl.h"
  17. #include "llvm/CodeGen/MachineBasicBlock.h"
  18. #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
  19. #include "llvm/CodeGen/MachineFunction.h"
  20. #include "llvm/CodeGen/MachineLoopInfo.h"
  21. #include "llvm/Pass.h"
  22. #include "llvm/Support/CommandLine.h"
  23. #include "llvm/Support/GraphWriter.h"
  24. #include <string>
  25. using namespace llvm;
  26. #define DEBUG_TYPE "machine-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 cl::opt<bool> PrintMachineBlockFreq(
  63. "print-machine-bfi", cl::init(false), cl::Hidden,
  64. cl::desc("Print the machine block frequency info."));
  65. // Command line option to specify the name of the function for block frequency
  66. // dump. Defined in Analysis/BlockFrequencyInfo.cpp.
  67. extern cl::opt<std::string> PrintBlockFreqFuncName;
  68. static GVDAGType getGVDT() {
  69. if (ViewBlockLayoutWithBFI != GVDT_None)
  70. return ViewBlockLayoutWithBFI;
  71. return ViewMachineBlockFreqPropagationDAG;
  72. }
  73. namespace llvm {
  74. template <> struct GraphTraits<MachineBlockFrequencyInfo *> {
  75. using NodeRef = const MachineBasicBlock *;
  76. using ChildIteratorType = MachineBasicBlock::const_succ_iterator;
  77. using nodes_iterator = pointer_iterator<MachineFunction::const_iterator>;
  78. static NodeRef getEntryNode(const MachineBlockFrequencyInfo *G) {
  79. return &G->getFunction()->front();
  80. }
  81. static ChildIteratorType child_begin(const NodeRef N) {
  82. return N->succ_begin();
  83. }
  84. static ChildIteratorType child_end(const NodeRef N) { return N->succ_end(); }
  85. static nodes_iterator nodes_begin(const MachineBlockFrequencyInfo *G) {
  86. return nodes_iterator(G->getFunction()->begin());
  87. }
  88. static nodes_iterator nodes_end(const MachineBlockFrequencyInfo *G) {
  89. return nodes_iterator(G->getFunction()->end());
  90. }
  91. };
  92. using MBFIDOTGraphTraitsBase =
  93. BFIDOTGraphTraitsBase<MachineBlockFrequencyInfo,
  94. MachineBranchProbabilityInfo>;
  95. template <>
  96. struct DOTGraphTraits<MachineBlockFrequencyInfo *>
  97. : public MBFIDOTGraphTraitsBase {
  98. const MachineFunction *CurFunc = nullptr;
  99. DenseMap<const MachineBasicBlock *, int> LayoutOrderMap;
  100. explicit DOTGraphTraits(bool isSimple = false)
  101. : MBFIDOTGraphTraitsBase(isSimple) {}
  102. std::string getNodeLabel(const MachineBasicBlock *Node,
  103. const MachineBlockFrequencyInfo *Graph) {
  104. int layout_order = -1;
  105. // Attach additional ordering information if 'isSimple' is false.
  106. if (!isSimple()) {
  107. const MachineFunction *F = Node->getParent();
  108. if (!CurFunc || F != CurFunc) {
  109. if (CurFunc)
  110. LayoutOrderMap.clear();
  111. CurFunc = F;
  112. int O = 0;
  113. for (auto MBI = F->begin(); MBI != F->end(); ++MBI, ++O) {
  114. LayoutOrderMap[&*MBI] = O;
  115. }
  116. }
  117. layout_order = LayoutOrderMap[Node];
  118. }
  119. return MBFIDOTGraphTraitsBase::getNodeLabel(Node, Graph, getGVDT(),
  120. layout_order);
  121. }
  122. std::string getNodeAttributes(const MachineBasicBlock *Node,
  123. const MachineBlockFrequencyInfo *Graph) {
  124. return MBFIDOTGraphTraitsBase::getNodeAttributes(Node, Graph,
  125. ViewHotFreqPercent);
  126. }
  127. std::string getEdgeAttributes(const MachineBasicBlock *Node, EdgeIter EI,
  128. const MachineBlockFrequencyInfo *MBFI) {
  129. return MBFIDOTGraphTraitsBase::getEdgeAttributes(
  130. Node, EI, MBFI, MBFI->getMBPI(), ViewHotFreqPercent);
  131. }
  132. };
  133. } // end namespace llvm
  134. INITIALIZE_PASS_BEGIN(MachineBlockFrequencyInfo, DEBUG_TYPE,
  135. "Machine Block Frequency Analysis", true, true)
  136. INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
  137. INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
  138. INITIALIZE_PASS_END(MachineBlockFrequencyInfo, DEBUG_TYPE,
  139. "Machine Block Frequency Analysis", true, true)
  140. char MachineBlockFrequencyInfo::ID = 0;
  141. MachineBlockFrequencyInfo::MachineBlockFrequencyInfo()
  142. : MachineFunctionPass(ID) {
  143. initializeMachineBlockFrequencyInfoPass(*PassRegistry::getPassRegistry());
  144. }
  145. MachineBlockFrequencyInfo::~MachineBlockFrequencyInfo() = default;
  146. void MachineBlockFrequencyInfo::getAnalysisUsage(AnalysisUsage &AU) const {
  147. AU.addRequired<MachineBranchProbabilityInfo>();
  148. AU.addRequired<MachineLoopInfo>();
  149. AU.setPreservesAll();
  150. MachineFunctionPass::getAnalysisUsage(AU);
  151. }
  152. void MachineBlockFrequencyInfo::calculate(
  153. const MachineFunction &F, const MachineBranchProbabilityInfo &MBPI,
  154. const MachineLoopInfo &MLI) {
  155. if (!MBFI)
  156. MBFI.reset(new ImplType);
  157. MBFI->calculate(F, MBPI, MLI);
  158. if (ViewMachineBlockFreqPropagationDAG != GVDT_None &&
  159. (ViewBlockFreqFuncName.empty() ||
  160. F.getName().equals(ViewBlockFreqFuncName))) {
  161. view("MachineBlockFrequencyDAGS." + F.getName());
  162. }
  163. if (PrintMachineBlockFreq &&
  164. (PrintBlockFreqFuncName.empty() ||
  165. F.getName().equals(PrintBlockFreqFuncName))) {
  166. MBFI->print(dbgs());
  167. }
  168. }
  169. bool MachineBlockFrequencyInfo::runOnMachineFunction(MachineFunction &F) {
  170. MachineBranchProbabilityInfo &MBPI =
  171. getAnalysis<MachineBranchProbabilityInfo>();
  172. MachineLoopInfo &MLI = getAnalysis<MachineLoopInfo>();
  173. calculate(F, MBPI, MLI);
  174. return false;
  175. }
  176. void MachineBlockFrequencyInfo::releaseMemory() { MBFI.reset(); }
  177. /// Pop up a ghostview window with the current block frequency propagation
  178. /// rendered using dot.
  179. void MachineBlockFrequencyInfo::view(const Twine &Name, bool isSimple) const {
  180. // This code is only for debugging.
  181. ViewGraph(const_cast<MachineBlockFrequencyInfo *>(this), Name, isSimple);
  182. }
  183. BlockFrequency
  184. MachineBlockFrequencyInfo::getBlockFreq(const MachineBasicBlock *MBB) const {
  185. return MBFI ? MBFI->getBlockFreq(MBB) : 0;
  186. }
  187. Optional<uint64_t> MachineBlockFrequencyInfo::getBlockProfileCount(
  188. const MachineBasicBlock *MBB) const {
  189. const Function &F = MBFI->getFunction()->getFunction();
  190. return MBFI ? MBFI->getBlockProfileCount(F, MBB) : None;
  191. }
  192. Optional<uint64_t>
  193. MachineBlockFrequencyInfo::getProfileCountFromFreq(uint64_t Freq) const {
  194. const Function &F = MBFI->getFunction()->getFunction();
  195. return MBFI ? MBFI->getProfileCountFromFreq(F, Freq) : None;
  196. }
  197. bool
  198. MachineBlockFrequencyInfo::isIrrLoopHeader(const MachineBasicBlock *MBB) {
  199. assert(MBFI && "Expected analysis to be available");
  200. return MBFI->isIrrLoopHeader(MBB);
  201. }
  202. const MachineFunction *MachineBlockFrequencyInfo::getFunction() const {
  203. return MBFI ? MBFI->getFunction() : nullptr;
  204. }
  205. const MachineBranchProbabilityInfo *MachineBlockFrequencyInfo::getMBPI() const {
  206. return MBFI ? &MBFI->getBPI() : nullptr;
  207. }
  208. raw_ostream &
  209. MachineBlockFrequencyInfo::printBlockFreq(raw_ostream &OS,
  210. const BlockFrequency Freq) const {
  211. return MBFI ? MBFI->printBlockFreq(OS, Freq) : OS;
  212. }
  213. raw_ostream &
  214. MachineBlockFrequencyInfo::printBlockFreq(raw_ostream &OS,
  215. const MachineBasicBlock *MBB) const {
  216. return MBFI ? MBFI->printBlockFreq(OS, MBB) : OS;
  217. }
  218. uint64_t MachineBlockFrequencyInfo::getEntryFreq() const {
  219. return MBFI ? MBFI->getEntryFreq() : 0;
  220. }