InstrProf: When reading, copy the data instead of taking a reference. NFC

This consolidates the logic to read instrprof records into the on disk
hash table's lookup trait and makes us copy the counter data instead
of taking references to it as we read. This will simplify further
changes to the format.

Patch by Betul Buyukkurt.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240206 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Justin Bogner
2015-06-20 01:26:04 +00:00
parent cdc126d293
commit 9edccc8b40
3 changed files with 88 additions and 88 deletions

View File

@ -15,7 +15,6 @@
#include "llvm/ProfileData/InstrProfReader.h"
#include "InstrProfIndexed.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ProfileData/InstrProf.h"
#include <cassert>
using namespace llvm;
@ -126,18 +125,16 @@ std::error_code TextInstrProfReader::readNextRecord(InstrProfRecord &Record) {
return error(instrprof_error::malformed);
// Read each counter and fill our internal storage with the values.
Counts.clear();
Counts.reserve(NumCounters);
Record.Counts.clear();
Record.Counts.reserve(NumCounters);
for (uint64_t I = 0; I < NumCounters; ++I) {
if (Line.is_at_end())
return error(instrprof_error::truncated);
uint64_t Count;
if ((Line++)->getAsInteger(10, Count))
return error(instrprof_error::malformed);
Counts.push_back(Count);
Record.Counts.push_back(Count);
}
// Give the record a reference to our internal counter storage.
Record.Counts = Counts;
return success();
}
@ -280,11 +277,10 @@ RawInstrProfReader<IntPtrT>::readNextRecord(InstrProfRecord &Record) {
Record.Hash = swap(Data->FuncHash);
Record.Name = RawName;
if (ShouldSwapBytes) {
Counts.clear();
Counts.reserve(RawCounts.size());
Record.Counts.clear();
Record.Counts.reserve(RawCounts.size());
for (uint64_t Count : RawCounts)
Counts.push_back(swap(Count));
Record.Counts = Counts;
Record.Counts.push_back(swap(Count));
} else
Record.Counts = RawCounts;
@ -303,6 +299,49 @@ InstrProfLookupTrait::ComputeHash(StringRef K) {
return IndexedInstrProf::ComputeHash(HashType, K);
}
typedef InstrProfLookupTrait::data_type data_type;
typedef InstrProfLookupTrait::offset_type offset_type;
data_type InstrProfLookupTrait::ReadData(StringRef K, const unsigned char *D,
offset_type N) {
// Check if the data is corrupt. If so, don't try to read it.
if (N % sizeof(uint64_t))
return data_type();
DataBuffer.clear();
uint64_t NumCounts;
uint64_t NumEntries = N / sizeof(uint64_t);
std::vector<uint64_t> CounterBuffer;
for (uint64_t I = 0; I < NumEntries; I += NumCounts) {
using namespace support;
// The function hash comes first.
uint64_t Hash = endian::readNext<uint64_t, little, unaligned>(D);
if (++I >= NumEntries)
return data_type();
// In v1, we have at least one count.
// Later, we have the number of counts.
NumCounts = (1 == FormatVersion)
? NumEntries - I
: endian::readNext<uint64_t, little, unaligned>(D);
if (1 != FormatVersion)
++I;
// If we have more counts than data, this is bogus.
if (I + NumCounts > NumEntries)
return data_type();
CounterBuffer.clear();
for (unsigned J = 0; J < NumCounts; ++J)
CounterBuffer.push_back(endian::readNext<uint64_t, little, unaligned>(D));
DataBuffer.push_back(InstrProfRecord(K, Hash, CounterBuffer));
}
return DataBuffer;
}
bool IndexedInstrProfReader::hasFormat(const MemoryBuffer &DataBuffer) {
if (DataBuffer.getBufferSize() < 8)
return false;
@ -342,8 +381,9 @@ std::error_code IndexedInstrProfReader::readHeader() {
uint64_t HashOffset = endian::readNext<uint64_t, little, unaligned>(Cur);
// The rest of the file is an on disk hash table.
Index.reset(InstrProfReaderIndex::Create(Start + HashOffset, Cur, Start,
InstrProfLookupTrait(HashType)));
Index.reset(InstrProfReaderIndex::Create(
Start + HashOffset, Cur, Start,
InstrProfLookupTrait(HashType, FormatVersion)));
// Set up our iterator for readNextRecord.
RecordIterator = Index->data_begin();
@ -357,21 +397,14 @@ std::error_code IndexedInstrProfReader::getFunctionCounts(
return error(instrprof_error::unknown_function);
// Found it. Look for counters with the right hash.
ArrayRef<uint64_t> Data = (*Iter).Data;
uint64_t NumCounts;
for (uint64_t I = 0, E = Data.size(); I != E; I += NumCounts) {
// The function hash comes first.
uint64_t FoundHash = Data[I++];
// In v1, we have at least one count. Later, we have the number of counts.
if (I == E)
return error(instrprof_error::malformed);
NumCounts = FormatVersion == 1 ? E - I : Data[I++];
// If we have more counts than data, this is bogus.
if (I + NumCounts > E)
return error(instrprof_error::malformed);
ArrayRef<InstrProfRecord> Data = (*Iter);
if (Data.empty())
return error(instrprof_error::malformed);
for (unsigned I = 0, E = Data.size(); I < E; ++I) {
// Check for a match and fill the vector if there is one.
if (FoundHash == FuncHash) {
Counts = Data.slice(I, NumCounts);
if (Data[I].Hash == FuncHash) {
Counts = Data[I].Counts;
return success();
}
}
@ -384,30 +417,15 @@ IndexedInstrProfReader::readNextRecord(InstrProfRecord &Record) {
if (RecordIterator == Index->data_end())
return error(instrprof_error::eof);
// Record the current function name.
Record.Name = (*RecordIterator).Name;
ArrayRef<uint64_t> Data = (*RecordIterator).Data;
// Valid data starts with a hash and either a count or the number of counts.
if (CurrentOffset + 1 > Data.size())
if ((*RecordIterator).empty())
return error(instrprof_error::malformed);
// First we have a function hash.
Record.Hash = Data[CurrentOffset++];
// In version 1 we knew the number of counters implicitly, but in newer
// versions we store the number of counters next.
uint64_t NumCounts =
FormatVersion == 1 ? Data.size() - CurrentOffset : Data[CurrentOffset++];
if (CurrentOffset + NumCounts > Data.size())
return error(instrprof_error::malformed);
// And finally the counts themselves.
Record.Counts = Data.slice(CurrentOffset, NumCounts);
// If we've exhausted this function's data, increment the record.
CurrentOffset += NumCounts;
if (CurrentOffset == Data.size()) {
static unsigned RecordIndex = 0;
ArrayRef<InstrProfRecord> Data = (*RecordIterator);
Record = Data[RecordIndex++];
if (RecordIndex >= Data.size()) {
++RecordIterator;
CurrentOffset = 0;
RecordIndex = 0;
}
return success();
}