LLVM 20.0.0git
LowLevelType.h
Go to the documentation of this file.
1//== llvm/CodeGenTypes/LowLevelType.h -------------------------- -*- 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/// \file
9/// Implement a low-level type suitable for MachineInstr level instruction
10/// selection.
11///
12/// For a type attached to a MachineInstr, we only care about 2 details: total
13/// size and the number of vector lanes (if any). Accordingly, there are 4
14/// possible valid type-kinds:
15///
16/// * `sN` for scalars and aggregates
17/// * `<N x sM>` for vectors, which must have at least 2 elements.
18/// * `pN` for pointers
19///
20/// Other information required for correct selection is expected to be carried
21/// by the opcode, or non-type flags. For example the distinction between G_ADD
22/// and G_FADD for int/float or fast-math flags.
23///
24//===----------------------------------------------------------------------===//
25
26#ifndef LLVM_CODEGEN_LOWLEVELTYPE_H
27#define LLVM_CODEGEN_LOWLEVELTYPE_H
28
31#include "llvm/Support/Debug.h"
32#include <cassert>
33
34namespace llvm {
35
36class Type;
37class raw_ostream;
38
39class LLT {
40public:
41 /// Get a low-level scalar or aggregate "bag of bits".
42 static constexpr LLT scalar(unsigned SizeInBits) {
43 return LLT{/*isPointer=*/false, /*isVector=*/false, /*isScalar=*/true,
44 ElementCount::getFixed(0), SizeInBits,
45 /*AddressSpace=*/0};
46 }
47
48 /// Get a low-level token; just a scalar with zero bits (or no size).
49 static constexpr LLT token() {
50 return LLT{/*isPointer=*/false, /*isVector=*/false,
51 /*isScalar=*/true, ElementCount::getFixed(0),
52 /*SizeInBits=*/0,
53 /*AddressSpace=*/0};
54 }
55
56 /// Get a low-level pointer in the given address space.
57 static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits) {
58 assert(SizeInBits > 0 && "invalid pointer size");
59 return LLT{/*isPointer=*/true, /*isVector=*/false, /*isScalar=*/false,
60 ElementCount::getFixed(0), SizeInBits, AddressSpace};
61 }
62
63 /// Get a low-level vector of some number of elements and element width.
64 static constexpr LLT vector(ElementCount EC, unsigned ScalarSizeInBits) {
65 assert(!EC.isScalar() && "invalid number of vector elements");
66 return LLT{/*isPointer=*/false, /*isVector=*/true, /*isScalar=*/false,
67 EC, ScalarSizeInBits, /*AddressSpace=*/0};
68 }
69
70 /// Get a low-level vector of some number of elements and element type.
71 static constexpr LLT vector(ElementCount EC, LLT ScalarTy) {
72 assert(!EC.isScalar() && "invalid number of vector elements");
73 assert(!ScalarTy.isVector() && "invalid vector element type");
74 return LLT{ScalarTy.isPointer(),
75 /*isVector=*/true,
76 /*isScalar=*/false,
77 EC,
78 ScalarTy.getSizeInBits().getFixedValue(),
79 ScalarTy.isPointer() ? ScalarTy.getAddressSpace() : 0};
80 }
81
82 /// Get a 16-bit IEEE half value.
83 /// TODO: Add IEEE semantics to type - This currently returns a simple `scalar(16)`.
84 static constexpr LLT float16() {
85 return scalar(16);
86 }
87
88 /// Get a 32-bit IEEE float value.
89 static constexpr LLT float32() {
90 return scalar(32);
91 }
92
93 /// Get a 64-bit IEEE double value.
94 static constexpr LLT float64() {
95 return scalar(64);
96 }
97
98 /// Get a low-level fixed-width vector of some number of elements and element
99 /// width.
100 static constexpr LLT fixed_vector(unsigned NumElements,
101 unsigned ScalarSizeInBits) {
102 return vector(ElementCount::getFixed(NumElements), ScalarSizeInBits);
103 }
104
105 /// Get a low-level fixed-width vector of some number of elements and element
106 /// type.
107 static constexpr LLT fixed_vector(unsigned NumElements, LLT ScalarTy) {
108 return vector(ElementCount::getFixed(NumElements), ScalarTy);
109 }
110
111 /// Get a low-level scalable vector of some number of elements and element
112 /// width.
113 static constexpr LLT scalable_vector(unsigned MinNumElements,
114 unsigned ScalarSizeInBits) {
115 return vector(ElementCount::getScalable(MinNumElements), ScalarSizeInBits);
116 }
117
118 /// Get a low-level scalable vector of some number of elements and element
119 /// type.
120 static constexpr LLT scalable_vector(unsigned MinNumElements, LLT ScalarTy) {
121 return vector(ElementCount::getScalable(MinNumElements), ScalarTy);
122 }
123
124 static constexpr LLT scalarOrVector(ElementCount EC, LLT ScalarTy) {
125 return EC.isScalar() ? ScalarTy : LLT::vector(EC, ScalarTy);
126 }
127
128 static constexpr LLT scalarOrVector(ElementCount EC, uint64_t ScalarSize) {
129 assert(ScalarSize <= std::numeric_limits<unsigned>::max() &&
130 "Not enough bits in LLT to represent size");
131 return scalarOrVector(EC, LLT::scalar(static_cast<unsigned>(ScalarSize)));
132 }
133
134 explicit constexpr LLT(bool isPointer, bool isVector, bool isScalar,
135 ElementCount EC, uint64_t SizeInBits,
136 unsigned AddressSpace)
137 : LLT() {
138 init(isPointer, isVector, isScalar, EC, SizeInBits, AddressSpace);
139 }
140 explicit constexpr LLT()
141 : IsScalar(false), IsPointer(false), IsVector(false), RawData(0) {}
142
143 explicit LLT(MVT VT);
144
145 constexpr bool isValid() const { return IsScalar || RawData != 0; }
146 constexpr bool isScalar() const { return IsScalar; }
147 constexpr bool isToken() const { return IsScalar && RawData == 0; };
148 constexpr bool isVector() const { return isValid() && IsVector; }
149 constexpr bool isPointer() const {
150 return isValid() && IsPointer && !IsVector;
151 }
152 constexpr bool isPointerVector() const { return IsPointer && isVector(); }
153 constexpr bool isPointerOrPointerVector() const {
154 return IsPointer && isValid();
155 }
156
157 /// Returns the number of elements in a vector LLT. Must only be called on
158 /// vector types.
159 constexpr uint16_t getNumElements() const {
160 if (isScalable())
162 "Possible incorrect use of LLT::getNumElements() for "
163 "scalable vector. Scalable flag may be dropped, use "
164 "LLT::getElementCount() instead");
166 }
167
168 /// Returns true if the LLT is a scalable vector. Must only be called on
169 /// vector types.
170 constexpr bool isScalable() const {
171 assert(isVector() && "Expected a vector type");
172 return getFieldValue(VectorScalableFieldInfo);
173 }
174
175 /// Returns true if the LLT is a fixed vector. Returns false otherwise, even
176 /// if the LLT is not a vector type.
177 constexpr bool isFixedVector() const { return isVector() && !isScalable(); }
178
179 /// Returns true if the LLT is a scalable vector. Returns false otherwise,
180 /// even if the LLT is not a vector type.
181 constexpr bool isScalableVector() const { return isVector() && isScalable(); }
182
183 constexpr ElementCount getElementCount() const {
184 assert(IsVector && "cannot get number of elements on scalar/aggregate");
185 return ElementCount::get(getFieldValue(VectorElementsFieldInfo),
186 isScalable());
187 }
188
189 /// Returns the total size of the type. Must only be called on sized types.
190 constexpr TypeSize getSizeInBits() const {
191 if (isPointer() || isScalar())
193 auto EC = getElementCount();
194 return TypeSize(getScalarSizeInBits() * EC.getKnownMinValue(),
195 EC.isScalable());
196 }
197
198 /// Returns the total size of the type in bytes, i.e. number of whole bytes
199 /// needed to represent the size in bits. Must only be called on sized types.
200 constexpr TypeSize getSizeInBytes() const {
201 TypeSize BaseSize = getSizeInBits();
202 return {(BaseSize.getKnownMinValue() + 7) / 8, BaseSize.isScalable()};
203 }
204
205 constexpr LLT getScalarType() const {
206 return isVector() ? getElementType() : *this;
207 }
208
209 /// If this type is a vector, return a vector with the same number of elements
210 /// but the new element type. Otherwise, return the new element type.
211 constexpr LLT changeElementType(LLT NewEltTy) const {
212 return isVector() ? LLT::vector(getElementCount(), NewEltTy) : NewEltTy;
213 }
214
215 /// If this type is a vector, return a vector with the same number of elements
216 /// but the new element size. Otherwise, return the new element type. Invalid
217 /// for pointer types. For pointer types, use changeElementType.
218 constexpr LLT changeElementSize(unsigned NewEltSize) const {
220 "invalid to directly change element size for pointers");
221 return isVector() ? LLT::vector(getElementCount(), NewEltSize)
222 : LLT::scalar(NewEltSize);
223 }
224
225 /// Return a vector or scalar with the same element type and the new element
226 /// count.
227 constexpr LLT changeElementCount(ElementCount EC) const {
229 }
230
231 /// Return a type that is \p Factor times smaller. Reduces the number of
232 /// elements if this is a vector, or the bitwidth for scalar/pointers. Does
233 /// not attempt to handle cases that aren't evenly divisible.
234 constexpr LLT divide(int Factor) const {
235 assert(Factor != 1);
236 assert((!isScalar() || getScalarSizeInBits() != 0) &&
237 "cannot divide scalar of size zero");
238 if (isVector()) {
239 assert(getElementCount().isKnownMultipleOf(Factor));
240 return scalarOrVector(getElementCount().divideCoefficientBy(Factor),
242 }
243
244 assert(getScalarSizeInBits() % Factor == 0);
245 return scalar(getScalarSizeInBits() / Factor);
246 }
247
248 /// Produce a vector type that is \p Factor times bigger, preserving the
249 /// element type. For a scalar or pointer, this will produce a new vector with
250 /// \p Factor elements.
251 constexpr LLT multiplyElements(int Factor) const {
252 if (isVector()) {
253 return scalarOrVector(getElementCount().multiplyCoefficientBy(Factor),
255 }
256
257 return fixed_vector(Factor, *this);
258 }
259
260 constexpr bool isByteSized() const {
262 }
263
264 constexpr unsigned getScalarSizeInBits() const {
266 return getFieldValue(PointerSizeFieldInfo);
267 return getFieldValue(ScalarSizeFieldInfo);
268 }
269
270 constexpr unsigned getAddressSpace() const {
272 "cannot get address space of non-pointer type");
273 return getFieldValue(PointerAddressSpaceFieldInfo);
274 }
275
276 /// Returns the vector's element type. Only valid for vector types.
277 constexpr LLT getElementType() const {
278 assert(isVector() && "cannot get element type of scalar/aggregate");
279 if (IsPointer)
281 else
282 return scalar(getScalarSizeInBits());
283 }
284
285 void print(raw_ostream &OS) const;
286
287#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
288 LLVM_DUMP_METHOD void dump() const;
289#endif
290
291 constexpr bool operator==(const LLT &RHS) const {
292 return IsPointer == RHS.IsPointer && IsVector == RHS.IsVector &&
293 IsScalar == RHS.IsScalar && RHS.RawData == RawData;
294 }
295
296 constexpr bool operator!=(const LLT &RHS) const { return !(*this == RHS); }
297
298 friend struct DenseMapInfo<LLT>;
300
301private:
302 /// LLT is packed into 64 bits as follows:
303 /// isScalar : 1
304 /// isPointer : 1
305 /// isVector : 1
306 /// with 61 bits remaining for Kind-specific data, packed in bitfields
307 /// as described below. As there isn't a simple portable way to pack bits
308 /// into bitfields, here the different fields in the packed structure is
309 /// described in static const *Field variables. Each of these variables
310 /// is a 2-element array, with the first element describing the bitfield size
311 /// and the second element describing the bitfield offset.
312 ///
313 /// +--------+---------+--------+----------+----------------------+
314 /// |isScalar|isPointer|isVector| RawData |Notes |
315 /// +--------+---------+--------+----------+----------------------+
316 /// | 0 | 0 | 0 | 0 |Invalid |
317 /// +--------+---------+--------+----------+----------------------+
318 /// | 0 | 0 | 1 | 0 |Tombstone Key |
319 /// +--------+---------+--------+----------+----------------------+
320 /// | 0 | 1 | 0 | 0 |Empty Key |
321 /// +--------+---------+--------+----------+----------------------+
322 /// | 1 | 0 | 0 | 0 |Token |
323 /// +--------+---------+--------+----------+----------------------+
324 /// | 1 | 0 | 0 | non-zero |Scalar |
325 /// +--------+---------+--------+----------+----------------------+
326 /// | 0 | 1 | 0 | non-zero |Pointer |
327 /// +--------+---------+--------+----------+----------------------+
328 /// | 0 | 0 | 1 | non-zero |Vector of non-pointer |
329 /// +--------+---------+--------+----------+----------------------+
330 /// | 0 | 1 | 1 | non-zero |Vector of pointer |
331 /// +--------+---------+--------+----------+----------------------+
332 ///
333 /// Everything else is reserved.
334 typedef int BitFieldInfo[2];
335 ///
336 /// This is how the bitfields are packed per Kind:
337 /// * Invalid:
338 /// gets encoded as RawData == 0, as that is an invalid encoding, since for
339 /// valid encodings, SizeInBits/SizeOfElement must be larger than 0.
340 /// * Non-pointer scalar (isPointer == 0 && isVector == 0):
341 /// SizeInBits: 32;
342 static const constexpr BitFieldInfo ScalarSizeFieldInfo{32, 29};
343 /// * Pointer (isPointer == 1 && isVector == 0):
344 /// SizeInBits: 16;
345 /// AddressSpace: 24;
346 static const constexpr BitFieldInfo PointerSizeFieldInfo{16, 45};
347 static const constexpr BitFieldInfo PointerAddressSpaceFieldInfo{24, 21};
348 /// * Vector-of-non-pointer (isPointer == 0 && isVector == 1):
349 /// NumElements: 16;
350 /// SizeOfElement: 32;
351 /// Scalable: 1;
352 static const constexpr BitFieldInfo VectorElementsFieldInfo{16, 5};
353 static const constexpr BitFieldInfo VectorScalableFieldInfo{1, 0};
354 /// * Vector-of-pointer (isPointer == 1 && isVector == 1):
355 /// NumElements: 16;
356 /// SizeOfElement: 16;
357 /// AddressSpace: 24;
358 /// Scalable: 1;
359
360 uint64_t IsScalar : 1;
361 uint64_t IsPointer : 1;
362 uint64_t IsVector : 1;
363 uint64_t RawData : 61;
364
365 static constexpr uint64_t getMask(const BitFieldInfo FieldInfo) {
366 const int FieldSizeInBits = FieldInfo[0];
367 return (((uint64_t)1) << FieldSizeInBits) - 1;
368 }
369 static constexpr uint64_t maskAndShift(uint64_t Val, uint64_t Mask,
370 uint8_t Shift) {
371 assert(Val <= Mask && "Value too large for field");
372 return (Val & Mask) << Shift;
373 }
374 static constexpr uint64_t maskAndShift(uint64_t Val,
375 const BitFieldInfo FieldInfo) {
376 return maskAndShift(Val, getMask(FieldInfo), FieldInfo[1]);
377 }
378
379 constexpr uint64_t getFieldValue(const BitFieldInfo FieldInfo) const {
380 return getMask(FieldInfo) & (RawData >> FieldInfo[1]);
381 }
382
383 constexpr void init(bool IsPointer, bool IsVector, bool IsScalar,
384 ElementCount EC, uint64_t SizeInBits,
385 unsigned AddressSpace) {
386 assert(SizeInBits <= std::numeric_limits<unsigned>::max() &&
387 "Not enough bits in LLT to represent size");
388 this->IsPointer = IsPointer;
389 this->IsVector = IsVector;
390 this->IsScalar = IsScalar;
391 if (IsPointer) {
392 RawData = maskAndShift(SizeInBits, PointerSizeFieldInfo) |
393 maskAndShift(AddressSpace, PointerAddressSpaceFieldInfo);
394 } else {
395 RawData = maskAndShift(SizeInBits, ScalarSizeFieldInfo);
396 }
397 if (IsVector) {
398 RawData |= maskAndShift(EC.getKnownMinValue(), VectorElementsFieldInfo) |
399 maskAndShift(EC.isScalable() ? 1 : 0, VectorScalableFieldInfo);
400 }
401 }
402
403public:
404 constexpr uint64_t getUniqueRAWLLTData() const {
405 return ((uint64_t)RawData) << 3 | ((uint64_t)IsScalar) << 2 |
406 ((uint64_t)IsPointer) << 1 | ((uint64_t)IsVector);
407 }
408};
409
411 Ty.print(OS);
412 return OS;
413}
414
415template<> struct DenseMapInfo<LLT> {
416 static inline LLT getEmptyKey() {
417 LLT Invalid;
418 Invalid.IsPointer = true;
419 return Invalid;
420 }
421 static inline LLT getTombstoneKey() {
422 LLT Invalid;
423 Invalid.IsVector = true;
424 return Invalid;
425 }
426 static inline unsigned getHashValue(const LLT &Ty) {
427 uint64_t Val = Ty.getUniqueRAWLLTData();
429 }
430 static bool isEqual(const LLT &LHS, const LLT &RHS) {
431 return LHS == RHS;
432 }
433};
434
435}
436
437#endif // LLVM_CODEGEN_LOWLEVELTYPE_H
AMDGPU promote alloca to vector or false DEBUG_TYPE to vector
RelocType Type
Definition: COFFYAML.cpp:410
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:622
This file defines DenseMapInfo traits for DenseMap.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
Value * RHS
Value * LHS
static constexpr ElementCount getScalable(ScalarTy MinVal)
Definition: TypeSize.h:314
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition: TypeSize.h:311
static constexpr ElementCount get(ScalarTy MinVal, bool Scalable)
Definition: TypeSize.h:317
static constexpr LLT float64()
Get a 64-bit IEEE double value.
Definition: LowLevelType.h:94
void print(raw_ostream &OS) const
constexpr bool isScalableVector() const
Returns true if the LLT is a scalable vector.
Definition: LowLevelType.h:181
static constexpr LLT scalarOrVector(ElementCount EC, uint64_t ScalarSize)
Definition: LowLevelType.h:128
constexpr unsigned getScalarSizeInBits() const
Definition: LowLevelType.h:264
constexpr LLT(bool isPointer, bool isVector, bool isScalar, ElementCount EC, uint64_t SizeInBits, unsigned AddressSpace)
Definition: LowLevelType.h:134
constexpr bool isScalar() const
Definition: LowLevelType.h:146
static constexpr LLT scalable_vector(unsigned MinNumElements, unsigned ScalarSizeInBits)
Get a low-level scalable vector of some number of elements and element width.
Definition: LowLevelType.h:113
constexpr bool operator==(const LLT &RHS) const
Definition: LowLevelType.h:291
constexpr LLT changeElementType(LLT NewEltTy) const
If this type is a vector, return a vector with the same number of elements but the new element type.
Definition: LowLevelType.h:211
constexpr LLT multiplyElements(int Factor) const
Produce a vector type that is Factor times bigger, preserving the element type.
Definition: LowLevelType.h:251
static constexpr LLT vector(ElementCount EC, unsigned ScalarSizeInBits)
Get a low-level vector of some number of elements and element width.
Definition: LowLevelType.h:64
constexpr bool isPointerVector() const
Definition: LowLevelType.h:152
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelType.h:42
constexpr bool isValid() const
Definition: LowLevelType.h:145
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
Definition: LowLevelType.h:159
constexpr bool operator!=(const LLT &RHS) const
Definition: LowLevelType.h:296
constexpr bool isToken() const
Definition: LowLevelType.h:147
constexpr bool isVector() const
Definition: LowLevelType.h:148
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
Definition: LowLevelType.h:57
constexpr bool isScalable() const
Returns true if the LLT is a scalable vector.
Definition: LowLevelType.h:170
constexpr uint64_t getUniqueRAWLLTData() const
Definition: LowLevelType.h:404
constexpr bool isByteSized() const
Definition: LowLevelType.h:260
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelType.h:190
constexpr bool isPointer() const
Definition: LowLevelType.h:149
constexpr LLT()
Definition: LowLevelType.h:140
constexpr LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
Definition: LowLevelType.h:277
static constexpr LLT vector(ElementCount EC, LLT ScalarTy)
Get a low-level vector of some number of elements and element type.
Definition: LowLevelType.h:71
constexpr ElementCount getElementCount() const
Definition: LowLevelType.h:183
constexpr LLT changeElementSize(unsigned NewEltSize) const
If this type is a vector, return a vector with the same number of elements but the new element size.
Definition: LowLevelType.h:218
static constexpr LLT fixed_vector(unsigned NumElements, LLT ScalarTy)
Get a low-level fixed-width vector of some number of elements and element type.
Definition: LowLevelType.h:107
static constexpr LLT float16()
Get a 16-bit IEEE half value.
Definition: LowLevelType.h:84
constexpr unsigned getAddressSpace() const
Definition: LowLevelType.h:270
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
Definition: LowLevelType.h:100
constexpr bool isPointerOrPointerVector() const
Definition: LowLevelType.h:153
constexpr bool isFixedVector() const
Returns true if the LLT is a fixed vector.
Definition: LowLevelType.h:177
static constexpr LLT token()
Get a low-level token; just a scalar with zero bits (or no size).
Definition: LowLevelType.h:49
constexpr LLT changeElementCount(ElementCount EC) const
Return a vector or scalar with the same element type and the new element count.
Definition: LowLevelType.h:227
LLVM_DUMP_METHOD void dump() const
constexpr LLT getScalarType() const
Definition: LowLevelType.h:205
constexpr TypeSize getSizeInBytes() const
Returns the total size of the type in bytes, i.e.
Definition: LowLevelType.h:200
static constexpr LLT scalable_vector(unsigned MinNumElements, LLT ScalarTy)
Get a low-level scalable vector of some number of elements and element type.
Definition: LowLevelType.h:120
static constexpr LLT scalarOrVector(ElementCount EC, LLT ScalarTy)
Definition: LowLevelType.h:124
static constexpr LLT float32()
Get a 32-bit IEEE float value.
Definition: LowLevelType.h:89
constexpr LLT divide(int Factor) const
Return a type that is Factor times smaller.
Definition: LowLevelType.h:234
Machine Value Type.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition: TypeSize.h:345
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:183
constexpr ScalarTy getFixedValue() const
Definition: TypeSize.h:202
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition: TypeSize.h:171
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition: TypeSize.h:168
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:39
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition: APFixedPoint.h:303
static LLT getTombstoneKey()
Definition: LowLevelType.h:421
static bool isEqual(const LLT &LHS, const LLT &RHS)
Definition: LowLevelType.h:430
static unsigned getHashValue(const LLT &Ty)
Definition: LowLevelType.h:426
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: DenseMapInfo.h:52