LLVM 22.0.0git
TypeSize.h
Go to the documentation of this file.
1//===- TypeSize.h - Wrapper around type sizes -------------------*- C++ -*-===//
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// This file provides a struct that can be used to query the size of IR types
10// which may be scalable vectors. It provides convenience operators so that
11// it can be used in much the same way as a single scalar value.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_SUPPORT_TYPESIZE_H
16#define LLVM_SUPPORT_TYPESIZE_H
17
22
23#include <cassert>
24#include <cstdint>
25#include <type_traits>
26
27namespace llvm {
28
29/// StackOffset holds a fixed and a scalable offset in bytes.
30class StackOffset {
31 int64_t Fixed = 0;
32 int64_t Scalable = 0;
33
34 StackOffset(int64_t Fixed, int64_t Scalable)
35 : Fixed(Fixed), Scalable(Scalable) {}
36
37public:
38 StackOffset() = default;
39 static StackOffset getFixed(int64_t Fixed) { return {Fixed, 0}; }
40 static StackOffset getScalable(int64_t Scalable) { return {0, Scalable}; }
41 static StackOffset get(int64_t Fixed, int64_t Scalable) {
42 return {Fixed, Scalable};
43 }
44
45 /// Returns the fixed component of the stack.
46 int64_t getFixed() const { return Fixed; }
47
48 /// Returns the scalable component of the stack.
49 int64_t getScalable() const { return Scalable; }
50
51 // Arithmetic operations.
52 StackOffset operator+(const StackOffset &RHS) const {
53 return {Fixed + RHS.Fixed, Scalable + RHS.Scalable};
54 }
55 StackOffset operator-(const StackOffset &RHS) const {
56 return {Fixed - RHS.Fixed, Scalable - RHS.Scalable};
57 }
58 StackOffset &operator+=(const StackOffset &RHS) {
59 Fixed += RHS.Fixed;
60 Scalable += RHS.Scalable;
61 return *this;
62 }
63 StackOffset &operator-=(const StackOffset &RHS) {
64 Fixed -= RHS.Fixed;
65 Scalable -= RHS.Scalable;
66 return *this;
67 }
68 StackOffset operator-() const { return {-Fixed, -Scalable}; }
69
70 // Equality comparisons.
71 bool operator==(const StackOffset &RHS) const {
72 return Fixed == RHS.Fixed && Scalable == RHS.Scalable;
73 }
74 bool operator!=(const StackOffset &RHS) const {
75 return Fixed != RHS.Fixed || Scalable != RHS.Scalable;
76 }
77
78 // The bool operator returns true iff any of the components is non zero.
79 explicit operator bool() const { return Fixed != 0 || Scalable != 0; }
80};
81
82namespace details {
83
84// Base class for ElementCount and TypeSize below.
85template <typename LeafTy, typename ValueTy> class FixedOrScalableQuantity {
86public:
87 using ScalarTy = ValueTy;
88
89protected:
91 bool Scalable = false;
92
93 constexpr FixedOrScalableQuantity() = default;
96
97 friend constexpr LeafTy &operator+=(LeafTy &LHS, const LeafTy &RHS) {
98 assert((LHS.Quantity == 0 || RHS.Quantity == 0 ||
99 LHS.Scalable == RHS.Scalable) &&
100 "Incompatible types");
101 LHS.Quantity += RHS.Quantity;
102 if (!RHS.isZero())
103 LHS.Scalable = RHS.Scalable;
104 return LHS;
105 }
106
107 friend constexpr LeafTy &operator-=(LeafTy &LHS, const LeafTy &RHS) {
108 assert((LHS.Quantity == 0 || RHS.Quantity == 0 ||
109 LHS.Scalable == RHS.Scalable) &&
110 "Incompatible types");
111 LHS.Quantity -= RHS.Quantity;
112 if (!RHS.isZero())
113 LHS.Scalable = RHS.Scalable;
114 return LHS;
115 }
116
117 friend constexpr LeafTy &operator*=(LeafTy &LHS, ScalarTy RHS) {
118 LHS.Quantity *= RHS;
119 return LHS;
120 }
121
122 friend constexpr LeafTy operator+(const LeafTy &LHS, const LeafTy &RHS) {
123 LeafTy Copy = LHS;
124 return Copy += RHS;
125 }
126
127 friend constexpr LeafTy operator-(const LeafTy &LHS, const LeafTy &RHS) {
128 LeafTy Copy = LHS;
129 return Copy -= RHS;
130 }
131
132 friend constexpr LeafTy operator*(const LeafTy &LHS, ScalarTy RHS) {
133 LeafTy Copy = LHS;
134 return Copy *= RHS;
135 }
136
137 template <typename U = ScalarTy>
138 friend constexpr std::enable_if_t<std::is_signed_v<U>, LeafTy>
139 operator-(const LeafTy &LHS) {
140 LeafTy Copy = LHS;
141 return Copy *= -1;
142 }
143
144public:
145 constexpr bool operator==(const FixedOrScalableQuantity &RHS) const {
146 return Quantity == RHS.Quantity && Scalable == RHS.Scalable;
147 }
148
149 constexpr bool operator!=(const FixedOrScalableQuantity &RHS) const {
150 return Quantity != RHS.Quantity || Scalable != RHS.Scalable;
151 }
152
153 constexpr bool isZero() const { return Quantity == 0; }
154
155 constexpr bool isNonZero() const { return Quantity != 0; }
156
157 explicit operator bool() const { return isNonZero(); }
158
159 /// Add \p RHS to the underlying quantity.
160 constexpr LeafTy getWithIncrement(ScalarTy RHS) const {
161 return LeafTy::get(Quantity + RHS, Scalable);
162 }
163
164 /// Returns the minimum value this quantity can represent.
165 constexpr ScalarTy getKnownMinValue() const { return Quantity; }
166
167 /// Returns whether the quantity is scaled by a runtime quantity (vscale).
168 constexpr bool isScalable() const { return Scalable; }
169
170 /// Returns true if the quantity is not scaled by vscale.
171 constexpr bool isFixed() const { return !Scalable; }
172
173 /// A return value of true indicates we know at compile time that the number
174 /// of elements (vscale * Min) is definitely even. However, returning false
175 /// does not guarantee that the total number of elements is odd.
176 constexpr bool isKnownEven() const { return (getKnownMinValue() & 0x1) == 0; }
177
178 /// This function tells the caller whether the element count is known at
179 /// compile time to be a multiple of the scalar value RHS.
180 constexpr bool isKnownMultipleOf(ScalarTy RHS) const {
181 return RHS != 0 && getKnownMinValue() % RHS == 0;
182 }
183
184 /// Returns whether or not the callee is known to be a multiple of RHS.
185 constexpr bool isKnownMultipleOf(const FixedOrScalableQuantity &RHS) const {
186 // x % y == 0 => x % y == 0
187 // x % y == 0 => (vscale * x) % y == 0
188 // x % y == 0 => (vscale * x) % (vscale * y) == 0
189 // but
190 // x % y == 0 !=> x % (vscale * y) == 0
191 if (!isScalable() && RHS.isScalable())
192 return false;
193 return RHS.getKnownMinValue() != 0 &&
194 getKnownMinValue() % RHS.getKnownMinValue() == 0;
195 }
196
197 // Return the minimum value with the assumption that the count is exact.
198 // Use in places where a scalable count doesn't make sense (e.g. non-vector
199 // types, or vectors in backends which don't support scalable vectors).
200 constexpr ScalarTy getFixedValue() const {
201 assert((!isScalable() || isZero()) &&
202 "Request for a fixed element count on a scalable object");
203 return getKnownMinValue();
204 }
205
206 // For some cases, quantity ordering between scalable and fixed quantity types
207 // cannot be determined at compile time, so such comparisons aren't allowed.
208 //
209 // e.g. <vscale x 2 x i16> could be bigger than <4 x i32> with a runtime
210 // vscale >= 5, equal sized with a vscale of 4, and smaller with
211 // a vscale <= 3.
212 //
213 // All the functions below make use of the fact vscale is always >= 1, which
214 // means that <vscale x 4 x i32> is guaranteed to be >= <4 x i32>, etc.
215
216 static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS,
218 if (!LHS.isScalable() || RHS.isScalable())
219 return LHS.getKnownMinValue() < RHS.getKnownMinValue();
220 return false;
221 }
222
223 static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS,
225 if (LHS.isScalable() || !RHS.isScalable())
226 return LHS.getKnownMinValue() > RHS.getKnownMinValue();
227 return false;
228 }
229
230 static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS,
232 if (!LHS.isScalable() || RHS.isScalable())
233 return LHS.getKnownMinValue() <= RHS.getKnownMinValue();
234 return false;
235 }
236
237 static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS,
239 if (LHS.isScalable() || !RHS.isScalable())
240 return LHS.getKnownMinValue() >= RHS.getKnownMinValue();
241 return false;
242 }
243
244 /// We do not provide the '/' operator here because division for polynomial
245 /// types does not work in the same way as for normal integer types. We can
246 /// only divide the minimum value (or coefficient) by RHS, which is not the
247 /// same as
248 /// (Min * Vscale) / RHS
249 /// The caller is recommended to use this function in combination with
250 /// isKnownMultipleOf(RHS), which lets the caller know if it's possible to
251 /// perform a lossless divide by RHS.
252 constexpr LeafTy divideCoefficientBy(ScalarTy RHS) const {
253 return LeafTy::get(getKnownMinValue() / RHS, isScalable());
254 }
255
256 constexpr LeafTy multiplyCoefficientBy(ScalarTy RHS) const {
257 return LeafTy::get(getKnownMinValue() * RHS, isScalable());
258 }
259
260 constexpr LeafTy coefficientNextPowerOf2() const {
261 return LeafTy::get(
263 isScalable());
264 }
265
266 /// Returns true if there exists a value X where RHS.multiplyCoefficientBy(X)
267 /// will result in a value whose quantity matches our own.
268 constexpr bool
270 return isScalable() == RHS.isScalable() &&
271 getKnownMinValue() % RHS.getKnownMinValue() == 0;
272 }
273
274 /// Returns a value X where RHS.multiplyCoefficientBy(X) will result in a
275 /// value whose quantity matches our own.
276 constexpr ScalarTy
278 assert(hasKnownScalarFactor(RHS) && "Expected RHS to be a known factor!");
279 return getKnownMinValue() / RHS.getKnownMinValue();
280 }
281
282 /// Printing function.
283 void print(raw_ostream &OS) const {
284 if (isScalable())
285 OS << "vscale x ";
286 OS << getKnownMinValue();
287 }
288};
289
290} // namespace details
291
292// Stores the number of elements for a type and whether this type is fixed
293// (N-Elements) or scalable (e.g., SVE).
294// - ElementCount::getFixed(1) : A scalar value.
295// - ElementCount::getFixed(2) : A vector type holding 2 values.
296// - ElementCount::getScalable(4) : A scalable vector type holding 4 values.
297class ElementCount
298 : public details::FixedOrScalableQuantity<ElementCount, unsigned> {
299 constexpr ElementCount(ScalarTy MinVal, bool Scalable)
301
302 constexpr ElementCount(
305
306public:
308
309 static constexpr ElementCount getFixed(ScalarTy MinVal) {
310 return ElementCount(MinVal, false);
311 }
312 static constexpr ElementCount getScalable(ScalarTy MinVal) {
313 return ElementCount(MinVal, true);
314 }
315 static constexpr ElementCount get(ScalarTy MinVal, bool Scalable) {
316 return ElementCount(MinVal, Scalable);
317 }
318
319 /// Exactly one element.
320 constexpr bool isScalar() const {
321 return !isScalable() && getKnownMinValue() == 1;
322 }
323 /// One or more elements.
324 constexpr bool isVector() const {
325 return (isScalable() && getKnownMinValue() != 0) || getKnownMinValue() > 1;
326 }
327};
328
329// Stores the size of a type. If the type is of fixed size, it will represent
330// the exact size. If the type is a scalable vector, it will represent the known
331// minimum size.
332class TypeSize : public details::FixedOrScalableQuantity<TypeSize, uint64_t> {
335
336public:
339
340 static constexpr TypeSize get(ScalarTy Quantity, bool Scalable) {
341 return TypeSize(Quantity, Scalable);
342 }
343 static constexpr TypeSize getFixed(ScalarTy ExactSize) {
344 return TypeSize(ExactSize, false);
345 }
346 static constexpr TypeSize getScalable(ScalarTy MinimumSize) {
347 return TypeSize(MinimumSize, true);
348 }
349 static constexpr TypeSize getZero() { return TypeSize(0, false); }
350
351 // All code for this class below this point is needed because of the
352 // temporary implicit conversion to uint64_t. The operator overloads are
353 // needed because otherwise the conversion of the parent class
354 // UnivariateLinearPolyBase -> TypeSize is ambiguous.
355 // TODO: Remove the implicit conversion.
356
357 // Casts to a uint64_t if this is a fixed-width size.
358 //
359 // This interface is deprecated and will be removed in a future version
360 // of LLVM in favour of upgrading uses that rely on this implicit conversion
361 // to uint64_t. Calls to functions that return a TypeSize should use the
362 // proper interfaces to TypeSize.
363 // In practice this is mostly calls to MVT/EVT::getSizeInBits().
364 //
365 // To determine how to upgrade the code:
366 //
367 // if (<algorithm works for both scalable and fixed-width vectors>)
368 // use getKnownMinValue()
369 // else if (<algorithm works only for fixed-width vectors>) {
370 // if <algorithm can be adapted for both scalable and fixed-width vectors>
371 // update the algorithm and use getKnownMinValue()
372 // else
373 // bail out early for scalable vectors and use getFixedValue()
374 // }
375 operator ScalarTy() const {
376 if (isScalable()) {
378 "Cannot implicitly convert a scalable size to a fixed-width size in "
379 "`TypeSize::operator ScalarTy()`");
380 }
381 return getFixedValue();
382 }
383
384 // Additional operators needed to avoid ambiguous parses
385 // because of the implicit conversion hack.
386 friend constexpr TypeSize operator*(const TypeSize &LHS, const int RHS) {
387 return LHS * (ScalarTy)RHS;
388 }
389 friend constexpr TypeSize operator*(const TypeSize &LHS, const unsigned RHS) {
390 return LHS * (ScalarTy)RHS;
391 }
392 friend constexpr TypeSize operator*(const TypeSize &LHS, const int64_t RHS) {
393 return LHS * (ScalarTy)RHS;
394 }
395 friend constexpr TypeSize operator*(const int LHS, const TypeSize &RHS) {
396 return RHS * LHS;
397 }
398 friend constexpr TypeSize operator*(const unsigned LHS, const TypeSize &RHS) {
399 return RHS * LHS;
400 }
401 friend constexpr TypeSize operator*(const int64_t LHS, const TypeSize &RHS) {
402 return RHS * LHS;
403 }
404 friend constexpr TypeSize operator*(const uint64_t LHS, const TypeSize &RHS) {
405 return RHS * LHS;
406 }
407};
408
409//===----------------------------------------------------------------------===//
410// Utilities
411//===----------------------------------------------------------------------===//
412
413/// Returns a TypeSize with a known minimum size that is the next integer
414/// (mod 2**64) that is greater than or equal to \p Quantity and is a multiple
415/// of \p Align. \p Align must be non-zero.
416///
417/// Similar to the alignTo functions in MathExtras.h
419 assert(Align != 0u && "Align must be non-zero");
420 return {(Size.getKnownMinValue() + Align - 1) / Align * Align,
421 Size.isScalable()};
422}
423
424/// Stream operator function for `FixedOrScalableQuantity`.
425template <typename LeafTy, typename ScalarTy>
429 PS.print(OS);
430 return OS;
431}
432
433template <> struct DenseMapInfo<ElementCount, void> {
434 static inline ElementCount getEmptyKey() {
435 return ElementCount::getScalable(~0U);
436 }
438 return ElementCount::getFixed(~0U - 1);
439 }
440 static unsigned getHashValue(const ElementCount &EltCnt) {
441 unsigned HashVal = EltCnt.getKnownMinValue() * 37U;
442 if (EltCnt.isScalable())
443 return (HashVal - 1U);
444
445 return HashVal;
446 }
447 static bool isEqual(const ElementCount &LHS, const ElementCount &RHS) {
448 return LHS == RHS;
449 }
450};
451
452} // end namespace llvm
453
454#endif // LLVM_SUPPORT_TYPESIZE_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Value * RHS
Value * LHS
constexpr bool isVector() const
One or more elements.
Definition TypeSize.h:324
constexpr ElementCount()
Definition TypeSize.h:307
static constexpr ElementCount getScalable(ScalarTy MinVal)
Definition TypeSize.h:312
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:309
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
Definition TypeSize.h:315
constexpr bool isScalar() const
Exactly one element.
Definition TypeSize.h:320
int64_t getFixed() const
Returns the fixed component of the stack.
Definition TypeSize.h:46
StackOffset operator+(const StackOffset &RHS) const
Definition TypeSize.h:52
int64_t getScalable() const
Returns the scalable component of the stack.
Definition TypeSize.h:49
StackOffset operator-() const
Definition TypeSize.h:68
bool operator!=(const StackOffset &RHS) const
Definition TypeSize.h:74
StackOffset operator-(const StackOffset &RHS) const
Definition TypeSize.h:55
bool operator==(const StackOffset &RHS) const
Definition TypeSize.h:71
StackOffset & operator-=(const StackOffset &RHS)
Definition TypeSize.h:63
static StackOffset get(int64_t Fixed, int64_t Scalable)
Definition TypeSize.h:41
StackOffset()=default
static StackOffset getScalable(int64_t Scalable)
Definition TypeSize.h:40
static StackOffset getFixed(int64_t Fixed)
Definition TypeSize.h:39
StackOffset & operator+=(const StackOffset &RHS)
Definition TypeSize.h:58
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:343
constexpr TypeSize(ScalarTy Quantity, bool Scalable)
Definition TypeSize.h:337
static constexpr TypeSize getZero()
Definition TypeSize.h:349
friend constexpr TypeSize operator*(const TypeSize &LHS, const unsigned RHS)
Definition TypeSize.h:389
friend constexpr TypeSize operator*(const TypeSize &LHS, const int64_t RHS)
Definition TypeSize.h:392
friend constexpr TypeSize operator*(const uint64_t LHS, const TypeSize &RHS)
Definition TypeSize.h:404
static constexpr TypeSize getScalable(ScalarTy MinimumSize)
Definition TypeSize.h:346
static constexpr TypeSize get(ScalarTy Quantity, bool Scalable)
Definition TypeSize.h:340
friend constexpr TypeSize operator*(const TypeSize &LHS, const int RHS)
Definition TypeSize.h:386
friend constexpr TypeSize operator*(const int64_t LHS, const TypeSize &RHS)
Definition TypeSize.h:401
friend constexpr TypeSize operator*(const unsigned LHS, const TypeSize &RHS)
Definition TypeSize.h:398
friend constexpr TypeSize operator*(const int LHS, const TypeSize &RHS)
Definition TypeSize.h:395
constexpr bool isKnownMultipleOf(ScalarTy RHS) const
This function tells the caller whether the element count is known at compile time to be a multiple of...
Definition TypeSize.h:180
constexpr bool hasKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns true if there exists a value X where RHS.multiplyCoefficientBy(X) will result in a value whos...
Definition TypeSize.h:269
friend constexpr LeafTy & operator*=(LeafTy &LHS, ScalarTy RHS)
Definition TypeSize.h:117
friend constexpr LeafTy operator+(const LeafTy &LHS, const LeafTy &RHS)
Definition TypeSize.h:122
constexpr bool operator!=(const FixedOrScalableQuantity &RHS) const
Definition TypeSize.h:149
friend constexpr LeafTy & operator-=(LeafTy &LHS, const LeafTy &RHS)
Definition TypeSize.h:107
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
static constexpr bool isKnownLE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
Definition TypeSize.h:230
constexpr FixedOrScalableQuantity()=default
friend constexpr LeafTy & operator+=(LeafTy &LHS, const LeafTy &RHS)
Definition TypeSize.h:97
constexpr bool isNonZero() const
Definition TypeSize.h:155
friend constexpr std::enable_if_t< std::is_signed_v< U >, LeafTy > operator-(const LeafTy &LHS)
Definition TypeSize.h:139
void print(raw_ostream &OS) const
Printing function.
Definition TypeSize.h:283
constexpr LeafTy coefficientNextPowerOf2() const
Definition TypeSize.h:260
constexpr LeafTy getWithIncrement(ScalarTy RHS) const
Add RHS to the underlying quantity.
Definition TypeSize.h:160
constexpr ScalarTy getKnownScalarFactor(const FixedOrScalableQuantity &RHS) const
Returns a value X where RHS.multiplyCoefficientBy(X) will result in a value whose quantity matches ou...
Definition TypeSize.h:277
constexpr FixedOrScalableQuantity(ScalarTy Quantity, bool Scalable)
Definition TypeSize.h:94
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
Definition TypeSize.h:216
friend constexpr LeafTy operator-(const LeafTy &LHS, const LeafTy &RHS)
Definition TypeSize.h:127
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
constexpr LeafTy multiplyCoefficientBy(ScalarTy RHS) const
Definition TypeSize.h:256
constexpr bool isKnownEven() const
A return value of true indicates we know at compile time that the number of elements (vscale * Min) i...
Definition TypeSize.h:176
constexpr bool isFixed() const
Returns true if the quantity is not scaled by vscale.
Definition TypeSize.h:171
friend constexpr LeafTy operator*(const LeafTy &LHS, ScalarTy RHS)
Definition TypeSize.h:132
constexpr bool operator==(const FixedOrScalableQuantity &RHS) const
Definition TypeSize.h:145
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:165
constexpr bool isKnownMultipleOf(const FixedOrScalableQuantity &RHS) const
Returns whether or not the callee is known to be a multiple of RHS.
Definition TypeSize.h:185
constexpr bool isZero() const
Definition TypeSize.h:153
static constexpr bool isKnownGT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
Definition TypeSize.h:223
constexpr LeafTy divideCoefficientBy(ScalarTy RHS) const
We do not provide the '/' operator here because division for polynomial types does not work in the sa...
Definition TypeSize.h:252
static constexpr bool isKnownGE(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
Definition TypeSize.h:237
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void reportFatalInternalError(Error Err)
Report a fatal error that indicates a bug in LLVM.
Definition Error.cpp:177
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
constexpr uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
Definition MathExtras.h:373
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
static unsigned getHashValue(const ElementCount &EltCnt)
Definition TypeSize.h:440
static bool isEqual(const ElementCount &LHS, const ElementCount &RHS)
Definition TypeSize.h:447
static ElementCount getTombstoneKey()
Definition TypeSize.h:437
An information struct used to provide DenseMap with the various necessary components for a given valu...