LLVM 24.0.0git
DenseMap.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "llvm/ADT/DenseMap.h"
11#include <cstring>
12
13using namespace llvm;
14using namespace llvm::densemap;
15using namespace llvm::densemap::detail;
16
17// A nonzero FixedSize turns the bucket copy into a couple of stores.
18template <size_t FixedSize, bool InlinePtrHash>
19static void rehashLoop(void *DstBuckets, UsedT *DstUsed, unsigned Mask,
20 const void *SrcBuckets, const UsedT *SrcUsed,
21 unsigned SrcNumBuckets, size_t RuntimeSize,
22 BucketHasher Hasher) {
23 const size_t BucketSize = FixedSize ? FixedSize : RuntimeSize;
24 char *Dst = static_cast<char *>(DstBuckets);
25 const char *Src = static_cast<const char *>(SrcBuckets);
26 forEachUsed(SrcUsed, SrcNumBuckets, [&](unsigned I) {
27 const char *SrcBucket = Src + static_cast<size_t>(I) * BucketSize;
28 unsigned Hash;
29 if constexpr (InlinePtrHash) {
30 void *Key;
31 std::memcpy(&Key, SrcBucket, sizeof(Key));
33 } else {
34 Hash = Hasher(SrcBucket);
35 }
36 unsigned BucketNo = Hash & Mask;
37 while (used(DstUsed, BucketNo))
38 BucketNo = (BucketNo + 1) & Mask;
39 std::memcpy(Dst + static_cast<size_t>(BucketNo) * BucketSize, SrcBucket,
40 BucketSize);
41 setUsed(DstUsed, BucketNo);
42 });
43}
44
45template <bool InlinePtrHash>
46static void rehashBySize(void *Dst, UsedT *DstUsed, unsigned Mask,
47 const void *Src, const UsedT *SrcUsed,
48 unsigned SrcNumBuckets, size_t BucketSize,
49 BucketHasher Hasher) {
50 // The bucket sizes of 95% of the grow instantiations in an LLVM build.
51 switch (BucketSize) {
52#define REHASH_CASE(N) \
53 case N: \
54 return rehashLoop<N, InlinePtrHash>(Dst, DstUsed, Mask, Src, SrcUsed, \
55 SrcNumBuckets, BucketSize, Hasher);
58 REHASH_CASE(12)
59 REHASH_CASE(16)
60 REHASH_CASE(24)
61 REHASH_CASE(32)
62 REHASH_CASE(40)
63 REHASH_CASE(48)
64#undef REHASH_CASE
65 default:
66 return rehashLoop<0, InlinePtrHash>(Dst, DstUsed, Mask, Src, SrcUsed,
67 SrcNumBuckets, BucketSize, Hasher);
68 }
69}
70
72 unsigned DstNumBuckets,
73 const void *Src, const UsedT *SrcUsed,
74 unsigned SrcNumBuckets,
75 size_t BucketSize,
76 BucketHasher Hasher) {
77 const unsigned Mask = DstNumBuckets - 1;
78 if (!Hasher)
79 return rehashBySize<true>(Dst, DstUsed, Mask, Src, SrcUsed, SrcNumBuckets,
80 BucketSize, Hasher);
81 return rehashBySize<false>(Dst, DstUsed, Mask, Src, SrcUsed, SrcNumBuckets,
82 BucketSize, Hasher);
83}
84
85void *densemap::detail::growRelocatable(void *OldBuckets, const UsedT *OldUsed,
86 unsigned OldNumBuckets,
87 unsigned NewNumBuckets,
88 size_t BucketSize, size_t Align,
89 BucketHasher Hasher, bool FreeOld) {
90 void *Storage = allocate_buffer(allocBytes(BucketSize, NewNumBuckets), Align);
91 UsedT *NewUsed = usedFor(Storage, BucketSize, NewNumBuckets);
92 clearUsed(NewUsed, NewNumBuckets);
93 if (OldNumBuckets) {
94 rehashRelocatable(Storage, NewUsed, NewNumBuckets, OldBuckets, OldUsed,
95 OldNumBuckets, BucketSize, Hasher);
96 if (FreeOld)
97 deallocate_buffer(OldBuckets, allocBytes(BucketSize, OldNumBuckets),
98 Align);
99 }
100 return Storage;
101}
#define REHASH_CASE(N)
static void rehashLoop(void *DstBuckets, UsedT *DstUsed, unsigned Mask, const void *SrcBuckets, const UsedT *SrcUsed, unsigned SrcNumBuckets, size_t RuntimeSize, BucketHasher Hasher)
Definition DenseMap.cpp:19
static void rehashBySize(void *Dst, UsedT *DstUsed, unsigned Mask, const void *Src, const UsedT *SrcUsed, unsigned SrcNumBuckets, size_t BucketSize, BucketHasher Hasher)
Definition DenseMap.cpp:46
This file defines the DenseMap class.
#define I(x, y, z)
Definition MD5.cpp:57
This file defines counterparts of C library allocation functions defined in the namespace 'std'.
void setUsed(UsedT *U, size_t I)
Definition DenseMap.h:110
UsedT * usedFor(void *Buckets, size_t BucketSize, unsigned Num)
Definition DenseMap.h:146
void clearUsed(UsedT *U, unsigned Num)
Definition DenseMap.h:114
LLVM_ATTRIBUTE_ALWAYS_INLINE void forEachUsed(const UsedT *U, unsigned N, Fn Func)
Definition DenseMap.h:122
size_t allocBytes(size_t BucketSize, unsigned Num)
Definition DenseMap.h:140
unsigned(*)(const void *Key) BucketHasher
Hashes the key, at offset 0 in a bucket.
Definition DenseMap.h:155
LLVM_ABI void * growRelocatable(void *OldBuckets, const UsedT *OldUsed, unsigned OldNumBuckets, unsigned NewNumBuckets, size_t BucketSize, size_t Align, BucketHasher Hasher, bool FreeOld)
Allocate a table of NewNumBuckets buckets and rehash the OldNumBuckets buckets at OldBuckets into it,...
Definition DenseMap.cpp:85
bool used(const UsedT *U, size_t I)
Definition DenseMap.h:107
LLVM_ABI void rehashRelocatable(void *Dst, UsedT *DstUsed, unsigned DstNumBuckets, const void *Src, const UsedT *SrcUsed, unsigned SrcNumBuckets, size_t BucketSize, BucketHasher Hasher)
Rehash the live buckets of Src into the empty Dst, which must have room for all of them.
Definition DenseMap.cpp:71
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * allocate_buffer(size_t Size, size_t Alignment)
Allocate a buffer of memory with the given size and alignment.
Definition MemAlloc.cpp:15
LLVM_ABI void deallocate_buffer(void *Ptr, size_t Size, size_t Alignment)
Deallocate a buffer of memory with the given size and alignment.
Definition MemAlloc.cpp:27
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
An information struct used to provide DenseMap with the various necessary components for a given valu...