InstrProfReader.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. //=-- InstrProfReader.cpp - Instrumented profiling reader -------------------=//
  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 contains support for reading profiling data for clang's
  11. // instrumentation based PGO and coverage.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "llvm/ProfileData/InstrProfReader.h"
  15. #include "InstrProfIndexed.h"
  16. #include "llvm/ADT/STLExtras.h"
  17. #include <cassert>
  18. using namespace llvm;
  19. static ErrorOr<std::unique_ptr<MemoryBuffer>>
  20. setupMemoryBuffer(std::string Path) {
  21. ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
  22. MemoryBuffer::getFileOrSTDIN(Path);
  23. if (std::error_code EC = BufferOrErr.getError())
  24. return EC;
  25. return std::move(BufferOrErr.get());
  26. }
  27. static std::error_code initializeReader(InstrProfReader &Reader) {
  28. return Reader.readHeader();
  29. }
  30. ErrorOr<std::unique_ptr<InstrProfReader>>
  31. InstrProfReader::create(std::string Path) {
  32. // Set up the buffer to read.
  33. auto BufferOrError = setupMemoryBuffer(Path);
  34. if (std::error_code EC = BufferOrError.getError())
  35. return EC;
  36. return InstrProfReader::create(std::move(BufferOrError.get()));
  37. }
  38. ErrorOr<std::unique_ptr<InstrProfReader>>
  39. InstrProfReader::create(std::unique_ptr<MemoryBuffer> Buffer) {
  40. // Sanity check the buffer.
  41. if (Buffer->getBufferSize() > std::numeric_limits<unsigned>::max())
  42. return instrprof_error::too_large;
  43. std::unique_ptr<InstrProfReader> Result;
  44. // Create the reader.
  45. if (IndexedInstrProfReader::hasFormat(*Buffer))
  46. Result.reset(new IndexedInstrProfReader(std::move(Buffer)));
  47. else if (RawInstrProfReader64::hasFormat(*Buffer))
  48. Result.reset(new RawInstrProfReader64(std::move(Buffer)));
  49. else if (RawInstrProfReader32::hasFormat(*Buffer))
  50. Result.reset(new RawInstrProfReader32(std::move(Buffer)));
  51. else
  52. Result.reset(new TextInstrProfReader(std::move(Buffer)));
  53. // Initialize the reader and return the result.
  54. if (std::error_code EC = initializeReader(*Result))
  55. return EC;
  56. return std::move(Result);
  57. }
  58. ErrorOr<std::unique_ptr<IndexedInstrProfReader>>
  59. IndexedInstrProfReader::create(std::string Path) {
  60. // Set up the buffer to read.
  61. auto BufferOrError = setupMemoryBuffer(Path);
  62. if (std::error_code EC = BufferOrError.getError())
  63. return EC;
  64. return IndexedInstrProfReader::create(std::move(BufferOrError.get()));
  65. }
  66. ErrorOr<std::unique_ptr<IndexedInstrProfReader>>
  67. IndexedInstrProfReader::create(std::unique_ptr<MemoryBuffer> Buffer) {
  68. // Sanity check the buffer.
  69. if (Buffer->getBufferSize() > std::numeric_limits<unsigned>::max())
  70. return instrprof_error::too_large;
  71. // Create the reader.
  72. if (!IndexedInstrProfReader::hasFormat(*Buffer))
  73. return instrprof_error::bad_magic;
  74. auto Result = llvm::make_unique<IndexedInstrProfReader>(std::move(Buffer));
  75. // Initialize the reader and return the result.
  76. if (std::error_code EC = initializeReader(*Result))
  77. return EC;
  78. return std::move(Result);
  79. }
  80. void InstrProfIterator::Increment() {
  81. if (Reader->readNextRecord(Record))
  82. *this = InstrProfIterator();
  83. }
  84. std::error_code TextInstrProfReader::readNextRecord(InstrProfRecord &Record) {
  85. // Skip empty lines and comments.
  86. while (!Line.is_at_end() && (Line->empty() || Line->startswith("#")))
  87. ++Line;
  88. // If we hit EOF while looking for a name, we're done.
  89. if (Line.is_at_end())
  90. return error(instrprof_error::eof);
  91. // Read the function name.
  92. Record.Name = *Line++;
  93. // Read the function hash.
  94. if (Line.is_at_end())
  95. return error(instrprof_error::truncated);
  96. if ((Line++)->getAsInteger(0, Record.Hash))
  97. return error(instrprof_error::malformed);
  98. // Read the number of counters.
  99. uint64_t NumCounters;
  100. if (Line.is_at_end())
  101. return error(instrprof_error::truncated);
  102. if ((Line++)->getAsInteger(10, NumCounters))
  103. return error(instrprof_error::malformed);
  104. if (NumCounters == 0)
  105. return error(instrprof_error::malformed);
  106. // Read each counter and fill our internal storage with the values.
  107. Record.Counts.clear();
  108. Record.Counts.reserve(NumCounters);
  109. for (uint64_t I = 0; I < NumCounters; ++I) {
  110. if (Line.is_at_end())
  111. return error(instrprof_error::truncated);
  112. uint64_t Count;
  113. if ((Line++)->getAsInteger(10, Count))
  114. return error(instrprof_error::malformed);
  115. Record.Counts.push_back(Count);
  116. }
  117. return success();
  118. }
  119. template <class IntPtrT>
  120. static uint64_t getRawMagic();
  121. template <>
  122. uint64_t getRawMagic<uint64_t>() {
  123. return
  124. uint64_t(255) << 56 |
  125. uint64_t('l') << 48 |
  126. uint64_t('p') << 40 |
  127. uint64_t('r') << 32 |
  128. uint64_t('o') << 24 |
  129. uint64_t('f') << 16 |
  130. uint64_t('r') << 8 |
  131. uint64_t(129);
  132. }
  133. template <>
  134. uint64_t getRawMagic<uint32_t>() {
  135. return
  136. uint64_t(255) << 56 |
  137. uint64_t('l') << 48 |
  138. uint64_t('p') << 40 |
  139. uint64_t('r') << 32 |
  140. uint64_t('o') << 24 |
  141. uint64_t('f') << 16 |
  142. uint64_t('R') << 8 |
  143. uint64_t(129);
  144. }
  145. template <class IntPtrT>
  146. bool RawInstrProfReader<IntPtrT>::hasFormat(const MemoryBuffer &DataBuffer) {
  147. if (DataBuffer.getBufferSize() < sizeof(uint64_t))
  148. return false;
  149. uint64_t Magic =
  150. *reinterpret_cast<const uint64_t *>(DataBuffer.getBufferStart());
  151. return getRawMagic<IntPtrT>() == Magic ||
  152. sys::getSwappedBytes(getRawMagic<IntPtrT>()) == Magic;
  153. }
  154. template <class IntPtrT>
  155. std::error_code RawInstrProfReader<IntPtrT>::readHeader() {
  156. if (!hasFormat(*DataBuffer))
  157. return error(instrprof_error::bad_magic);
  158. if (DataBuffer->getBufferSize() < sizeof(RawHeader))
  159. return error(instrprof_error::bad_header);
  160. auto *Header =
  161. reinterpret_cast<const RawHeader *>(DataBuffer->getBufferStart());
  162. ShouldSwapBytes = Header->Magic != getRawMagic<IntPtrT>();
  163. return readHeader(*Header);
  164. }
  165. template <class IntPtrT>
  166. std::error_code
  167. RawInstrProfReader<IntPtrT>::readNextHeader(const char *CurrentPos) {
  168. const char *End = DataBuffer->getBufferEnd();
  169. // Skip zero padding between profiles.
  170. while (CurrentPos != End && *CurrentPos == 0)
  171. ++CurrentPos;
  172. // If there's nothing left, we're done.
  173. if (CurrentPos == End)
  174. return instrprof_error::eof;
  175. // If there isn't enough space for another header, this is probably just
  176. // garbage at the end of the file.
  177. if (CurrentPos + sizeof(RawHeader) > End)
  178. return instrprof_error::malformed;
  179. // The writer ensures each profile is padded to start at an aligned address.
  180. if (reinterpret_cast<size_t>(CurrentPos) % alignOf<uint64_t>())
  181. return instrprof_error::malformed;
  182. // The magic should have the same byte order as in the previous header.
  183. uint64_t Magic = *reinterpret_cast<const uint64_t *>(CurrentPos);
  184. if (Magic != swap(getRawMagic<IntPtrT>()))
  185. return instrprof_error::bad_magic;
  186. // There's another profile to read, so we need to process the header.
  187. auto *Header = reinterpret_cast<const RawHeader *>(CurrentPos);
  188. return readHeader(*Header);
  189. }
  190. static uint64_t getRawVersion() {
  191. return 1;
  192. }
  193. template <class IntPtrT>
  194. std::error_code
  195. RawInstrProfReader<IntPtrT>::readHeader(const RawHeader &Header) {
  196. if (swap(Header.Version) != getRawVersion())
  197. return error(instrprof_error::unsupported_version);
  198. CountersDelta = swap(Header.CountersDelta);
  199. NamesDelta = swap(Header.NamesDelta);
  200. auto DataSize = swap(Header.DataSize);
  201. auto CountersSize = swap(Header.CountersSize);
  202. auto NamesSize = swap(Header.NamesSize);
  203. ptrdiff_t DataOffset = sizeof(RawHeader);
  204. ptrdiff_t CountersOffset = DataOffset + sizeof(ProfileData) * DataSize;
  205. ptrdiff_t NamesOffset = CountersOffset + sizeof(uint64_t) * CountersSize;
  206. size_t ProfileSize = NamesOffset + sizeof(char) * NamesSize;
  207. auto *Start = reinterpret_cast<const char *>(&Header);
  208. if (Start + ProfileSize > DataBuffer->getBufferEnd())
  209. return error(instrprof_error::bad_header);
  210. Data = reinterpret_cast<const ProfileData *>(Start + DataOffset);
  211. DataEnd = Data + DataSize;
  212. CountersStart = reinterpret_cast<const uint64_t *>(Start + CountersOffset);
  213. NamesStart = Start + NamesOffset;
  214. ProfileEnd = Start + ProfileSize;
  215. return success();
  216. }
  217. template <class IntPtrT>
  218. std::error_code
  219. RawInstrProfReader<IntPtrT>::readNextRecord(InstrProfRecord &Record) {
  220. if (Data == DataEnd)
  221. if (std::error_code EC = readNextHeader(ProfileEnd))
  222. return EC;
  223. // Get the raw data.
  224. StringRef RawName(getName(Data->NamePtr), swap(Data->NameSize));
  225. uint32_t NumCounters = swap(Data->NumCounters);
  226. if (NumCounters == 0)
  227. return error(instrprof_error::malformed);
  228. auto RawCounts = makeArrayRef(getCounter(Data->CounterPtr), NumCounters);
  229. // Check bounds.
  230. auto *NamesStartAsCounter = reinterpret_cast<const uint64_t *>(NamesStart);
  231. if (RawName.data() < NamesStart ||
  232. RawName.data() + RawName.size() > DataBuffer->getBufferEnd() ||
  233. RawCounts.data() < CountersStart ||
  234. RawCounts.data() + RawCounts.size() > NamesStartAsCounter)
  235. return error(instrprof_error::malformed);
  236. // Store the data in Record, byte-swapping as necessary.
  237. Record.Hash = swap(Data->FuncHash);
  238. Record.Name = RawName;
  239. if (ShouldSwapBytes) {
  240. Record.Counts.clear();
  241. Record.Counts.reserve(RawCounts.size());
  242. for (uint64_t Count : RawCounts)
  243. Record.Counts.push_back(swap(Count));
  244. } else
  245. Record.Counts = RawCounts;
  246. // Iterate.
  247. ++Data;
  248. return success();
  249. }
  250. namespace llvm {
  251. template class RawInstrProfReader<uint32_t>;
  252. template class RawInstrProfReader<uint64_t>;
  253. }
  254. InstrProfLookupTrait::hash_value_type
  255. InstrProfLookupTrait::ComputeHash(StringRef K) {
  256. return IndexedInstrProf::ComputeHash(HashType, K);
  257. }
  258. typedef InstrProfLookupTrait::data_type data_type;
  259. typedef InstrProfLookupTrait::offset_type offset_type;
  260. data_type InstrProfLookupTrait::ReadData(StringRef K, const unsigned char *D,
  261. offset_type N) {
  262. // Check if the data is corrupt. If so, don't try to read it.
  263. if (N % sizeof(uint64_t))
  264. return data_type();
  265. DataBuffer.clear();
  266. uint64_t NumCounts;
  267. uint64_t NumEntries = N / sizeof(uint64_t);
  268. std::vector<uint64_t> CounterBuffer;
  269. for (uint64_t I = 0; I < NumEntries; I += NumCounts) {
  270. using namespace support;
  271. // The function hash comes first.
  272. uint64_t Hash = endian::readNext<uint64_t, little, unaligned>(D);
  273. if (++I >= NumEntries)
  274. return data_type();
  275. // In v1, we have at least one count.
  276. // Later, we have the number of counts.
  277. NumCounts = (1 == FormatVersion)
  278. ? NumEntries - I
  279. : endian::readNext<uint64_t, little, unaligned>(D);
  280. if (1 != FormatVersion)
  281. ++I;
  282. // If we have more counts than data, this is bogus.
  283. if (I + NumCounts > NumEntries)
  284. return data_type();
  285. CounterBuffer.clear();
  286. for (unsigned J = 0; J < NumCounts; ++J)
  287. CounterBuffer.push_back(endian::readNext<uint64_t, little, unaligned>(D));
  288. DataBuffer.push_back(InstrProfRecord(K, Hash, std::move(CounterBuffer)));
  289. }
  290. return DataBuffer;
  291. }
  292. bool IndexedInstrProfReader::hasFormat(const MemoryBuffer &DataBuffer) {
  293. if (DataBuffer.getBufferSize() < 8)
  294. return false;
  295. using namespace support;
  296. uint64_t Magic =
  297. endian::read<uint64_t, little, aligned>(DataBuffer.getBufferStart());
  298. return Magic == IndexedInstrProf::Magic;
  299. }
  300. std::error_code IndexedInstrProfReader::readHeader() {
  301. const unsigned char *Start =
  302. (const unsigned char *)DataBuffer->getBufferStart();
  303. const unsigned char *Cur = Start;
  304. if ((const unsigned char *)DataBuffer->getBufferEnd() - Cur < 24)
  305. return error(instrprof_error::truncated);
  306. using namespace support;
  307. // Check the magic number.
  308. uint64_t Magic = endian::readNext<uint64_t, little, unaligned>(Cur);
  309. if (Magic != IndexedInstrProf::Magic)
  310. return error(instrprof_error::bad_magic);
  311. // Read the version.
  312. FormatVersion = endian::readNext<uint64_t, little, unaligned>(Cur);
  313. if (FormatVersion > IndexedInstrProf::Version)
  314. return error(instrprof_error::unsupported_version);
  315. // Read the maximal function count.
  316. MaxFunctionCount = endian::readNext<uint64_t, little, unaligned>(Cur);
  317. // Read the hash type and start offset.
  318. IndexedInstrProf::HashT HashType = static_cast<IndexedInstrProf::HashT>(
  319. endian::readNext<uint64_t, little, unaligned>(Cur));
  320. if (HashType > IndexedInstrProf::HashT::Last)
  321. return error(instrprof_error::unsupported_hash_type);
  322. uint64_t HashOffset = endian::readNext<uint64_t, little, unaligned>(Cur);
  323. // The rest of the file is an on disk hash table.
  324. Index.reset(InstrProfReaderIndex::Create(
  325. Start + HashOffset, Cur, Start,
  326. InstrProfLookupTrait(HashType, FormatVersion)));
  327. // Set up our iterator for readNextRecord.
  328. RecordIterator = Index->data_begin();
  329. return success();
  330. }
  331. std::error_code IndexedInstrProfReader::getFunctionCounts(
  332. StringRef FuncName, uint64_t FuncHash, std::vector<uint64_t> &Counts) {
  333. auto Iter = Index->find(FuncName);
  334. if (Iter == Index->end())
  335. return error(instrprof_error::unknown_function);
  336. // Found it. Look for counters with the right hash.
  337. ArrayRef<InstrProfRecord> Data = (*Iter);
  338. if (Data.empty())
  339. return error(instrprof_error::malformed);
  340. for (unsigned I = 0, E = Data.size(); I < E; ++I) {
  341. // Check for a match and fill the vector if there is one.
  342. if (Data[I].Hash == FuncHash) {
  343. Counts = Data[I].Counts;
  344. return success();
  345. }
  346. }
  347. return error(instrprof_error::hash_mismatch);
  348. }
  349. std::error_code
  350. IndexedInstrProfReader::readNextRecord(InstrProfRecord &Record) {
  351. // Are we out of records?
  352. if (RecordIterator == Index->data_end())
  353. return error(instrprof_error::eof);
  354. if ((*RecordIterator).empty())
  355. return error(instrprof_error::malformed);
  356. static unsigned RecordIndex = 0;
  357. ArrayRef<InstrProfRecord> Data = (*RecordIterator);
  358. Record = Data[RecordIndex++];
  359. if (RecordIndex >= Data.size()) {
  360. ++RecordIterator;
  361. RecordIndex = 0;
  362. }
  363. return success();
  364. }