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.

247 lines
9.0 KiB

  1. //===- llvm/Analysis/ProfileInfo.h - Profile Info Interface -----*- C++ -*-===//
  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. // This file defines the generic ProfileInfo interface, which is used as the
  11. // common interface used by all clients of profiling information, and
  12. // implemented either by making static guestimations, or by actually reading in
  13. // profiling information gathered by running the program.
  14. //
  15. // Note that to be useful, all profile-based optimizations should preserve
  16. // ProfileInfo, which requires that they notify it when changes to the CFG are
  17. // made. (This is not implemented yet.)
  18. //
  19. //===----------------------------------------------------------------------===//
  20. #ifndef LLVM_ANALYSIS_PROFILEINFO_H
  21. #define LLVM_ANALYSIS_PROFILEINFO_H
  22. #include "llvm/Support/Debug.h"
  23. #include "llvm/Support/ErrorHandling.h"
  24. #include "llvm/Support/Format.h"
  25. #include "llvm/Support/raw_ostream.h"
  26. #include <cassert>
  27. #include <map>
  28. #include <set>
  29. #include <string>
  30. namespace llvm {
  31. class Pass;
  32. class raw_ostream;
  33. class BasicBlock;
  34. class Function;
  35. class MachineBasicBlock;
  36. class MachineFunction;
  37. // Helper for dumping edges to dbgs().
  38. raw_ostream& operator<<(raw_ostream &O, std::pair<const BasicBlock *, const BasicBlock *> E);
  39. raw_ostream& operator<<(raw_ostream &O, std::pair<const MachineBasicBlock *, const MachineBasicBlock *> E);
  40. raw_ostream& operator<<(raw_ostream &O, const BasicBlock *BB);
  41. raw_ostream& operator<<(raw_ostream &O, const MachineBasicBlock *MBB);
  42. raw_ostream& operator<<(raw_ostream &O, const Function *F);
  43. raw_ostream& operator<<(raw_ostream &O, const MachineFunction *MF);
  44. /// ProfileInfo Class - This class holds and maintains profiling
  45. /// information for some unit of code.
  46. template<class FType, class BType>
  47. class ProfileInfoT {
  48. public:
  49. // Types for handling profiling information.
  50. typedef std::pair<const BType*, const BType*> Edge;
  51. typedef std::pair<Edge, double> EdgeWeight;
  52. typedef std::map<Edge, double> EdgeWeights;
  53. typedef std::map<const BType*, double> BlockCounts;
  54. typedef std::map<const BType*, const BType*> Path;
  55. protected:
  56. // EdgeInformation - Count the number of times a transition between two
  57. // blocks is executed. As a special case, we also hold an edge from the
  58. // null BasicBlock to the entry block to indicate how many times the
  59. // function was entered.
  60. std::map<const FType*, EdgeWeights> EdgeInformation;
  61. // BlockInformation - Count the number of times a block is executed.
  62. std::map<const FType*, BlockCounts> BlockInformation;
  63. // FunctionInformation - Count the number of times a function is executed.
  64. std::map<const FType*, double> FunctionInformation;
  65. ProfileInfoT<MachineFunction, MachineBasicBlock> *MachineProfile;
  66. public:
  67. static char ID; // Class identification, replacement for typeinfo
  68. ProfileInfoT();
  69. ~ProfileInfoT(); // We want to be subclassed
  70. // MissingValue - The value that is returned for execution counts in case
  71. // no value is available.
  72. static const double MissingValue;
  73. // getFunction() - Returns the Function for an Edge, checking for validity.
  74. static const FType* getFunction(Edge e) {
  75. if (e.first)
  76. return e.first->getParent();
  77. if (e.second)
  78. return e.second->getParent();
  79. llvm_unreachable("Invalid ProfileInfo::Edge");
  80. }
  81. // getEdge() - Creates an Edge from two BasicBlocks.
  82. static Edge getEdge(const BType *Src, const BType *Dest) {
  83. return std::make_pair(Src, Dest);
  84. }
  85. //===------------------------------------------------------------------===//
  86. /// Profile Information Queries
  87. ///
  88. double getExecutionCount(const FType *F);
  89. double getExecutionCount(const BType *BB);
  90. void setExecutionCount(const BType *BB, double w);
  91. void addExecutionCount(const BType *BB, double w);
  92. double getEdgeWeight(Edge e) const {
  93. typename std::map<const FType*, EdgeWeights>::const_iterator J =
  94. EdgeInformation.find(getFunction(e));
  95. if (J == EdgeInformation.end()) return MissingValue;
  96. typename EdgeWeights::const_iterator I = J->second.find(e);
  97. if (I == J->second.end()) return MissingValue;
  98. return I->second;
  99. }
  100. void setEdgeWeight(Edge e, double w) {
  101. DEBUG_WITH_TYPE("profile-info",
  102. dbgs() << "Creating Edge " << e
  103. << " (weight: " << format("%.20g",w) << ")\n");
  104. EdgeInformation[getFunction(e)][e] = w;
  105. }
  106. void addEdgeWeight(Edge e, double w);
  107. EdgeWeights &getEdgeWeights (const FType *F) {
  108. return EdgeInformation[F];
  109. }
  110. //===------------------------------------------------------------------===//
  111. /// Analysis Update Methods
  112. ///
  113. void removeBlock(const BType *BB);
  114. void removeEdge(Edge e);
  115. void replaceEdge(const Edge &, const Edge &);
  116. enum GetPathMode {
  117. GetPathToExit = 1,
  118. GetPathToValue = 2,
  119. GetPathToDest = 4,
  120. GetPathWithNewEdges = 8
  121. };
  122. const BType *GetPath(const BType *Src, const BType *Dest,
  123. Path &P, unsigned Mode);
  124. void divertFlow(const Edge &, const Edge &);
  125. void splitEdge(const BType *FirstBB, const BType *SecondBB,
  126. const BType *NewBB, bool MergeIdenticalEdges = false);
  127. void splitBlock(const BType *Old, const BType* New);
  128. void splitBlock(const BType *BB, const BType* NewBB,
  129. BType *const *Preds, unsigned NumPreds);
  130. void replaceAllUses(const BType *RmBB, const BType *DestBB);
  131. void transfer(const FType *Old, const FType *New);
  132. void repair(const FType *F);
  133. void dump(FType *F = 0, bool real = true) {
  134. dbgs() << "**** This is ProfileInfo " << this << " speaking:\n";
  135. if (!real) {
  136. typename std::set<const FType*> Functions;
  137. dbgs() << "Functions: \n";
  138. if (F) {
  139. dbgs() << F << "@" << format("%p", F) << ": " << format("%.20g",getExecutionCount(F)) << "\n";
  140. Functions.insert(F);
  141. } else {
  142. for (typename std::map<const FType*, double>::iterator fi = FunctionInformation.begin(),
  143. fe = FunctionInformation.end(); fi != fe; ++fi) {
  144. dbgs() << fi->first << "@" << format("%p",fi->first) << ": " << format("%.20g",fi->second) << "\n";
  145. Functions.insert(fi->first);
  146. }
  147. }
  148. for (typename std::set<const FType*>::iterator FI = Functions.begin(), FE = Functions.end();
  149. FI != FE; ++FI) {
  150. const FType *F = *FI;
  151. typename std::map<const FType*, BlockCounts>::iterator bwi = BlockInformation.find(F);
  152. dbgs() << "BasicBlocks for Function " << F << ":\n";
  153. for (typename BlockCounts::const_iterator bi = bwi->second.begin(), be = bwi->second.end(); bi != be; ++bi) {
  154. dbgs() << bi->first << "@" << format("%p", bi->first) << ": " << format("%.20g",bi->second) << "\n";
  155. }
  156. }
  157. for (typename std::set<const FType*>::iterator FI = Functions.begin(), FE = Functions.end();
  158. FI != FE; ++FI) {
  159. typename std::map<const FType*, EdgeWeights>::iterator ei = EdgeInformation.find(*FI);
  160. dbgs() << "Edges for Function " << ei->first << ":\n";
  161. for (typename EdgeWeights::iterator ewi = ei->second.begin(), ewe = ei->second.end();
  162. ewi != ewe; ++ewi) {
  163. dbgs() << ewi->first << ": " << format("%.20g",ewi->second) << "\n";
  164. }
  165. }
  166. } else {
  167. assert(F && "No function given, this is not supported!");
  168. dbgs() << "Functions: \n";
  169. dbgs() << F << "@" << format("%p", F) << ": " << format("%.20g",getExecutionCount(F)) << "\n";
  170. dbgs() << "BasicBlocks for Function " << F << ":\n";
  171. for (typename FType::const_iterator BI = F->begin(), BE = F->end();
  172. BI != BE; ++BI) {
  173. const BType *BB = &(*BI);
  174. dbgs() << BB << "@" << format("%p", BB) << ": " << format("%.20g",getExecutionCount(BB)) << "\n";
  175. }
  176. }
  177. dbgs() << "**** ProfileInfo " << this << ", over and out.\n";
  178. }
  179. bool CalculateMissingEdge(const BType *BB, Edge &removed, bool assumeEmptyExit = false);
  180. bool EstimateMissingEdges(const BType *BB);
  181. ProfileInfoT<MachineFunction, MachineBasicBlock> *MI() {
  182. if (MachineProfile == 0)
  183. MachineProfile = new ProfileInfoT<MachineFunction, MachineBasicBlock>();
  184. return MachineProfile;
  185. }
  186. bool hasMI() const {
  187. return (MachineProfile != 0);
  188. }
  189. };
  190. typedef ProfileInfoT<Function, BasicBlock> ProfileInfo;
  191. typedef ProfileInfoT<MachineFunction, MachineBasicBlock> MachineProfileInfo;
  192. /// createProfileLoaderPass - This function returns a Pass that loads the
  193. /// profiling information for the module from the specified filename, making
  194. /// it available to the optimizers.
  195. Pass *createProfileLoaderPass(const std::string &Filename);
  196. } // End llvm namespace
  197. #endif