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