aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/ProfileData/InstrProfReader.cpp
diff options
context:
space:
mode:
authorBetul Buyukkurt <betulb@codeaurora.org>2015-11-18 18:14:55 +0000
committerBetul Buyukkurt <betulb@codeaurora.org>2015-11-18 18:14:55 +0000
commit6fac1741c914939a7ca2f9a5b118dc27247f403c (patch)
treee97807136d8bf5e75422c1a6c6b844e27294fda6 /llvm/lib/ProfileData/InstrProfReader.cpp
parent808385f1aedc196e1b7b3ac88667aee8d5b8fa1d (diff)
downloadllvm-6fac1741c914939a7ca2f9a5b118dc27247f403c.zip
llvm-6fac1741c914939a7ca2f9a5b118dc27247f403c.tar.gz
llvm-6fac1741c914939a7ca2f9a5b118dc27247f403c.tar.bz2
[PGO] Value profiling support
This change introduces an instrumentation intrinsic instruction for value profiling purposes, the lowering of the instrumentation intrinsic and raw reader updates. The raw profile data files for llvm-profdata testing are updated. llvm-svn: 253484
Diffstat (limited to 'llvm/lib/ProfileData/InstrProfReader.cpp')
-rw-r--r--llvm/lib/ProfileData/InstrProfReader.cpp83
1 files changed, 76 insertions, 7 deletions
diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp
index 479b6bc..8a0354d 100644
--- a/llvm/lib/ProfileData/InstrProfReader.cpp
+++ b/llvm/lib/ProfileData/InstrProfReader.cpp
@@ -206,15 +206,21 @@ std::error_code RawInstrProfReader<IntPtrT>::readHeader(
CountersDelta = swap(Header.CountersDelta);
NamesDelta = swap(Header.NamesDelta);
+ ValueDataDelta = swap(Header.ValueDataDelta);
auto DataSize = swap(Header.DataSize);
auto CountersSize = swap(Header.CountersSize);
auto NamesSize = swap(Header.NamesSize);
+ auto ValueDataSize = swap(Header.ValueDataSize);
+ ValueKindLast = swap(Header.ValueKindLast);
+
+ auto DataSizeInBytes = DataSize * sizeof(RawInstrProf::ProfileData<IntPtrT>);
+ auto PaddingSize = getNumPaddingBytes(NamesSize);
ptrdiff_t DataOffset = sizeof(RawInstrProf::Header);
- ptrdiff_t CountersOffset =
- DataOffset + sizeof(RawInstrProf::ProfileData<IntPtrT>) * DataSize;
+ ptrdiff_t CountersOffset = DataOffset + DataSizeInBytes;
ptrdiff_t NamesOffset = CountersOffset + sizeof(uint64_t) * CountersSize;
- size_t ProfileSize = NamesOffset + sizeof(char) * NamesSize;
+ ptrdiff_t ValueDataOffset = NamesOffset + NamesSize + PaddingSize;
+ size_t ProfileSize = ValueDataOffset + ValueDataSize;
auto *Start = reinterpret_cast<const char *>(&Header);
if (Start + ProfileSize > DataBuffer->getBufferEnd())
@@ -225,8 +231,23 @@ std::error_code RawInstrProfReader<IntPtrT>::readHeader(
DataEnd = Data + DataSize;
CountersStart = reinterpret_cast<const uint64_t *>(Start + CountersOffset);
NamesStart = Start + NamesOffset;
+ ValueDataStart = reinterpret_cast<const uint8_t*>(Start + ValueDataOffset);
ProfileEnd = Start + ProfileSize;
+ FunctionPtrToNameMap.clear();
+ for (const RawInstrProf::ProfileData<IntPtrT> *I = Data; I != DataEnd; ++I) {
+ const IntPtrT FPtr = swap(I->FunctionPointer);
+ if (!FPtr)
+ continue;
+ StringRef FunctionName(getName(I->NamePtr), swap(I->NameSize));
+ const char* NameEntryPtr = StringTable.insertString(FunctionName);
+ FunctionPtrToNameMap.push_back(std::pair<const IntPtrT, const char*>
+ (FPtr, NameEntryPtr));
+ }
+ std::sort(FunctionPtrToNameMap.begin(), FunctionPtrToNameMap.end(), less_first());
+ FunctionPtrToNameMap.erase(std::unique(FunctionPtrToNameMap.begin(),
+ FunctionPtrToNameMap.end()),
+ FunctionPtrToNameMap.end());
return success();
}
@@ -234,9 +255,8 @@ template <class IntPtrT>
std::error_code RawInstrProfReader<IntPtrT>::readName(InstrProfRecord &Record) {
Record.Name = StringRef(getName(Data->NamePtr), swap(Data->NameSize));
if (Record.Name.data() < NamesStart ||
- Record.Name.data() + Record.Name.size() > DataBuffer->getBufferEnd())
+ Record.Name.data() + Record.Name.size() > (char*)ValueDataStart)
return error(instrprof_error::malformed);
-
return success();
}
@@ -275,8 +295,54 @@ std::error_code RawInstrProfReader<IntPtrT>::readRawCounts(
}
template <class IntPtrT>
-std::error_code
-RawInstrProfReader<IntPtrT>::readNextRecord(InstrProfRecord &Record) {
+std::error_code RawInstrProfReader<IntPtrT>::readValueData(
+ InstrProfRecord &Record) {
+
+ Record.clearValueData();
+ if (!Data->Values || (ValueDataDelta == 0))
+ return success();
+
+ // Read value data.
+ uint64_t NumVSites = 0;
+ for (uint32_t Kind = IPVK_First; Kind <= ValueKindLast; ++Kind)
+ NumVSites += swap(Data->NumValueSites[Kind]);
+ NumVSites += getNumPaddingBytes(NumVSites);
+
+ auto VDataCounts = makeArrayRef(getValueDataCounts(Data->Values), NumVSites);
+ // Check bounds.
+ if (VDataCounts.data() < ValueDataStart ||
+ VDataCounts.data() + VDataCounts.size() > (const uint8_t *)ProfileEnd)
+ return error(instrprof_error::malformed);
+
+ const InstrProfValueData *VDataPtr =
+ getValueData(swap(Data->Values) + NumVSites);
+ for (uint32_t Kind = IPVK_First; Kind <= ValueKindLast; ++Kind) {
+ NumVSites = swap(Data->NumValueSites[Kind]);
+ Record.reserveSites(Kind, NumVSites);
+ for (uint32_t VSite = 0; VSite < NumVSites; ++VSite) {
+
+ uint32_t VDataCount = VDataCounts[VSite];
+ if ((const char *)(VDataPtr + VDataCount) > ProfileEnd)
+ return error(instrprof_error::malformed);
+
+ std::vector<InstrProfValueData> CurrentValues;
+ CurrentValues.reserve(VDataCount);
+ for (uint32_t VIndex = 0; VIndex < VDataCount; ++VIndex) {
+ uint64_t TargetValue = swap(VDataPtr->Value);
+ uint64_t Count = swap(VDataPtr->Count);
+ CurrentValues.push_back({TargetValue, Count});
+ ++VDataPtr;
+ }
+ Record.addValueData(Kind, VSite, CurrentValues.data(),
+ VDataCount, &FunctionPtrToNameMap);
+ }
+ }
+ return success();
+}
+
+template <class IntPtrT>
+std::error_code RawInstrProfReader<IntPtrT>::readNextRecord(
+ InstrProfRecord &Record) {
if (atEnd())
if (std::error_code EC = readNextHeader(ProfileEnd))
return EC;
@@ -293,6 +359,9 @@ RawInstrProfReader<IntPtrT>::readNextRecord(InstrProfRecord &Record) {
if (std::error_code EC = readRawCounts(Record))
return EC;
+ // Read value data and set Record.
+ if (std::error_code EC = readValueData(Record)) return EC;
+
// Iterate.
advanceData();
return success();