diff options
author | Betul Buyukkurt <betulb@codeaurora.org> | 2015-11-18 18:14:55 +0000 |
---|---|---|
committer | Betul Buyukkurt <betulb@codeaurora.org> | 2015-11-18 18:14:55 +0000 |
commit | a5be9e3cfba9cc841f37881a60bf5337aac5a704 (patch) | |
tree | 2419b04d855e58baf9aec601ff633b97e40f89cc /lib/ProfileData | |
parent | 2e1334977408d524b9e96066d60fd1f6e1601144 (diff) |
[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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253484 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ProfileData')
-rw-r--r-- | lib/ProfileData/InstrProfReader.cpp | 83 |
1 files changed, 76 insertions, 7 deletions
diff --git a/lib/ProfileData/InstrProfReader.cpp b/lib/ProfileData/InstrProfReader.cpp index 479b6bc61d9..8a0354dc98c 100644 --- a/lib/ProfileData/InstrProfReader.cpp +++ b/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(); |