ProfileInfoLoader.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. //===- ProfileInfoLoad.cpp - Load profile information from disk -----------===//
  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. // The ProfileInfoLoader class is used to load and represent profiling
  11. // information read in from the dump file.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "llvm/Analysis/ProfileInfoLoader.h"
  15. #include "llvm/Analysis/ProfileInfoTypes.h"
  16. #include "llvm/Module.h"
  17. #include "llvm/InstrTypes.h"
  18. #include "llvm/Support/Streams.h"
  19. #include <cstdio>
  20. #include <cstdlib>
  21. #include <map>
  22. using namespace llvm;
  23. // ByteSwap - Byteswap 'Var' if 'Really' is true.
  24. //
  25. static inline unsigned ByteSwap(unsigned Var, bool Really) {
  26. if (!Really) return Var;
  27. return ((Var & (255<< 0)) << 24) |
  28. ((Var & (255<< 8)) << 8) |
  29. ((Var & (255<<16)) >> 8) |
  30. ((Var & (255<<24)) >> 24);
  31. }
  32. static void ReadProfilingBlock(const char *ToolName, FILE *F,
  33. bool ShouldByteSwap,
  34. std::vector<unsigned> &Data) {
  35. // Read the number of entries...
  36. unsigned NumEntries;
  37. if (fread(&NumEntries, sizeof(unsigned), 1, F) != 1) {
  38. cerr << ToolName << ": data packet truncated!\n";
  39. perror(0);
  40. exit(1);
  41. }
  42. NumEntries = ByteSwap(NumEntries, ShouldByteSwap);
  43. // Read the counts...
  44. std::vector<unsigned> TempSpace(NumEntries);
  45. // Read in the block of data...
  46. if (fread(&TempSpace[0], sizeof(unsigned)*NumEntries, 1, F) != 1) {
  47. cerr << ToolName << ": data packet truncated!\n";
  48. perror(0);
  49. exit(1);
  50. }
  51. // Make sure we have enough space...
  52. if (Data.size() < NumEntries)
  53. Data.resize(NumEntries);
  54. // Accumulate the data we just read into the data.
  55. if (!ShouldByteSwap) {
  56. for (unsigned i = 0; i != NumEntries; ++i)
  57. Data[i] += TempSpace[i];
  58. } else {
  59. for (unsigned i = 0; i != NumEntries; ++i)
  60. Data[i] += ByteSwap(TempSpace[i], true);
  61. }
  62. }
  63. // ProfileInfoLoader ctor - Read the specified profiling data file, exiting the
  64. // program if the file is invalid or broken.
  65. //
  66. ProfileInfoLoader::ProfileInfoLoader(const char *ToolName,
  67. const std::string &Filename,
  68. Module &TheModule) : M(TheModule) {
  69. FILE *F = fopen(Filename.c_str(), "r");
  70. if (F == 0) {
  71. cerr << ToolName << ": Error opening '" << Filename << "': ";
  72. perror(0);
  73. exit(1);
  74. }
  75. // Keep reading packets until we run out of them.
  76. unsigned PacketType;
  77. while (fread(&PacketType, sizeof(unsigned), 1, F) == 1) {
  78. // If the low eight bits of the packet are zero, we must be dealing with an
  79. // endianness mismatch. Byteswap all words read from the profiling
  80. // information.
  81. bool ShouldByteSwap = (char)PacketType == 0;
  82. PacketType = ByteSwap(PacketType, ShouldByteSwap);
  83. switch (PacketType) {
  84. case ArgumentInfo: {
  85. unsigned ArgLength;
  86. if (fread(&ArgLength, sizeof(unsigned), 1, F) != 1) {
  87. cerr << ToolName << ": arguments packet truncated!\n";
  88. perror(0);
  89. exit(1);
  90. }
  91. ArgLength = ByteSwap(ArgLength, ShouldByteSwap);
  92. // Read in the arguments...
  93. std::vector<char> Chars(ArgLength+4);
  94. if (ArgLength)
  95. if (fread(&Chars[0], (ArgLength+3) & ~3, 1, F) != 1) {
  96. cerr << ToolName << ": arguments packet truncated!\n";
  97. perror(0);
  98. exit(1);
  99. }
  100. CommandLines.push_back(std::string(&Chars[0], &Chars[ArgLength]));
  101. break;
  102. }
  103. case FunctionInfo:
  104. ReadProfilingBlock(ToolName, F, ShouldByteSwap, FunctionCounts);
  105. break;
  106. case BlockInfo:
  107. ReadProfilingBlock(ToolName, F, ShouldByteSwap, BlockCounts);
  108. break;
  109. case EdgeInfo:
  110. ReadProfilingBlock(ToolName, F, ShouldByteSwap, EdgeCounts);
  111. break;
  112. case BBTraceInfo:
  113. ReadProfilingBlock(ToolName, F, ShouldByteSwap, BBTrace);
  114. break;
  115. default:
  116. cerr << ToolName << ": Unknown packet type #" << PacketType << "!\n";
  117. exit(1);
  118. }
  119. }
  120. fclose(F);
  121. }
  122. // getFunctionCounts - This method is used by consumers of function counting
  123. // information. If we do not directly have function count information, we
  124. // compute it from other, more refined, types of profile information.
  125. //
  126. void ProfileInfoLoader::getFunctionCounts(std::vector<std::pair<Function*,
  127. unsigned> > &Counts) {
  128. if (FunctionCounts.empty()) {
  129. if (hasAccurateBlockCounts()) {
  130. // Synthesize function frequency information from the number of times
  131. // their entry blocks were executed.
  132. std::vector<std::pair<BasicBlock*, unsigned> > BlockCounts;
  133. getBlockCounts(BlockCounts);
  134. for (unsigned i = 0, e = BlockCounts.size(); i != e; ++i)
  135. if (&BlockCounts[i].first->getParent()->getEntryBlock() ==
  136. BlockCounts[i].first)
  137. Counts.push_back(std::make_pair(BlockCounts[i].first->getParent(),
  138. BlockCounts[i].second));
  139. } else {
  140. cerr << "Function counts are not available!\n";
  141. }
  142. return;
  143. }
  144. unsigned Counter = 0;
  145. for (Module::iterator I = M.begin(), E = M.end();
  146. I != E && Counter != FunctionCounts.size(); ++I)
  147. if (!I->isDeclaration())
  148. Counts.push_back(std::make_pair(I, FunctionCounts[Counter++]));
  149. }
  150. // getBlockCounts - This method is used by consumers of block counting
  151. // information. If we do not directly have block count information, we
  152. // compute it from other, more refined, types of profile information.
  153. //
  154. void ProfileInfoLoader::getBlockCounts(std::vector<std::pair<BasicBlock*,
  155. unsigned> > &Counts) {
  156. if (BlockCounts.empty()) {
  157. if (hasAccurateEdgeCounts()) {
  158. // Synthesize block count information from edge frequency information.
  159. // The block execution frequency is equal to the sum of the execution
  160. // frequency of all outgoing edges from a block.
  161. //
  162. // If a block has no successors, this will not be correct, so we have to
  163. // special case it. :(
  164. std::vector<std::pair<Edge, unsigned> > EdgeCounts;
  165. getEdgeCounts(EdgeCounts);
  166. std::map<BasicBlock*, unsigned> InEdgeFreqs;
  167. BasicBlock *LastBlock = 0;
  168. TerminatorInst *TI = 0;
  169. for (unsigned i = 0, e = EdgeCounts.size(); i != e; ++i) {
  170. if (EdgeCounts[i].first.first != LastBlock) {
  171. LastBlock = EdgeCounts[i].first.first;
  172. TI = LastBlock->getTerminator();
  173. Counts.push_back(std::make_pair(LastBlock, 0));
  174. }
  175. Counts.back().second += EdgeCounts[i].second;
  176. unsigned SuccNum = EdgeCounts[i].first.second;
  177. if (SuccNum >= TI->getNumSuccessors()) {
  178. static bool Warned = false;
  179. if (!Warned) {
  180. cerr << "WARNING: profile info doesn't seem to match"
  181. << " the program!\n";
  182. Warned = true;
  183. }
  184. } else {
  185. // If this successor has no successors of its own, we will never
  186. // compute an execution count for that block. Remember the incoming
  187. // edge frequencies to add later.
  188. BasicBlock *Succ = TI->getSuccessor(SuccNum);
  189. if (Succ->getTerminator()->getNumSuccessors() == 0)
  190. InEdgeFreqs[Succ] += EdgeCounts[i].second;
  191. }
  192. }
  193. // Now we have to accumulate information for those blocks without
  194. // successors into our table.
  195. for (std::map<BasicBlock*, unsigned>::iterator I = InEdgeFreqs.begin(),
  196. E = InEdgeFreqs.end(); I != E; ++I) {
  197. unsigned i = 0;
  198. for (; i != Counts.size() && Counts[i].first != I->first; ++i)
  199. /*empty*/;
  200. if (i == Counts.size()) Counts.push_back(std::make_pair(I->first, 0));
  201. Counts[i].second += I->second;
  202. }
  203. } else {
  204. cerr << "Block counts are not available!\n";
  205. }
  206. return;
  207. }
  208. unsigned Counter = 0;
  209. for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
  210. for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
  211. Counts.push_back(std::make_pair(BB, BlockCounts[Counter++]));
  212. if (Counter == BlockCounts.size())
  213. return;
  214. }
  215. }
  216. // getEdgeCounts - This method is used by consumers of edge counting
  217. // information. If we do not directly have edge count information, we compute
  218. // it from other, more refined, types of profile information.
  219. //
  220. void ProfileInfoLoader::getEdgeCounts(std::vector<std::pair<Edge,
  221. unsigned> > &Counts) {
  222. if (EdgeCounts.empty()) {
  223. cerr << "Edge counts not available, and no synthesis "
  224. << "is implemented yet!\n";
  225. return;
  226. }
  227. unsigned Counter = 0;
  228. for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
  229. for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
  230. for (unsigned i = 0, e = BB->getTerminator()->getNumSuccessors();
  231. i != e; ++i) {
  232. Counts.push_back(std::make_pair(Edge(BB, i), EdgeCounts[Counter++]));
  233. if (Counter == EdgeCounts.size())
  234. return;
  235. }
  236. }
  237. // getBBTrace - This method is used by consumers of basic-block trace
  238. // information.
  239. //
  240. void ProfileInfoLoader::getBBTrace(std::vector<BasicBlock *> &Trace) {
  241. if (BBTrace.empty ()) {
  242. cerr << "Basic block trace is not available!\n";
  243. return;
  244. }
  245. cerr << "Basic block trace loading is not implemented yet!\n";
  246. }