LLVM: include/llvm/ADT/ConcurrentHashtable.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9#ifndef LLVM_ADT_CONCURRENTHASHTABLE_H
10#define LLVM_ADT_CONCURRENTHASHTABLE_H
11
16#include "llvm/Config/llvm-config.h"
22#include
23#include
24#include
25#include
26#include
27
28namespace llvm {
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74template <typename KeyTy, typename KeyDataTy, typename AllocatorTy>
76public:
77
81
82
86
87
88 static inline const KeyTy &getKey(const KeyDataTy &KeyData) {
89 return KeyData.getKey();
90 }
91
92
96};
97
98template <typename KeyTy, typename KeyDataTy, typename AllocatorTy,
99 typename Info =
100 ConcurrentHashTableInfoByPtr<KeyTy, KeyDataTy, AllocatorTy>>
102public:
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");
111
112
113 uint64_t EstimatedNumberOfBuckets = ThreadsNum;
114 if (ThreadsNum > 1) {
115 EstimatedNumberOfBuckets *= InitialNumberOfBuckets;
116 EstimatedNumberOfBuckets *= std::max(
117 1,
119 2);
120 }
121 EstimatedNumberOfBuckets = PowerOf2Ceil(EstimatedNumberOfBuckets);
123 std::min(EstimatedNumberOfBuckets, (uint64_t)(1Ull << 31));
124
125
127
131
132
136
139
143 }
144
145
147
150
151
152
153 MaxBucketSize = 1Ull << (std::min((size_t)31, LeadingZerosNumber));
154
155
157 }
158
166
167
168
169
170
171 std::pair<KeyDataTy *, bool> insert(const KeyTy &NewValue) {
172
173 uint64_t Hash = Info::getHashValue(NewValue);
176
177#if LLVM_ENABLE_THREADS
178
179 std::scoped_lockstd::mutex Lock(CurBucket.Guard);
180#endif
181
185
186 while (true) {
187 uint32_t CurEntryHashBits = BucketHashes[CurEntryIdx];
188
189 if (CurEntryHashBits == 0 && BucketEntries[CurEntryIdx] == nullptr) {
190
192 BucketEntries[CurEntryIdx] = NewData;
193 BucketHashes[CurEntryIdx] = ExtHashBits;
194
197 return {NewData, true};
198 }
199
200 if (CurEntryHashBits == ExtHashBits) {
201
202 KeyDataTy *EntryData = BucketEntries[CurEntryIdx];
203 if (Info::isEqual(Info::getKey(*EntryData), NewValue)) {
204
205 return {EntryData, false};
206 }
207 }
208
209 CurEntryIdx++;
210 CurEntryIdx &= (CurBucket.Size - 1);
211 }
212
214 return {};
215 }
216
217
219 OS << "\n--- HashTable statistic:\n";
222
223 uint64_t NumberOfNonEmptyBuckets = 0;
224 uint64_t NumberOfEntriesPlusEmpty = 0;
225 uint64_t OverallNumberOfEntries = 0;
227
229
230
233
234 BucketSizesMap[CurBucket.Size]++;
235
237 NumberOfNonEmptyBuckets++;
238 NumberOfEntriesPlusEmpty += CurBucket.Size;
240 OverallSize +=
242 }
243
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;
248
249 std::stringstream stream;
250 stream << std::fixed << std::setprecision(2)
251 << ((float)OverallNumberOfEntries / (float)NumberOfEntriesPlusEmpty);
252 std::string str = stream.str();
253
254 OS << "\nLoad factor = " << str;
255 OS << "\nOverall allocated size = " << OverallSize;
256 }
257
258protected:
261
264
265
268
269
271
272
274
275
277
278
280
281#if LLVM_ENABLE_THREADS
282
283 std::mutex Guard;
284#endif
285 };
286
287
289 assert((CurBucket.Size > 0) && "Uninitialised bucket");
291 return;
292
295
296 uint32_t NewBucketSize = CurBucket.Size << 1;
297 assert((NewBucketSize <= MaxBucketSize) && "New bucket size is too big");
298 assert((CurBucket.Size < NewBucketSize) &&
299 "New bucket size less than size of current bucket");
300
301
304
305
307 memset(DestHashes, 0, sizeof(ExtHashBitsTy) * NewBucketSize);
308
310 memset(DestEntries, 0, sizeof(EntryDataTy) * NewBucketSize);
311
312
313 for (uint32_t CurSrcEntryIdx = 0; CurSrcEntryIdx < CurBucket.Size;
314 CurSrcEntryIdx++) {
315 uint32_t CurSrcEntryHashBits = SrcHashes[CurSrcEntryIdx];
316
317
318 if (CurSrcEntryHashBits == 0 && SrcEntries[CurSrcEntryIdx] == nullptr)
319 continue;
320
322
323
324 while (true) {
325 uint32_t CurDestEntryHashBits = DestHashes[StartDestIdx];
326
327 if (CurDestEntryHashBits == 0 && DestEntries[StartDestIdx] == nullptr) {
328
329 DestHashes[StartDestIdx] = CurSrcEntryHashBits;
330 DestEntries[StartDestIdx] = SrcEntries[CurSrcEntryIdx];
331 break;
332 }
333
334 StartDestIdx++;
335 StartDestIdx = StartDestIdx & (NewBucketSize - 1);
336 }
337 }
338
339
340 CurBucket.Hashes = DestHashes;
341 CurBucket.Entries = DestEntries;
342 CurBucket.Size = NewBucketSize;
343
344
345 delete[] SrcHashes;
346 delete[] SrcEntries;
347 }
348
350
354
356 assert((BucketSize > 0) && "Empty bucket");
357
358 return ExtHashBits & (BucketSize - 1);
359 }
360
361
363
364
366
367
369
370
372
373
375
376
378
379
381
382
384};
385
386}
387
388#endif
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.
Definition ConcurrentHashtable.h:171
uint32_t getStartIdx(uint32_t ExtHashBits, uint32_t BucketSize)
Definition ConcurrentHashtable.h:355
virtual ~ConcurrentHashTableByPtr()
Definition ConcurrentHashtable.h:159
uint64_t HashBitsNum
Definition ConcurrentHashtable.h:362
std::unique_ptr< Bucket[]> BucketsArray
Definition ConcurrentHashtable.h:380
uint32_t MaxBucketSize
Definition ConcurrentHashtable.h:371
KeyDataTy * EntryDataTy
Definition ConcurrentHashtable.h:260
EntryDataTy * DataPtr
Definition ConcurrentHashtable.h:263
ExtHashBitsTy * HashesPtr
Definition ConcurrentHashtable.h:262
uint64_t ExtHashMask
Definition ConcurrentHashtable.h:368
uint32_t getBucketIdx(hash_code Hash)
Definition ConcurrentHashtable.h:349
uint64_t HashMask
Definition ConcurrentHashtable.h:365
uint32_t ExtHashBitsTy
Definition ConcurrentHashtable.h:259
uint32_t NumberOfBuckets
Definition ConcurrentHashtable.h:377
void printStatistic(raw_ostream &OS)
Print information about current state of hash table structures.
Definition ConcurrentHashtable.h:218
void RehashBucket(Bucket &CurBucket)
Definition ConcurrentHashtable.h:288
uint32_t InitialBucketSize
Definition ConcurrentHashtable.h:374
uint32_t getExtHashBits(uint64_t Hash)
Definition ConcurrentHashtable.h:351
ConcurrentHashTableByPtr(AllocatorTy &Allocator, uint64_t EstimatedSize=100000, size_t ThreadsNum=parallel::strategy.compute_thread_count(), size_t InitialNumberOfBuckets=128)
Definition ConcurrentHashtable.h:103
AllocatorTy & MultiThreadAllocator
Definition ConcurrentHashtable.h:383
ConcurrentHashTable - is a resizeable concurrent hashtable.
Definition ConcurrentHashtable.h:75
static KeyDataTy * create(const KeyTy &Key, AllocatorTy &Allocator)
Definition ConcurrentHashtable.h:93
static const KeyTy & getKey(const KeyDataTy &KeyData)
Definition ConcurrentHashtable.h:88
static bool isEqual(const KeyTy &LHS, const KeyTy &RHS)
Definition ConcurrentHashtable.h:83
static uint64_t getHashValue(const KeyTy &Key)
Definition ConcurrentHashtable.h:78
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
DataPtr Entries
Definition ConcurrentHashtable.h:279
HashesPtr Hashes
Definition ConcurrentHashtable.h:276
uint32_t Size
Definition ConcurrentHashtable.h:270
uint32_t NumberOfEntries
Definition ConcurrentHashtable.h:273