From d89494bf0312145ad18320eab794b89b300f64e7 Mon Sep 17 00:00:00 2001 From: Xinliang David Li Date: Tue, 1 Dec 2015 20:26:26 +0000 Subject: [PATCH] [PGO] Add support for reading multiple versions of indexed profile format profile data Profile readers using incompatible on-disk hash table format can now share the same implementation and interfaces. Differential Revision: http://reviews.llvm.org/D15100 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254458 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ProfileData/InstrProfReader.h | 64 +++++++++++++--------- include/llvm/Support/OnDiskHashTable.h | 7 ++- lib/ProfileData/InstrProfReader.cpp | 49 +++++++++-------- 3 files changed, 70 insertions(+), 50 deletions(-) diff --git a/include/llvm/ProfileData/InstrProfReader.h b/include/llvm/ProfileData/InstrProfReader.h index e0a93cec320..49233366e16 100644 --- a/include/llvm/ProfileData/InstrProfReader.h +++ b/include/llvm/ProfileData/InstrProfReader.h @@ -259,36 +259,50 @@ public: } }; -class InstrProfReaderIndex { - private: - typedef OnDiskIterableChainedHashTable IndexType; +struct InstrProfReaderIndexBase { + // Read all the profile records with the same key pointed to the current + // iterator. + virtual std::error_code getRecords(ArrayRef &Data) = 0; + // Read all the profile records with the key equal to FuncName + virtual std::error_code getRecords(StringRef FuncName, + ArrayRef &Data) = 0; + virtual void advanceToNextKey() = 0; + virtual bool atEnd() const = 0; + virtual void setValueProfDataEndianness(support::endianness Endianness) = 0; + virtual ~InstrProfReaderIndexBase() {} +}; + +typedef OnDiskIterableChainedHashTable + OnDiskHashTableImplV3; - std::unique_ptr Index; - IndexType::data_iterator RecordIterator; +template +class InstrProfReaderIndex : public InstrProfReaderIndexBase { + +private: + std::unique_ptr HashTable; + typename HashTableImpl::data_iterator RecordIterator; uint64_t FormatVersion; // String table for holding a unique copy of all the strings in the profile. InstrProfStringTable StringTable; - public: - InstrProfReaderIndex() : Index(nullptr) {} - void Init(const unsigned char *Buckets, const unsigned char *const Payload, - const unsigned char *const Base, IndexedInstrProf::HashT HashType, - uint64_t Version); +public: + InstrProfReaderIndex(const unsigned char *Buckets, + const unsigned char *const Payload, + const unsigned char *const Base, + IndexedInstrProf::HashT HashType, uint64_t Version); - // Read all the pofile records with the same key pointed to the current - // iterator. - std::error_code getRecords(ArrayRef &Data); - // Read all the profile records with the key equal to FuncName + std::error_code getRecords(ArrayRef &Data) override; std::error_code getRecords(StringRef FuncName, - ArrayRef &Data); - - void advanceToNextKey() { RecordIterator++; } - bool atEnd() const { return RecordIterator == Index->data_end(); } - // Used for testing purpose only. - void setValueProfDataEndianness(support::endianness Endianness) { - Index->getInfoObj().setValueProfDataEndianness(Endianness); + ArrayRef &Data) override; + void advanceToNextKey() override { RecordIterator++; } + bool atEnd() const override { + return RecordIterator == HashTable->data_end(); + } + void setValueProfDataEndianness(support::endianness Endianness) override { + HashTable->getInfoObj().setValueProfDataEndianness(Endianness); } + ~InstrProfReaderIndex() override {} }; /// Reader for the indexed binary instrprof format. @@ -297,16 +311,16 @@ private: /// The profile data file contents. std::unique_ptr DataBuffer; /// The index into the profile data. - InstrProfReaderIndex Index; + std::unique_ptr Index; /// The maximal execution count among all functions. uint64_t MaxFunctionCount; IndexedInstrProfReader(const IndexedInstrProfReader &) = delete; IndexedInstrProfReader &operator=(const IndexedInstrProfReader &) = delete; - public: +public: IndexedInstrProfReader(std::unique_ptr DataBuffer) - : DataBuffer(std::move(DataBuffer)), Index() {} + : DataBuffer(std::move(DataBuffer)), Index(nullptr) {} /// Return true if the given buffer is in an indexed instrprof format. static bool hasFormat(const MemoryBuffer &DataBuffer); @@ -337,7 +351,7 @@ private: // Used for testing purpose only. void setValueProfDataEndianness(support::endianness Endianness) { - Index.setValueProfDataEndianness(Endianness); + Index->setValueProfDataEndianness(Endianness); } }; diff --git a/include/llvm/Support/OnDiskHashTable.h b/include/llvm/Support/OnDiskHashTable.h index c47134f46c8..ac978d4c242 100644 --- a/include/llvm/Support/OnDiskHashTable.h +++ b/include/llvm/Support/OnDiskHashTable.h @@ -263,11 +263,12 @@ template class OnDiskChainedHashTable { Info InfoObj; public: + typedef Info InfoType; typedef typename Info::internal_key_type internal_key_type; typedef typename Info::external_key_type external_key_type; - typedef typename Info::data_type data_type; - typedef typename Info::hash_value_type hash_value_type; - typedef typename Info::offset_type offset_type; + typedef typename Info::data_type data_type; + typedef typename Info::hash_value_type hash_value_type; + typedef typename Info::offset_type offset_type; OnDiskChainedHashTable(offset_type NumBuckets, offset_type NumEntries, const unsigned char *Buckets, diff --git a/lib/ProfileData/InstrProfReader.cpp b/lib/ProfileData/InstrProfReader.cpp index e4348b19ac0..cfc96873980 100644 --- a/lib/ProfileData/InstrProfReader.cpp +++ b/lib/ProfileData/InstrProfReader.cpp @@ -441,11 +441,11 @@ data_type InstrProfLookupTrait::ReadData(StringRef K, const unsigned char *D, return DataBuffer; } -std::error_code -InstrProfReaderIndex::getRecords(StringRef FuncName, - ArrayRef &Data) { - auto Iter = Index->find(FuncName); - if (Iter == Index->end()) +template +std::error_code InstrProfReaderIndex::getRecords( + StringRef FuncName, ArrayRef &Data) { + auto Iter = HashTable->find(FuncName); + if (Iter == HashTable->end()) return instrprof_error::unknown_function; Data = (*Iter); @@ -455,9 +455,11 @@ InstrProfReaderIndex::getRecords(StringRef FuncName, return instrprof_error::success; } -std::error_code InstrProfReaderIndex::getRecords( +template +std::error_code InstrProfReaderIndex::getRecords( ArrayRef &Data) { - if (atEnd()) return instrprof_error::eof; + if (atEnd()) + return instrprof_error::eof; Data = *RecordIterator; @@ -466,25 +468,26 @@ std::error_code InstrProfReaderIndex::getRecords( return instrprof_error::success; } -void InstrProfReaderIndex::Init(const unsigned char *Buckets, - const unsigned char *const Payload, - const unsigned char *const Base, - IndexedInstrProf::HashT HashType, - uint64_t Version) { +template +InstrProfReaderIndex::InstrProfReaderIndex( + const unsigned char *Buckets, const unsigned char *const Payload, + const unsigned char *const Base, IndexedInstrProf::HashT HashType, + uint64_t Version) { FormatVersion = Version; - Index.reset(IndexType::Create(Buckets, Payload, Base, - InstrProfLookupTrait(HashType, Version))); + HashTable.reset(HashTableImpl::Create( + Buckets, Payload, Base, + typename HashTableImpl::InfoType(HashType, Version))); // Form the map of hash values to const char* keys in profiling data. std::vector> HashKeys; - for (auto Key : Index->keys()) { + for (auto Key : HashTable->keys()) { const char *KeyTableRef = StringTable.insertString(Key); HashKeys.push_back(std::make_pair(ComputeHash(HashType, Key), KeyTableRef)); } std::sort(HashKeys.begin(), HashKeys.end(), less_first()); HashKeys.erase(std::unique(HashKeys.begin(), HashKeys.end()), HashKeys.end()); // Set the hash key map for the InstrLookupTrait - Index->getInfoObj().setHashKeys(std::move(HashKeys)); - RecordIterator = Index->data_begin(); + HashTable->getInfoObj().setHashKeys(std::move(HashKeys)); + RecordIterator = HashTable->data_begin(); } bool IndexedInstrProfReader::hasFormat(const MemoryBuffer &DataBuffer) { @@ -532,8 +535,10 @@ std::error_code IndexedInstrProfReader::readHeader() { uint64_t HashOffset = endian::byte_swap(Header->HashOffset); // The rest of the file is an on disk hash table. - Index.Init(Start + HashOffset, Cur, Start, HashType, FormatVersion); - + InstrProfReaderIndexBase *IndexPtr = nullptr; + IndexPtr = new InstrProfReaderIndex( + Start + HashOffset, Cur, Start, HashType, FormatVersion); + Index.reset(IndexPtr); return success(); } @@ -541,7 +546,7 @@ ErrorOr IndexedInstrProfReader::getInstrProfRecord(StringRef FuncName, uint64_t FuncHash) { ArrayRef Data; - std::error_code EC = Index.getRecords(FuncName, Data); + std::error_code EC = Index->getRecords(FuncName, Data); if (EC != instrprof_error::success) return EC; // Found it. Look for counters with the right hash. @@ -571,13 +576,13 @@ std::error_code IndexedInstrProfReader::readNextRecord( ArrayRef Data; - std::error_code EC = Index.getRecords(Data); + std::error_code EC = Index->getRecords(Data); if (EC != instrprof_error::success) return error(EC); Record = Data[RecordIndex++]; if (RecordIndex >= Data.size()) { - Index.advanceToNextKey(); + Index->advanceToNextKey(); RecordIndex = 0; } return success(); -- 2.34.1