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