ProfileDataLoader.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. //===- ProfileDataLoader.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 ProfileDataLoader class is used to load raw profiling data from the dump
  11. // file.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "llvm/Analysis/ProfileDataLoader.h"
  15. #include "llvm/ADT/ArrayRef.h"
  16. #include "llvm/ADT/OwningPtr.h"
  17. #include "llvm/Analysis/ProfileDataTypes.h"
  18. #include "llvm/InstrTypes.h"
  19. #include "llvm/Module.h"
  20. #include "llvm/Support/raw_ostream.h"
  21. #include "llvm/Support/system_error.h"
  22. #include <cstdio>
  23. #include <cstdlib>
  24. using namespace llvm;
  25. raw_ostream &llvm::operator<<(raw_ostream &O, std::pair<const BasicBlock *,
  26. const BasicBlock *> E) {
  27. O << "(";
  28. if (E.first)
  29. O << E.first->getName();
  30. else
  31. O << "0";
  32. O << ",";
  33. if (E.second)
  34. O << E.second->getName();
  35. else
  36. O << "0";
  37. return O << ")";
  38. }
  39. /// AddCounts - Add 'A' and 'B', accounting for the fact that the value of one
  40. /// (or both) may not be defined.
  41. static unsigned AddCounts(unsigned A, unsigned B) {
  42. // If either value is undefined, use the other.
  43. // Undefined + undefined = undefined.
  44. if (A == ProfileDataLoader::Uncounted) return B;
  45. if (B == ProfileDataLoader::Uncounted) return A;
  46. return A + B;
  47. }
  48. /// ReadProfilingData - Load 'NumEntries' items of type 'T' from file 'F'
  49. template <typename T>
  50. static void ReadProfilingData(const char *ToolName, FILE *F,
  51. T *Data, size_t NumEntries) {
  52. // Read in the block of data...
  53. if (fread(Data, sizeof(T), NumEntries, F) != NumEntries)
  54. report_fatal_error(Twine(ToolName) + ": Profiling data truncated");
  55. }
  56. /// ReadProfilingNumEntries - Read how many entries are in this profiling data
  57. /// packet.
  58. static unsigned ReadProfilingNumEntries(const char *ToolName, FILE *F,
  59. bool ShouldByteSwap) {
  60. unsigned Entry;
  61. ReadProfilingData<unsigned>(ToolName, F, &Entry, 1);
  62. return ShouldByteSwap ? ByteSwap_32(Entry) : Entry;
  63. }
  64. /// ReadProfilingBlock - Read the number of entries in the next profiling data
  65. /// packet and then accumulate the entries into 'Data'.
  66. static void ReadProfilingBlock(const char *ToolName, FILE *F,
  67. bool ShouldByteSwap,
  68. SmallVector<unsigned, 32> &Data) {
  69. // Read the number of entries...
  70. unsigned NumEntries = ReadProfilingNumEntries(ToolName, F, ShouldByteSwap);
  71. // Read in the data.
  72. SmallVector<unsigned, 8> TempSpace(NumEntries);
  73. ReadProfilingData<unsigned>(ToolName, F, TempSpace.data(), NumEntries);
  74. // Make sure we have enough space ...
  75. if (Data.size() < NumEntries)
  76. Data.resize(NumEntries, ProfileDataLoader::Uncounted);
  77. // Accumulate the data we just read into the existing data.
  78. for (unsigned i = 0; i < NumEntries; ++i) {
  79. unsigned Entry = ShouldByteSwap ? ByteSwap_32(TempSpace[i]) : TempSpace[i];
  80. Data[i] = AddCounts(Entry, Data[i]);
  81. }
  82. }
  83. /// ReadProfilingArgBlock - Read the command line arguments that the progam was
  84. /// run with when the current profiling data packet(s) were generated.
  85. static void ReadProfilingArgBlock(const char *ToolName, FILE *F,
  86. bool ShouldByteSwap,
  87. SmallVector<std::string, 1> &CommandLines) {
  88. // Read the number of bytes ...
  89. unsigned ArgLength = ReadProfilingNumEntries(ToolName, F, ShouldByteSwap);
  90. // Read in the arguments (if there are any to read). Round up the length to
  91. // the nearest 4-byte multiple.
  92. SmallVector<char, 8> Args(ArgLength+4);
  93. if (ArgLength)
  94. ReadProfilingData<char>(ToolName, F, Args.data(), (ArgLength+3) & ~3);
  95. // Store the arguments.
  96. CommandLines.push_back(std::string(&Args[0], &Args[ArgLength]));
  97. }
  98. const unsigned ProfileDataLoader::Uncounted = ~0U;
  99. /// ProfileDataLoader ctor - Read the specified profiling data file, reporting
  100. /// a fatal error if the file is invalid or broken.
  101. ProfileDataLoader::ProfileDataLoader(const char *ToolName,
  102. const std::string &Filename)
  103. : Filename(Filename) {
  104. FILE *F = fopen(Filename.c_str(), "rb");
  105. if (F == 0)
  106. report_fatal_error(Twine(ToolName) + ": Error opening '" +
  107. Filename + "': ");
  108. // Keep reading packets until we run out of them.
  109. unsigned PacketType;
  110. while (fread(&PacketType, sizeof(unsigned), 1, F) == 1) {
  111. // If the low eight bits of the packet are zero, we must be dealing with an
  112. // endianness mismatch. Byteswap all words read from the profiling
  113. // information. This can happen when the compiler host and target have
  114. // different endianness.
  115. bool ShouldByteSwap = (char)PacketType == 0;
  116. PacketType = ShouldByteSwap ? ByteSwap_32(PacketType) : PacketType;
  117. switch (PacketType) {
  118. case ArgumentInfo:
  119. ReadProfilingArgBlock(ToolName, F, ShouldByteSwap, CommandLines);
  120. break;
  121. case EdgeInfo:
  122. ReadProfilingBlock(ToolName, F, ShouldByteSwap, EdgeCounts);
  123. break;
  124. default:
  125. report_fatal_error(std::string(ToolName)
  126. + ": Unknown profiling packet type");
  127. break;
  128. }
  129. }
  130. fclose(F);
  131. }