Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

342 lines
9.8 KiB

  1. //===---- BlockFrequencyImpl.h - Machine Block Frequency Implementation ---===//
  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. // Shared implementation of BlockFrequency for IR and Machine Instructions.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H
  14. #define LLVM_ANALYSIS_BLOCKFREQUENCYIMPL_H
  15. #include "llvm/ADT/DenseMap.h"
  16. #include "llvm/ADT/PostOrderIterator.h"
  17. #include "llvm/CodeGen/MachineBasicBlock.h"
  18. #include "llvm/CodeGen/MachineFunction.h"
  19. #include "llvm/IR/BasicBlock.h"
  20. #include "llvm/Support/BlockFrequency.h"
  21. #include "llvm/Support/BranchProbability.h"
  22. #include "llvm/Support/Debug.h"
  23. #include "llvm/Support/raw_ostream.h"
  24. #include <string>
  25. #include <vector>
  26. namespace llvm {
  27. class BlockFrequencyInfo;
  28. class MachineBlockFrequencyInfo;
  29. /// BlockFrequencyImpl implements block frequency algorithm for IR and
  30. /// Machine Instructions. Algorithm starts with value 1024 (START_FREQ)
  31. /// for the entry block and then propagates frequencies using branch weights
  32. /// from (Machine)BranchProbabilityInfo. LoopInfo is not required because
  33. /// algorithm can find "backedges" by itself.
  34. template<class BlockT, class FunctionT, class BlockProbInfoT>
  35. class BlockFrequencyImpl {
  36. DenseMap<const BlockT *, BlockFrequency> Freqs;
  37. BlockProbInfoT *BPI;
  38. FunctionT *Fn;
  39. typedef GraphTraits< Inverse<BlockT *> > GT;
  40. const uint32_t EntryFreq;
  41. std::string getBlockName(BasicBlock *BB) const {
  42. return BB->getName().str();
  43. }
  44. std::string getBlockName(MachineBasicBlock *MBB) const {
  45. std::string str;
  46. raw_string_ostream ss(str);
  47. ss << "BB#" << MBB->getNumber();
  48. if (const BasicBlock *BB = MBB->getBasicBlock())
  49. ss << " derived from LLVM BB " << BB->getName();
  50. return ss.str();
  51. }
  52. void setBlockFreq(BlockT *BB, BlockFrequency Freq) {
  53. Freqs[BB] = Freq;
  54. DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") = " << Freq << "\n");
  55. }
  56. /// getEdgeFreq - Return edge frequency based on SRC frequency and Src -> Dst
  57. /// edge probability.
  58. BlockFrequency getEdgeFreq(BlockT *Src, BlockT *Dst) const {
  59. BranchProbability Prob = BPI->getEdgeProbability(Src, Dst);
  60. return getBlockFreq(Src) * Prob;
  61. }
  62. /// incBlockFreq - Increase BB block frequency by FREQ.
  63. ///
  64. void incBlockFreq(BlockT *BB, BlockFrequency Freq) {
  65. Freqs[BB] += Freq;
  66. DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") += " << Freq
  67. << " --> " << Freqs[BB] << "\n");
  68. }
  69. /// divBlockFreq - Divide BB block frequency by PROB. If Prob = 0 do nothing.
  70. ///
  71. void divBlockFreq(BlockT *BB, BranchProbability Prob) {
  72. uint64_t N = Prob.getNumerator();
  73. assert(N && "Illegal division by zero!");
  74. uint64_t D = Prob.getDenominator();
  75. uint64_t Freq = (Freqs[BB].getFrequency() * D) / N;
  76. // Should we assert it?
  77. if (Freq > UINT32_MAX)
  78. Freq = UINT32_MAX;
  79. Freqs[BB] = BlockFrequency(Freq);
  80. DEBUG(dbgs() << "Frequency(" << getBlockName(BB) << ") /= (" << Prob
  81. << ") --> " << Freqs[BB] << "\n");
  82. }
  83. // All blocks in postorder.
  84. std::vector<BlockT *> POT;
  85. // Map Block -> Position in reverse-postorder list.
  86. DenseMap<BlockT *, unsigned> RPO;
  87. // Cycle Probability for each bloch.
  88. DenseMap<BlockT *, uint32_t> CycleProb;
  89. // (reverse-)postorder traversal iterators.
  90. typedef typename std::vector<BlockT *>::iterator pot_iterator;
  91. typedef typename std::vector<BlockT *>::reverse_iterator rpot_iterator;
  92. pot_iterator pot_begin() { return POT.begin(); }
  93. pot_iterator pot_end() { return POT.end(); }
  94. rpot_iterator rpot_begin() { return POT.rbegin(); }
  95. rpot_iterator rpot_end() { return POT.rend(); }
  96. rpot_iterator rpot_at(BlockT *BB) {
  97. rpot_iterator I = rpot_begin();
  98. unsigned idx = RPO[BB];
  99. assert(idx);
  100. std::advance(I, idx - 1);
  101. assert(*I == BB);
  102. return I;
  103. }
  104. /// isReachable - Returns if BB block is reachable from the entry.
  105. ///
  106. bool isReachable(BlockT *BB) {
  107. return RPO.count(BB);
  108. }
  109. /// isBackedge - Return if edge Src -> Dst is a backedge.
  110. ///
  111. bool isBackedge(BlockT *Src, BlockT *Dst) {
  112. assert(isReachable(Src));
  113. assert(isReachable(Dst));
  114. unsigned a = RPO[Src];
  115. unsigned b = RPO[Dst];
  116. return a >= b;
  117. }
  118. /// getSingleBlockPred - return single BB block predecessor or NULL if
  119. /// BB has none or more predecessors.
  120. BlockT *getSingleBlockPred(BlockT *BB) {
  121. typename GT::ChildIteratorType
  122. PI = GraphTraits< Inverse<BlockT *> >::child_begin(BB),
  123. PE = GraphTraits< Inverse<BlockT *> >::child_end(BB);
  124. if (PI == PE)
  125. return 0;
  126. BlockT *Pred = *PI;
  127. ++PI;
  128. if (PI != PE)
  129. return 0;
  130. return Pred;
  131. }
  132. void doBlock(BlockT *BB, BlockT *LoopHead,
  133. SmallPtrSet<BlockT *, 8> &BlocksInLoop) {
  134. DEBUG(dbgs() << "doBlock(" << getBlockName(BB) << ")\n");
  135. setBlockFreq(BB, 0);
  136. if (BB == LoopHead) {
  137. setBlockFreq(BB, EntryFreq);
  138. return;
  139. }
  140. if(BlockT *Pred = getSingleBlockPred(BB)) {
  141. if (BlocksInLoop.count(Pred))
  142. setBlockFreq(BB, getEdgeFreq(Pred, BB));
  143. // TODO: else? irreducible, ignore it for now.
  144. return;
  145. }
  146. bool isInLoop = false;
  147. bool isLoopHead = false;
  148. for (typename GT::ChildIteratorType
  149. PI = GraphTraits< Inverse<BlockT *> >::child_begin(BB),
  150. PE = GraphTraits< Inverse<BlockT *> >::child_end(BB);
  151. PI != PE; ++PI) {
  152. BlockT *Pred = *PI;
  153. if (isReachable(Pred) && isBackedge(Pred, BB)) {
  154. isLoopHead = true;
  155. } else if (BlocksInLoop.count(Pred)) {
  156. incBlockFreq(BB, getEdgeFreq(Pred, BB));
  157. isInLoop = true;
  158. }
  159. // TODO: else? irreducible.
  160. }
  161. if (!isInLoop)
  162. return;
  163. if (!isLoopHead)
  164. return;
  165. assert(EntryFreq >= CycleProb[BB]);
  166. uint32_t CProb = CycleProb[BB];
  167. uint32_t Numerator = EntryFreq - CProb ? EntryFreq - CProb : 1;
  168. divBlockFreq(BB, BranchProbability(Numerator, EntryFreq));
  169. }
  170. /// doLoop - Propagate block frequency down through the loop.
  171. void doLoop(BlockT *Head, BlockT *Tail) {
  172. DEBUG(dbgs() << "doLoop(" << getBlockName(Head) << ", "
  173. << getBlockName(Tail) << ")\n");
  174. SmallPtrSet<BlockT *, 8> BlocksInLoop;
  175. for (rpot_iterator I = rpot_at(Head), E = rpot_at(Tail); ; ++I) {
  176. BlockT *BB = *I;
  177. doBlock(BB, Head, BlocksInLoop);
  178. BlocksInLoop.insert(BB);
  179. if (I == E)
  180. break;
  181. }
  182. // Compute loop's cyclic probability using backedges probabilities.
  183. for (typename GT::ChildIteratorType
  184. PI = GraphTraits< Inverse<BlockT *> >::child_begin(Head),
  185. PE = GraphTraits< Inverse<BlockT *> >::child_end(Head);
  186. PI != PE; ++PI) {
  187. BlockT *Pred = *PI;
  188. assert(Pred);
  189. if (isReachable(Pred) && isBackedge(Pred, Head)) {
  190. uint64_t N = getEdgeFreq(Pred, Head).getFrequency();
  191. uint64_t D = getBlockFreq(Head).getFrequency();
  192. assert(N <= EntryFreq && "Backedge frequency must be <= EntryFreq!");
  193. uint64_t Res = (N * EntryFreq) / D;
  194. assert(Res <= UINT32_MAX);
  195. CycleProb[Head] += (uint32_t) Res;
  196. DEBUG(dbgs() << " CycleProb[" << getBlockName(Head) << "] += " << Res
  197. << " --> " << CycleProb[Head] << "\n");
  198. }
  199. }
  200. }
  201. friend class BlockFrequencyInfo;
  202. friend class MachineBlockFrequencyInfo;
  203. BlockFrequencyImpl() : EntryFreq(BlockFrequency::getEntryFrequency()) { }
  204. void doFunction(FunctionT *fn, BlockProbInfoT *bpi) {
  205. Fn = fn;
  206. BPI = bpi;
  207. // Clear everything.
  208. RPO.clear();
  209. POT.clear();
  210. CycleProb.clear();
  211. Freqs.clear();
  212. BlockT *EntryBlock = fn->begin();
  213. std::copy(po_begin(EntryBlock), po_end(EntryBlock), std::back_inserter(POT));
  214. unsigned RPOidx = 0;
  215. for (rpot_iterator I = rpot_begin(), E = rpot_end(); I != E; ++I) {
  216. BlockT *BB = *I;
  217. RPO[BB] = ++RPOidx;
  218. DEBUG(dbgs() << "RPO[" << getBlockName(BB) << "] = " << RPO[BB] << "\n");
  219. }
  220. // Travel over all blocks in postorder.
  221. for (pot_iterator I = pot_begin(), E = pot_end(); I != E; ++I) {
  222. BlockT *BB = *I;
  223. BlockT *LastTail = 0;
  224. DEBUG(dbgs() << "POT: " << getBlockName(BB) << "\n");
  225. for (typename GT::ChildIteratorType
  226. PI = GraphTraits< Inverse<BlockT *> >::child_begin(BB),
  227. PE = GraphTraits< Inverse<BlockT *> >::child_end(BB);
  228. PI != PE; ++PI) {
  229. BlockT *Pred = *PI;
  230. if (isReachable(Pred) && isBackedge(Pred, BB)
  231. && (!LastTail || RPO[Pred] > RPO[LastTail]))
  232. LastTail = Pred;
  233. }
  234. if (LastTail)
  235. doLoop(BB, LastTail);
  236. }
  237. // At the end assume the whole function as a loop, and travel over it once
  238. // again.
  239. doLoop(*(rpot_begin()), *(pot_begin()));
  240. }
  241. public:
  242. /// getBlockFreq - Return block frequency. Return 0 if we don't have it.
  243. BlockFrequency getBlockFreq(const BlockT *BB) const {
  244. typename DenseMap<const BlockT *, BlockFrequency>::const_iterator
  245. I = Freqs.find(BB);
  246. if (I != Freqs.end())
  247. return I->second;
  248. return 0;
  249. }
  250. void print(raw_ostream &OS) const {
  251. OS << "\n\n---- Block Freqs ----\n";
  252. for (typename FunctionT::iterator I = Fn->begin(), E = Fn->end(); I != E;) {
  253. BlockT *BB = I++;
  254. OS << " " << getBlockName(BB) << " = " << getBlockFreq(BB) << "\n";
  255. for (typename GraphTraits<BlockT *>::ChildIteratorType
  256. SI = GraphTraits<BlockT *>::child_begin(BB),
  257. SE = GraphTraits<BlockT *>::child_end(BB); SI != SE; ++SI) {
  258. BlockT *Succ = *SI;
  259. OS << " " << getBlockName(BB) << " -> " << getBlockName(Succ)
  260. << " = " << getEdgeFreq(BB, Succ) << "\n";
  261. }
  262. }
  263. }
  264. void dump() const {
  265. print(dbgs());
  266. }
  267. };
  268. }
  269. #endif