From a0c0857e7a2398237d00a13ad9ac7078c0148578 Mon Sep 17 00:00:00 2001 From: Wei Mi Date: Mon, 11 Jun 2018 22:40:43 +0000 Subject: [SampleFDO] Add a new compact binary format for sample profile. Name table occupies a big chunk of size in current binary format sample profile. In order to reduce its size, the patch changes the sample writer/reader to save/restore MD5Hash of names in the name table. Sample annotation phase will also use MD5Hash of name to query samples accordingly. Experiment shows compact binary format can reduce the size of sample profile by 2/3 compared with binary format generally. Differential Revision: https://reviews.llvm.org/D47955 llvm-svn: 334447 --- llvm/lib/ProfileData/SampleProfReader.cpp | 92 +++++++++++++++++++++++++------ 1 file changed, 75 insertions(+), 17 deletions(-) (limited to 'llvm/lib/ProfileData/SampleProfReader.cpp') diff --git a/llvm/lib/ProfileData/SampleProfReader.cpp b/llvm/lib/ProfileData/SampleProfReader.cpp index e192b58de9c..345549e4668 100644 --- a/llvm/lib/ProfileData/SampleProfReader.cpp +++ b/llvm/lib/ProfileData/SampleProfReader.cpp @@ -319,16 +319,33 @@ ErrorOr SampleProfileReaderBinary::readString() { return Str; } -ErrorOr SampleProfileReaderBinary::readStringFromTable() { +template +inline ErrorOr SampleProfileReaderBinary::readStringIndex(T &Table) { std::error_code EC; auto Idx = readNumber(); if (std::error_code EC = Idx.getError()) return EC; - if (*Idx >= NameTable.size()) + if (*Idx >= Table.size()) return sampleprof_error::truncated_name_table; + return *Idx; +} + +ErrorOr SampleProfileReaderRawBinary::readStringFromTable() { + auto Idx = readStringIndex(NameTable); + if (std::error_code EC = Idx.getError()) + return EC; + return NameTable[*Idx]; } +ErrorOr SampleProfileReaderCompactBinary::readStringFromTable() { + auto Idx = readStringIndex(NameTable); + if (std::error_code EC = Idx.getError()) + return EC; + + return StringRef(NameTable[*Idx]); +} + std::error_code SampleProfileReaderBinary::readProfile(FunctionSamples &FProfile) { auto NumSamples = readNumber(); @@ -429,6 +446,48 @@ std::error_code SampleProfileReaderBinary::read() { return sampleprof_error::success; } +std::error_code SampleProfileReaderRawBinary::verifySPMagic(uint64_t Magic) { + if (Magic == SPMagic()) + return sampleprof_error::success; + return sampleprof_error::bad_magic; +} + +std::error_code +SampleProfileReaderCompactBinary::verifySPMagic(uint64_t Magic) { + if (Magic == SPMagic(SPF_Compact_Binary)) + return sampleprof_error::success; + return sampleprof_error::bad_magic; +} + +std::error_code SampleProfileReaderRawBinary::readNameTable() { + auto Size = readNumber(); + if (std::error_code EC = Size.getError()) + return EC; + NameTable.reserve(*Size); + for (uint32_t I = 0; I < *Size; ++I) { + auto Name(readString()); + if (std::error_code EC = Name.getError()) + return EC; + NameTable.push_back(*Name); + } + + return sampleprof_error::success; +} + +std::error_code SampleProfileReaderCompactBinary::readNameTable() { + auto Size = readNumber(); + if (std::error_code EC = Size.getError()) + return EC; + NameTable.reserve(*Size); + for (uint32_t I = 0; I < *Size; ++I) { + auto FID = readNumber(); + if (std::error_code EC = FID.getError()) + return EC; + NameTable.push_back(std::to_string(*FID)); + } + return sampleprof_error::success; +} + std::error_code SampleProfileReaderBinary::readHeader() { Data = reinterpret_cast(Buffer->getBufferStart()); End = Data + Buffer->getBufferSize(); @@ -437,7 +496,7 @@ std::error_code SampleProfileReaderBinary::readHeader() { auto Magic = readNumber(); if (std::error_code EC = Magic.getError()) return EC; - else if (*Magic != SPMagic()) + else if (std::error_code EC = verifySPMagic(*Magic)) return sampleprof_error::bad_magic; // Read the version number. @@ -450,18 +509,8 @@ std::error_code SampleProfileReaderBinary::readHeader() { if (std::error_code EC = readSummary()) return EC; - // Read the name table. - auto Size = readNumber(); - if (std::error_code EC = Size.getError()) + if (std::error_code EC = readNameTable()) return EC; - NameTable.reserve(*Size); - for (uint32_t I = 0; I < *Size; ++I) { - auto Name(readString()); - if (std::error_code EC = Name.getError()) - return EC; - NameTable.push_back(*Name); - } - return sampleprof_error::success; } @@ -521,13 +570,20 @@ std::error_code SampleProfileReaderBinary::readSummary() { return sampleprof_error::success; } -bool SampleProfileReaderBinary::hasFormat(const MemoryBuffer &Buffer) { +bool SampleProfileReaderRawBinary::hasFormat(const MemoryBuffer &Buffer) { const uint8_t *Data = reinterpret_cast(Buffer.getBufferStart()); uint64_t Magic = decodeULEB128(Data); return Magic == SPMagic(); } +bool SampleProfileReaderCompactBinary::hasFormat(const MemoryBuffer &Buffer) { + const uint8_t *Data = + reinterpret_cast(Buffer.getBufferStart()); + uint64_t Magic = decodeULEB128(Data); + return Magic == SPMagic(SPF_Compact_Binary); +} + std::error_code SampleProfileReaderGCC::skipNextWord() { uint32_t dummy; if (!GcovBuffer.readInt(dummy)) @@ -813,8 +869,10 @@ SampleProfileReader::create(const Twine &Filename, LLVMContext &C) { ErrorOr> SampleProfileReader::create(std::unique_ptr &B, LLVMContext &C) { std::unique_ptr Reader; - if (SampleProfileReaderBinary::hasFormat(*B)) - Reader.reset(new SampleProfileReaderBinary(std::move(B), C)); + if (SampleProfileReaderRawBinary::hasFormat(*B)) + Reader.reset(new SampleProfileReaderRawBinary(std::move(B), C)); + else if (SampleProfileReaderCompactBinary::hasFormat(*B)) + Reader.reset(new SampleProfileReaderCompactBinary(std::move(B), C)); else if (SampleProfileReaderGCC::hasFormat(*B)) Reader.reset(new SampleProfileReaderGCC(std::move(B), C)); else if (SampleProfileReaderText::hasFormat(*B)) -- cgit v1.2.3