9#ifndef LLVM_ADT_CONCURRENTHASHTABLE_H
10#define LLVM_ADT_CONCURRENTHASHTABLE_H
16#include "llvm/Config/llvm-config.h"
74template <
typename KeyTy,
typename KeyDataTy,
typename AllocatorTy>
88 static inline const KeyTy &
getKey(
const KeyDataTy &KeyData) {
89 return KeyData.getKey();
98template <
typename KeyTy,
typename KeyDataTy,
typename AllocatorTy,
100 ConcurrentHashTableInfoByPtr<KeyTy, KeyDataTy, AllocatorTy>>
106 size_t InitialNumberOfBuckets = 128)
108 assert((ThreadsNum > 0) &&
"ThreadsNum must be greater than 0");
109 assert((InitialNumberOfBuckets > 0) &&
110 "InitialNumberOfBuckets must be greater than 0");
113 uint64_t EstimatedNumberOfBuckets = ThreadsNum;
114 if (ThreadsNum > 1) {
115 EstimatedNumberOfBuckets *= InitialNumberOfBuckets;
116 EstimatedNumberOfBuckets *= std::max(
121 EstimatedNumberOfBuckets =
PowerOf2Ceil(EstimatedNumberOfBuckets);
123 std::min(EstimatedNumberOfBuckets, (
uint64_t)(1Ull << 31));
153 MaxBucketSize = 1Ull << (std::min((
size_t)31, LeadingZerosNumber));
171 std::pair<KeyDataTy *, bool>
insert(
const KeyTy &NewValue) {
173 uint64_t Hash = Info::getHashValue(NewValue);
177#if LLVM_ENABLE_THREADS
179 std::scoped_lock<std::mutex> Lock(CurBucket.Guard);
187 uint32_t CurEntryHashBits = BucketHashes[CurEntryIdx];
189 if (CurEntryHashBits == 0 && BucketEntries[CurEntryIdx] ==
nullptr) {
192 BucketEntries[CurEntryIdx] = NewData;
193 BucketHashes[CurEntryIdx] = ExtHashBits;
197 return {NewData,
true};
200 if (CurEntryHashBits == ExtHashBits) {
202 KeyDataTy *EntryData = BucketEntries[CurEntryIdx];
203 if (Info::isEqual(Info::getKey(*EntryData), NewValue)) {
205 return {EntryData,
false};
210 CurEntryIdx &= (CurBucket.
Size - 1);
219 OS <<
"\n--- HashTable statistic:\n";
223 uint64_t NumberOfNonEmptyBuckets = 0;
224 uint64_t NumberOfEntriesPlusEmpty = 0;
225 uint64_t OverallNumberOfEntries = 0;
234 BucketSizesMap[CurBucket.
Size]++;
237 NumberOfNonEmptyBuckets++;
238 NumberOfEntriesPlusEmpty += CurBucket.
Size;
244 OS <<
"\nOverall number of entries = " << OverallNumberOfEntries;
245 OS <<
"\nOverall number of non empty buckets = " << NumberOfNonEmptyBuckets;
246 for (
auto [
Size,
Count] : BucketSizesMap)
247 OS <<
"\n Number of buckets with size " <<
Size <<
": " <<
Count;
249 std::stringstream stream;
250 stream << std::fixed << std::setprecision(2)
251 << ((float)OverallNumberOfEntries / (float)NumberOfEntriesPlusEmpty);
252 std::string str = stream.str();
254 OS <<
"\nLoad factor = " << str;
255 OS <<
"\nOverall allocated size = " << OverallSize;
281#if LLVM_ENABLE_THREADS
289 assert((CurBucket.
Size > 0) &&
"Uninitialised bucket");
299 "New bucket size less than size of current bucket");
307 memset(DestHashes, 0,
sizeof(
ExtHashBitsTy) * NewBucketSize);
310 memset(DestEntries, 0,
sizeof(
EntryDataTy) * NewBucketSize);
313 for (
uint32_t CurSrcEntryIdx = 0; CurSrcEntryIdx < CurBucket.
Size;
315 uint32_t CurSrcEntryHashBits = SrcHashes[CurSrcEntryIdx];
318 if (CurSrcEntryHashBits == 0 && SrcEntries[CurSrcEntryIdx] ==
nullptr)
325 uint32_t CurDestEntryHashBits = DestHashes[StartDestIdx];
327 if (CurDestEntryHashBits == 0 && DestEntries[StartDestIdx] ==
nullptr) {
329 DestHashes[StartDestIdx] = CurSrcEntryHashBits;
330 DestEntries[StartDestIdx] = SrcEntries[CurSrcEntryIdx];
335 StartDestIdx = StartDestIdx & (NewBucketSize - 1);
340 CurBucket.
Hashes = DestHashes;
341 CurBucket.
Entries = DestEntries;
342 CurBucket.
Size = NewBucketSize;
356 assert((BucketSize > 0) &&
"Empty bucket");
358 return ExtHashBits & (BucketSize - 1);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the BumpPtrAllocator interface.
Analysis containing CSE Info
This file defines the DenseMap class.
This file defines the SmallVector class.
std::pair< KeyDataTy *, bool > insert(const KeyTy &NewValue)
Insert new value NewValue or return already existing entry.
uint32_t getStartIdx(uint32_t ExtHashBits, uint32_t BucketSize)
virtual ~ConcurrentHashTableByPtr()
std::unique_ptr< Bucket[]> BucketsArray
ExtHashBitsTy * HashesPtr
uint32_t getBucketIdx(hash_code Hash)
void printStatistic(raw_ostream &OS)
Print information about current state of hash table structures.
void RehashBucket(Bucket &CurBucket)
uint32_t InitialBucketSize
uint32_t getExtHashBits(uint64_t Hash)
ConcurrentHashTableByPtr(AllocatorTy &Allocator, uint64_t EstimatedSize=100000, size_t ThreadsNum=parallel::strategy.compute_thread_count(), size_t InitialNumberOfBuckets=128)
AllocatorTy & MultiThreadAllocator
ConcurrentHashTable - is a resizeable concurrent hashtable.
static KeyDataTy * create(const KeyTy &Key, AllocatorTy &Allocator)
static const KeyTy & getKey(const KeyDataTy &KeyData)
static bool isEqual(const KeyTy &LHS, const KeyTy &RHS)
static uint64_t getHashValue(const KeyTy &Key)
An opaque object representing a hash code.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_ABI ThreadPoolStrategy strategy
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI uint64_t xxh3_64bits(ArrayRef< uint8_t > data)
uint64_t PowerOf2Ceil(uint64_t A)
Returns the power of two which is greater than or equal to the given value.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionAddr VTableAddr Count
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key