MachineBlockFrequencyInfo.cpp 10 KB

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