136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//=-- InstrProfReader.cpp - Instrumented profiling reader -------------------=// 236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// The LLVM Compiler Infrastructure 436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This file is distributed under the University of Illinois Open Source 636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// License. See LICENSE.TXT for details. 736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===// 936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 1036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This file contains support for reading profiling data for clang's 1136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// instrumentation based PGO and coverage. 1236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// 1336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===// 1436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ProfileData/InstrProfReader.h" 1636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ProfileData/InstrProf.h" 1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 18dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "InstrProfIndexed.h" 19dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include <cassert> 2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesusing namespace llvm; 2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 24cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic std::error_code 25cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinessetupMemoryBuffer(std::string Path, std::unique_ptr<MemoryBuffer> &Buffer) { 26cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = 27cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MemoryBuffer::getFileOrSTDIN(Path); 28cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (std::error_code EC = BufferOrErr.getError()) 2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return EC; 30cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Buffer = std::move(BufferOrErr.get()); 3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 3236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Sanity check the file. 3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Buffer->getBufferSize() > std::numeric_limits<unsigned>::max()) 3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return instrprof_error::too_large; 35dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return instrprof_error::success; 36dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 37dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 38cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic std::error_code initializeReader(InstrProfReader &Reader) { 39dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return Reader.readHeader(); 40dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 41dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 42cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstd::error_code 43cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesInstrProfReader::create(std::string Path, 44cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::unique_ptr<InstrProfReader> &Result) { 45dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Set up the buffer to read. 46dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines std::unique_ptr<MemoryBuffer> Buffer; 47cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (std::error_code EC = setupMemoryBuffer(Path, Buffer)) 48dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return EC; 4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Create the reader. 51dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (IndexedInstrProfReader::hasFormat(*Buffer)) 52dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Result.reset(new IndexedInstrProfReader(std::move(Buffer))); 53dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines else if (RawInstrProfReader64::hasFormat(*Buffer)) 5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result.reset(new RawInstrProfReader64(std::move(Buffer))); 5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (RawInstrProfReader32::hasFormat(*Buffer)) 5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result.reset(new RawInstrProfReader32(std::move(Buffer))); 5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Result.reset(new TextInstrProfReader(std::move(Buffer))); 5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Initialize the reader and return the result. 61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return initializeReader(*Result); 62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 63dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 64cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstd::error_code IndexedInstrProfReader::create( 65dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines std::string Path, std::unique_ptr<IndexedInstrProfReader> &Result) { 66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Set up the buffer to read. 67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines std::unique_ptr<MemoryBuffer> Buffer; 68cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (std::error_code EC = setupMemoryBuffer(Path, Buffer)) 69dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return EC; 70dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 71dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Create the reader. 72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!IndexedInstrProfReader::hasFormat(*Buffer)) 73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return instrprof_error::bad_magic; 74dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Result.reset(new IndexedInstrProfReader(std::move(Buffer))); 75dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 76dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Initialize the reader and return the result. 77dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return initializeReader(*Result); 7836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 7936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 8036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid InstrProfIterator::Increment() { 8136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Reader->readNextRecord(Record)) 8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *this = InstrProfIterator(); 8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 85cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstd::error_code TextInstrProfReader::readNextRecord(InstrProfRecord &Record) { 8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Skip empty lines. 8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines while (!Line.is_at_end() && Line->empty()) 8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ++Line; 8936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // If we hit EOF while looking for a name, we're done. 9036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Line.is_at_end()) 9136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return error(instrprof_error::eof); 9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Read the function name. 9436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Record.Name = *Line++; 9536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Read the function hash. 9736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Line.is_at_end()) 9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return error(instrprof_error::truncated); 9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((Line++)->getAsInteger(10, Record.Hash)) 10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return error(instrprof_error::malformed); 10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Read the number of counters. 10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t NumCounters; 10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Line.is_at_end()) 10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return error(instrprof_error::truncated); 10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((Line++)->getAsInteger(10, NumCounters)) 10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return error(instrprof_error::malformed); 108dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (NumCounters == 0) 109dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return error(instrprof_error::malformed); 11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Read each counter and fill our internal storage with the values. 11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Counts.clear(); 11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Counts.reserve(NumCounters); 11436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (uint64_t I = 0; I < NumCounters; ++I) { 11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Line.is_at_end()) 11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return error(instrprof_error::truncated); 11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Count; 11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((Line++)->getAsInteger(10, Count)) 11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return error(instrprof_error::malformed); 12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Counts.push_back(Count); 12136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Give the record a reference to our internal counter storage. 12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Record.Counts = Counts; 12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return success(); 12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <class IntPtrT> 12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic uint64_t getRawMagic(); 13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <> 13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesuint64_t getRawMagic<uint64_t>() { 13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t(255) << 56 | 13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t('l') << 48 | 13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t('p') << 40 | 13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t('r') << 32 | 13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t('o') << 24 | 13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t('f') << 16 | 14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t('r') << 8 | 14136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t(129); 14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <> 14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesuint64_t getRawMagic<uint32_t>() { 14636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t(255) << 56 | 14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t('l') << 48 | 14936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t('p') << 40 | 15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t('r') << 32 | 15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t('o') << 24 | 15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t('f') << 16 | 15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t('R') << 8 | 15436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t(129); 15536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 15636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <class IntPtrT> 15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool RawInstrProfReader<IntPtrT>::hasFormat(const MemoryBuffer &DataBuffer) { 15936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (DataBuffer.getBufferSize() < sizeof(uint64_t)) 16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 16136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Magic = 16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines *reinterpret_cast<const uint64_t *>(DataBuffer.getBufferStart()); 16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return getRawMagic<IntPtrT>() == Magic || 164cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines sys::getSwappedBytes(getRawMagic<IntPtrT>()) == Magic; 16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <class IntPtrT> 168cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstd::error_code RawInstrProfReader<IntPtrT>::readHeader() { 16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!hasFormat(*DataBuffer)) 17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return error(instrprof_error::bad_magic); 17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (DataBuffer->getBufferSize() < sizeof(RawHeader)) 17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return error(instrprof_error::bad_header); 17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto *Header = 17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines reinterpret_cast<const RawHeader *>(DataBuffer->getBufferStart()); 17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ShouldSwapBytes = Header->Magic != getRawMagic<IntPtrT>(); 17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return readHeader(*Header); 17736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 179dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinestemplate <class IntPtrT> 180cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstd::error_code 181cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesRawInstrProfReader<IntPtrT>::readNextHeader(const char *CurrentPos) { 182dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const char *End = DataBuffer->getBufferEnd(); 183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Skip zero padding between profiles. 184dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines while (CurrentPos != End && *CurrentPos == 0) 185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ++CurrentPos; 186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // If there's nothing left, we're done. 187dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (CurrentPos == End) 188dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return instrprof_error::eof; 189dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // If there isn't enough space for another header, this is probably just 190dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // garbage at the end of the file. 191dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (CurrentPos + sizeof(RawHeader) > End) 192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return instrprof_error::malformed; 193dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // The magic should have the same byte order as in the previous header. 194dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Magic = *reinterpret_cast<const uint64_t *>(CurrentPos); 195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Magic != swap(getRawMagic<IntPtrT>())) 196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return instrprof_error::bad_magic; 197dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 198dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // There's another profile to read, so we need to process the header. 199dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines auto *Header = reinterpret_cast<const RawHeader *>(CurrentPos); 200dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return readHeader(*Header); 201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 202dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic uint64_t getRawVersion() { 20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return 1; 20536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 20636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <class IntPtrT> 208cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstd::error_code 209cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesRawInstrProfReader<IntPtrT>::readHeader(const RawHeader &Header) { 21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (swap(Header.Version) != getRawVersion()) 21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return error(instrprof_error::unsupported_version); 21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CountersDelta = swap(Header.CountersDelta); 21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NamesDelta = swap(Header.NamesDelta); 21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto DataSize = swap(Header.DataSize); 21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto CountersSize = swap(Header.CountersSize); 21736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto NamesSize = swap(Header.NamesSize); 21836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 21936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ptrdiff_t DataOffset = sizeof(RawHeader); 22036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ptrdiff_t CountersOffset = DataOffset + sizeof(ProfileData) * DataSize; 22136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ptrdiff_t NamesOffset = CountersOffset + sizeof(uint64_t) * CountersSize; 222dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines size_t ProfileSize = NamesOffset + sizeof(char) * NamesSize; 22336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 224dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines auto *Start = reinterpret_cast<const char *>(&Header); 225dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Start + ProfileSize > DataBuffer->getBufferEnd()) 22636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return error(instrprof_error::bad_header); 22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Data = reinterpret_cast<const ProfileData *>(Start + DataOffset); 22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines DataEnd = Data + DataSize; 23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CountersStart = reinterpret_cast<const uint64_t *>(Start + CountersOffset); 23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines NamesStart = Start + NamesOffset; 232dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ProfileEnd = Start + ProfileSize; 23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return success(); 23536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 23736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate <class IntPtrT> 238cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstd::error_code 23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesRawInstrProfReader<IntPtrT>::readNextRecord(InstrProfRecord &Record) { 24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Data == DataEnd) 241cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (std::error_code EC = readNextHeader(ProfileEnd)) 242dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return EC; 24336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 24436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Get the raw data. 24536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef RawName(getName(Data->NamePtr), swap(Data->NameSize)); 246dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint32_t NumCounters = swap(Data->NumCounters); 247dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (NumCounters == 0) 248dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return error(instrprof_error::malformed); 249dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines auto RawCounts = makeArrayRef(getCounter(Data->CounterPtr), NumCounters); 25036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Check bounds. 25236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines auto *NamesStartAsCounter = reinterpret_cast<const uint64_t *>(NamesStart); 25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (RawName.data() < NamesStart || 25436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RawName.data() + RawName.size() > DataBuffer->getBufferEnd() || 25536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RawCounts.data() < CountersStart || 25636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines RawCounts.data() + RawCounts.size() > NamesStartAsCounter) 25736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return error(instrprof_error::malformed); 25836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 25936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Store the data in Record, byte-swapping as necessary. 26036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Record.Hash = swap(Data->FuncHash); 26136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Record.Name = RawName; 26236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (ShouldSwapBytes) { 26336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Counts.clear(); 26436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Counts.reserve(RawCounts.size()); 26536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (uint64_t Count : RawCounts) 26636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Counts.push_back(swap(Count)); 26736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Record.Counts = Counts; 26836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else 26936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Record.Counts = RawCounts; 27036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 27136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Iterate. 27236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ++Data; 27336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return success(); 27436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 27536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 27636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace llvm { 27736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate class RawInstrProfReader<uint32_t>; 27836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestemplate class RawInstrProfReader<uint64_t>; 27936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 280dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 281dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesInstrProfLookupTrait::hash_value_type 282dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesInstrProfLookupTrait::ComputeHash(StringRef K) { 283dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return IndexedInstrProf::ComputeHash(HashType, K); 284dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 285dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 286dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool IndexedInstrProfReader::hasFormat(const MemoryBuffer &DataBuffer) { 287dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (DataBuffer.getBufferSize() < 8) 288dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 289dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines using namespace support; 290dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Magic = 291dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines endian::read<uint64_t, little, aligned>(DataBuffer.getBufferStart()); 292dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return Magic == IndexedInstrProf::Magic; 293dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 294dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 295cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstd::error_code IndexedInstrProfReader::readHeader() { 296dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const unsigned char *Start = 297dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines (const unsigned char *)DataBuffer->getBufferStart(); 298dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const unsigned char *Cur = Start; 299dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if ((const unsigned char *)DataBuffer->getBufferEnd() - Cur < 24) 300dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return error(instrprof_error::truncated); 301dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 302dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines using namespace support; 303dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 304dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Check the magic number. 305dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Magic = endian::readNext<uint64_t, little, unaligned>(Cur); 306dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Magic != IndexedInstrProf::Magic) 307dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return error(instrprof_error::bad_magic); 308dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 309dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Read the version. 310dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Version = endian::readNext<uint64_t, little, unaligned>(Cur); 311dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Version != IndexedInstrProf::Version) 312dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return error(instrprof_error::unsupported_version); 313dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 314dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Read the maximal function count. 315dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MaxFunctionCount = endian::readNext<uint64_t, little, unaligned>(Cur); 316dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 317dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Read the hash type and start offset. 318dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines IndexedInstrProf::HashT HashType = static_cast<IndexedInstrProf::HashT>( 319dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines endian::readNext<uint64_t, little, unaligned>(Cur)); 320dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (HashType > IndexedInstrProf::HashT::Last) 321dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return error(instrprof_error::unsupported_hash_type); 322dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t HashOffset = endian::readNext<uint64_t, little, unaligned>(Cur); 323dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 324dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // The rest of the file is an on disk hash table. 325dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Index.reset(InstrProfReaderIndex::Create(Start + HashOffset, Cur, Start, 326dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines InstrProfLookupTrait(HashType))); 327dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Set up our iterator for readNextRecord. 328dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines RecordIterator = Index->data_begin(); 329dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 330dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return success(); 331dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 332dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 333cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstd::error_code IndexedInstrProfReader::getFunctionCounts( 334dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines StringRef FuncName, uint64_t &FuncHash, std::vector<uint64_t> &Counts) { 335dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const auto &Iter = Index->find(FuncName); 336dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Iter == Index->end()) 337dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return error(instrprof_error::unknown_function); 338dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 339dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Found it. Make sure it's valid before giving back a result. 340dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const InstrProfRecord &Record = *Iter; 341dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Record.Name.empty()) 342dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return error(instrprof_error::malformed); 343dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines FuncHash = Record.Hash; 344dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Counts = Record.Counts; 345dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return success(); 346dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 347dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 348cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstd::error_code 349cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesIndexedInstrProfReader::readNextRecord(InstrProfRecord &Record) { 350dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Are we out of records? 351dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (RecordIterator == Index->data_end()) 352dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return error(instrprof_error::eof); 353dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 354dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Read the next one. 355dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Record = *RecordIterator; 356dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ++RecordIterator; 357dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Record.Name.empty()) 358dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return error(instrprof_error::malformed); 359dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return success(); 360dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 361