Index: llvm/trunk/include/llvm/ProfileData/InstrProfReader.h =================================================================== --- llvm/trunk/include/llvm/ProfileData/InstrProfReader.h +++ llvm/trunk/include/llvm/ProfileData/InstrProfReader.h @@ -259,36 +259,50 @@ } }; -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 @@ /// 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 @@ // Used for testing purpose only. void setValueProfDataEndianness(support::endianness Endianness) { - Index.setValueProfDataEndianness(Endianness); + Index->setValueProfDataEndianness(Endianness); } }; Index: llvm/trunk/include/llvm/Support/OnDiskHashTable.h =================================================================== --- llvm/trunk/include/llvm/Support/OnDiskHashTable.h +++ llvm/trunk/include/llvm/Support/OnDiskHashTable.h @@ -263,11 +263,12 @@ 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, Index: llvm/trunk/lib/ProfileData/InstrProfReader.cpp =================================================================== --- llvm/trunk/lib/ProfileData/InstrProfReader.cpp +++ llvm/trunk/lib/ProfileData/InstrProfReader.cpp @@ -441,11 +441,11 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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();