1 //===- LLVMDialect.h - MLIR LLVM dialect types ------------------*- 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 defines the types for the LLVM dialect in MLIR. These MLIR types
10 // correspond to the LLVM IR type system.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef MLIR_DIALECT_LLVMIR_LLVMTYPES_H_
15 #define MLIR_DIALECT_LLVMIR_LLVMTYPES_H_
16 
17 #include "mlir/IR/Types.h"
18 
19 namespace llvm {
20 class ElementCount;
21 class TypeSize;
22 } // namespace llvm
23 
24 namespace mlir {
25 
26 class DialectAsmParser;
27 class DialectAsmPrinter;
28 
29 namespace LLVM {
30 class LLVMDialect;
31 
32 namespace detail {
33 struct LLVMFunctionTypeStorage;
34 struct LLVMIntegerTypeStorage;
35 struct LLVMPointerTypeStorage;
36 struct LLVMStructTypeStorage;
37 struct LLVMTypeAndSizeStorage;
38 } // namespace detail
39 
40 class LLVMBFloatType;
41 class LLVMHalfType;
42 class LLVMFloatType;
43 class LLVMDoubleType;
44 class LLVMFP128Type;
45 class LLVMX86FP80Type;
46 class LLVMIntegerType;
47 
48 //===----------------------------------------------------------------------===//
49 // LLVMType.
50 //===----------------------------------------------------------------------===//
51 
52 /// Base class for LLVM dialect types.
53 ///
54 /// The LLVM dialect in MLIR fully reflects the LLVM IR type system, prodiving a
55 /// separate MLIR type for each LLVM IR type. All types are represented as
56 /// separate subclasses and are compatible with the isa/cast infrastructure. For
57 /// convenience, the base class provides most of the APIs available on
58 /// llvm::Type in addition to MLIR-compatible APIs.
59 ///
60 /// The LLVM dialect type system is closed: parametric types can only refer to
61 /// other LLVM dialect types. This is consistent with LLVM IR and enables a more
62 /// concise pretty-printing format.
63 ///
64 /// Similarly to other MLIR types, LLVM dialect types are owned by the MLIR
65 /// context, have an immutable identifier (for most types except identified
66 /// structs, the entire type is the identifier) and are thread-safe.
67 class LLVMType : public Type {
68 public:
69   /// Inherit base constructors.
70   using Type::Type;
71 
72   /// Support for PointerLikeTypeTraits.
73   using Type::getAsOpaquePointer;
getFromOpaquePointer(const void * ptr)74   static LLVMType getFromOpaquePointer(const void *ptr) {
75     return LLVMType(static_cast<ImplType *>(const_cast<void *>(ptr)));
76   }
77 
78   /// Support for isa/cast.
79   static bool classof(Type type);
80 
81   LLVMDialect &getDialect();
82 
83   /// Returns the size of a primitive type (including vectors) in bits, for
84   /// example, the size of !llvm.i16 is 16 and the size of !llvm.vec<4 x i16>
85   /// is 64. Returns 0 for non-primitive (aggregates such as struct) or types
86   /// that don't have a size (such as void).
87   llvm::TypeSize getPrimitiveSizeInBits();
88 
89   /// Floating-point type utilities.
isBFloatTy()90   bool isBFloatTy() { return isa<LLVMBFloatType>(); }
isHalfTy()91   bool isHalfTy() { return isa<LLVMHalfType>(); }
isFloatTy()92   bool isFloatTy() { return isa<LLVMFloatType>(); }
isDoubleTy()93   bool isDoubleTy() { return isa<LLVMDoubleType>(); }
isFP128Ty()94   bool isFP128Ty() { return isa<LLVMFP128Type>(); }
isX86_FP80Ty()95   bool isX86_FP80Ty() { return isa<LLVMX86FP80Type>(); }
isFloatingPointTy()96   bool isFloatingPointTy() {
97     return isa<LLVMHalfType>() || isa<LLVMBFloatType>() ||
98            isa<LLVMFloatType>() || isa<LLVMDoubleType>() ||
99            isa<LLVMFP128Type>() || isa<LLVMX86FP80Type>();
100   }
101 
102   /// Array type utilities.
103   LLVMType getArrayElementType();
104   unsigned getArrayNumElements();
105   bool isArrayTy();
106 
107   /// Integer type utilities.
isIntegerTy()108   bool isIntegerTy() { return isa<LLVMIntegerType>(); }
109   bool isIntegerTy(unsigned bitwidth);
110   unsigned getIntegerBitWidth();
111 
112   /// Vector type utilities.
113   LLVMType getVectorElementType();
114   unsigned getVectorNumElements();
115   llvm::ElementCount getVectorElementCount();
116   bool isVectorTy();
117 
118   /// Function type utilities.
119   LLVMType getFunctionParamType(unsigned argIdx);
120   unsigned getFunctionNumParams();
121   LLVMType getFunctionResultType();
122   bool isFunctionTy();
123   bool isFunctionVarArg();
124 
125   /// Pointer type utilities.
126   LLVMType getPointerTo(unsigned addrSpace = 0);
127   LLVMType getPointerElementTy();
128   bool isPointerTy();
129 
130   /// Struct type utilities.
131   LLVMType getStructElementType(unsigned i);
132   unsigned getStructNumElements();
133   bool isStructTy();
134 
135   /// Utilities used to generate floating point types.
136   static LLVMType getDoubleTy(MLIRContext *context);
137   static LLVMType getFloatTy(MLIRContext *context);
138   static LLVMType getBFloatTy(MLIRContext *context);
139   static LLVMType getHalfTy(MLIRContext *context);
140   static LLVMType getFP128Ty(MLIRContext *context);
141   static LLVMType getX86_FP80Ty(MLIRContext *context);
142 
143   /// Utilities used to generate integer types.
144   static LLVMType getIntNTy(MLIRContext *context, unsigned numBits);
getInt1Ty(MLIRContext * context)145   static LLVMType getInt1Ty(MLIRContext *context) {
146     return getIntNTy(context, /*numBits=*/1);
147   }
getInt8Ty(MLIRContext * context)148   static LLVMType getInt8Ty(MLIRContext *context) {
149     return getIntNTy(context, /*numBits=*/8);
150   }
getInt8PtrTy(MLIRContext * context)151   static LLVMType getInt8PtrTy(MLIRContext *context) {
152     return getInt8Ty(context).getPointerTo();
153   }
getInt16Ty(MLIRContext * context)154   static LLVMType getInt16Ty(MLIRContext *context) {
155     return getIntNTy(context, /*numBits=*/16);
156   }
getInt32Ty(MLIRContext * context)157   static LLVMType getInt32Ty(MLIRContext *context) {
158     return getIntNTy(context, /*numBits=*/32);
159   }
getInt64Ty(MLIRContext * context)160   static LLVMType getInt64Ty(MLIRContext *context) {
161     return getIntNTy(context, /*numBits=*/64);
162   }
163 
164   /// Utilities used to generate other miscellaneous types.
165   static LLVMType getArrayTy(LLVMType elementType, uint64_t numElements);
166   static LLVMType getFunctionTy(LLVMType result, ArrayRef<LLVMType> params,
167                                 bool isVarArg);
getFunctionTy(LLVMType result,bool isVarArg)168   static LLVMType getFunctionTy(LLVMType result, bool isVarArg) {
169     return getFunctionTy(result, llvm::None, isVarArg);
170   }
171   static LLVMType getStructTy(MLIRContext *context, ArrayRef<LLVMType> elements,
172                               bool isPacked = false);
173   static LLVMType getStructTy(MLIRContext *context, bool isPacked = false) {
174     return getStructTy(context, llvm::None, isPacked);
175   }
176   template <typename... Args>
177   static typename std::enable_if<llvm::are_base_of<LLVMType, Args...>::value,
178                                  LLVMType>::type
getStructTy(LLVMType elt1,Args...elts)179   getStructTy(LLVMType elt1, Args... elts) {
180     SmallVector<LLVMType, 8> fields({elt1, elts...});
181     return getStructTy(elt1.getContext(), fields);
182   }
183   static LLVMType getVectorTy(LLVMType elementType, unsigned numElements);
184 
185   /// Void type utilities.
186   static LLVMType getVoidTy(MLIRContext *context);
187   bool isVoidTy();
188 
189   // Creation and setting of LLVM's identified struct types
190   static LLVMType createStructTy(MLIRContext *context,
191                                  ArrayRef<LLVMType> elements,
192                                  Optional<StringRef> name,
193                                  bool isPacked = false);
194 
createStructTy(MLIRContext * context,Optional<StringRef> name)195   static LLVMType createStructTy(MLIRContext *context,
196                                  Optional<StringRef> name) {
197     return createStructTy(context, llvm::None, name);
198   }
199 
200   static LLVMType createStructTy(ArrayRef<LLVMType> elements,
201                                  Optional<StringRef> name,
202                                  bool isPacked = false) {
203     assert(!elements.empty() &&
204            "This method may not be invoked with an empty list");
205     LLVMType ele0 = elements.front();
206     return createStructTy(ele0.getContext(), elements, name, isPacked);
207   }
208 
209   template <typename... Args>
210   static typename std::enable_if_t<llvm::are_base_of<LLVMType, Args...>::value,
211                                    LLVMType>
createStructTy(StringRef name,LLVMType elt1,Args...elts)212   createStructTy(StringRef name, LLVMType elt1, Args... elts) {
213     SmallVector<LLVMType, 8> fields({elt1, elts...});
214     Optional<StringRef> opt_name(name);
215     return createStructTy(elt1.getContext(), fields, opt_name);
216   }
217 
218   static LLVMType setStructTyBody(LLVMType structType,
219                                   ArrayRef<LLVMType> elements,
220                                   bool isPacked = false);
221 
222   template <typename... Args>
223   static typename std::enable_if_t<llvm::are_base_of<LLVMType, Args...>::value,
224                                    LLVMType>
setStructTyBody(LLVMType structType,LLVMType elt1,Args...elts)225   setStructTyBody(LLVMType structType, LLVMType elt1, Args... elts) {
226     SmallVector<LLVMType, 8> fields({elt1, elts...});
227     return setStructTyBody(structType, fields);
228   }
229 };
230 
231 //===----------------------------------------------------------------------===//
232 // Trivial types.
233 //===----------------------------------------------------------------------===//
234 
235 // Batch-define trivial types.
236 #define DEFINE_TRIVIAL_LLVM_TYPE(ClassName)                                    \
237   class ClassName : public Type::TypeBase<ClassName, LLVMType, TypeStorage> {  \
238   public:                                                                      \
239     using Base::Base;                                                          \
240   }
241 
242 DEFINE_TRIVIAL_LLVM_TYPE(LLVMVoidType);
243 DEFINE_TRIVIAL_LLVM_TYPE(LLVMHalfType);
244 DEFINE_TRIVIAL_LLVM_TYPE(LLVMBFloatType);
245 DEFINE_TRIVIAL_LLVM_TYPE(LLVMFloatType);
246 DEFINE_TRIVIAL_LLVM_TYPE(LLVMDoubleType);
247 DEFINE_TRIVIAL_LLVM_TYPE(LLVMFP128Type);
248 DEFINE_TRIVIAL_LLVM_TYPE(LLVMX86FP80Type);
249 DEFINE_TRIVIAL_LLVM_TYPE(LLVMPPCFP128Type);
250 DEFINE_TRIVIAL_LLVM_TYPE(LLVMX86MMXType);
251 DEFINE_TRIVIAL_LLVM_TYPE(LLVMTokenType);
252 DEFINE_TRIVIAL_LLVM_TYPE(LLVMLabelType);
253 DEFINE_TRIVIAL_LLVM_TYPE(LLVMMetadataType);
254 
255 #undef DEFINE_TRIVIAL_LLVM_TYPE
256 
257 //===----------------------------------------------------------------------===//
258 // LLVMArrayType.
259 //===----------------------------------------------------------------------===//
260 
261 /// LLVM dialect array type. It is an aggregate type representing consecutive
262 /// elements in memory, parameterized by the number of elements and the element
263 /// type.
264 class LLVMArrayType : public Type::TypeBase<LLVMArrayType, LLVMType,
265                                             detail::LLVMTypeAndSizeStorage> {
266 public:
267   /// Inherit base constructors.
268   using Base::Base;
269 
270   /// Checks if the given type can be used inside an array type.
271   static bool isValidElementType(LLVMType type);
272 
273   /// Gets or creates an instance of LLVM dialect array type containing
274   /// `numElements` of `elementType`, in the same context as `elementType`.
275   static LLVMArrayType get(LLVMType elementType, unsigned numElements);
276   static LLVMArrayType getChecked(Location loc, LLVMType elementType,
277                                   unsigned numElements);
278 
279   /// Returns the element type of the array.
280   LLVMType getElementType();
281 
282   /// Returns the number of elements in the array type.
283   unsigned getNumElements();
284 
285   /// Verifies that the type about to be constructed is well-formed.
286   static LogicalResult verifyConstructionInvariants(Location loc,
287                                                     LLVMType elementType,
288                                                     unsigned numElements);
289 };
290 
291 //===----------------------------------------------------------------------===//
292 // LLVMFunctionType.
293 //===----------------------------------------------------------------------===//
294 
295 /// LLVM dialect function type. It consists of a single return type (unlike MLIR
296 /// which can have multiple), a list of parameter types and can optionally be
297 /// variadic.
298 class LLVMFunctionType
299     : public Type::TypeBase<LLVMFunctionType, LLVMType,
300                             detail::LLVMFunctionTypeStorage> {
301 public:
302   /// Inherit base constructors.
303   using Base::Base;
304 
305   /// Checks if the given type can be used an argument in a function type.
306   static bool isValidArgumentType(LLVMType type);
307 
308   /// Checks if the given type can be used as a result in a function type.
309   static bool isValidResultType(LLVMType type);
310 
311   /// Returns whether the function is variadic.
312   bool isVarArg();
313 
314   /// Gets or creates an instance of LLVM dialect function in the same context
315   /// as the `result` type.
316   static LLVMFunctionType get(LLVMType result, ArrayRef<LLVMType> arguments,
317                               bool isVarArg = false);
318   static LLVMFunctionType getChecked(Location loc, LLVMType result,
319                                      ArrayRef<LLVMType> arguments,
320                                      bool isVarArg = false);
321 
322   /// Returns the result type of the function.
323   LLVMType getReturnType();
324 
325   /// Returns the number of arguments to the function.
326   unsigned getNumParams();
327 
328   /// Returns `i`-th argument of the function. Asserts on out-of-bounds.
329   LLVMType getParamType(unsigned i);
330 
331   /// Returns a list of argument types of the function.
332   ArrayRef<LLVMType> getParams();
params()333   ArrayRef<LLVMType> params() { return getParams(); }
334 
335   /// Verifies that the type about to be constructed is well-formed.
336   static LogicalResult
337   verifyConstructionInvariants(Location loc, LLVMType result,
338                                ArrayRef<LLVMType> arguments, bool);
339 };
340 
341 //===----------------------------------------------------------------------===//
342 // LLVMIntegerType.
343 //===----------------------------------------------------------------------===//
344 
345 /// LLVM dialect signless integer type parameterized by bitwidth.
346 class LLVMIntegerType : public Type::TypeBase<LLVMIntegerType, LLVMType,
347                                               detail::LLVMIntegerTypeStorage> {
348 public:
349   /// Inherit base constructor.
350   using Base::Base;
351 
352   /// Gets or creates an instance of the integer of the specified `bitwidth` in
353   /// the given context.
354   static LLVMIntegerType get(MLIRContext *ctx, unsigned bitwidth);
355   static LLVMIntegerType getChecked(Location loc, unsigned bitwidth);
356 
357   /// Returns the bitwidth of this integer type.
358   unsigned getBitWidth();
359 
360   /// Verifies that the type about to be constructed is well-formed.
361   static LogicalResult verifyConstructionInvariants(Location loc,
362                                                     unsigned bitwidth);
363 };
364 
365 //===----------------------------------------------------------------------===//
366 // LLVMPointerType.
367 //===----------------------------------------------------------------------===//
368 
369 /// LLVM dialect pointer type. This type typically represents a reference to an
370 /// object in memory. It is parameterized by the element type and the address
371 /// space.
372 class LLVMPointerType : public Type::TypeBase<LLVMPointerType, LLVMType,
373                                               detail::LLVMPointerTypeStorage> {
374 public:
375   /// Inherit base constructors.
376   using Base::Base;
377 
378   /// Checks if the given type can have a pointer type pointing to it.
379   static bool isValidElementType(LLVMType type);
380 
381   /// Gets or creates an instance of LLVM dialect pointer type pointing to an
382   /// object of `pointee` type in the given address space. The pointer type is
383   /// created in the same context as `pointee`.
384   static LLVMPointerType get(LLVMType pointee, unsigned addressSpace = 0);
385   static LLVMPointerType getChecked(Location loc, LLVMType pointee,
386                                     unsigned addressSpace = 0);
387 
388   /// Returns the pointed-to type.
389   LLVMType getElementType();
390 
391   /// Returns the address space of the pointer.
392   unsigned getAddressSpace();
393 
394   /// Verifies that the type about to be constructed is well-formed.
395   static LogicalResult verifyConstructionInvariants(Location loc,
396                                                     LLVMType pointee, unsigned);
397 };
398 
399 //===----------------------------------------------------------------------===//
400 // LLVMStructType.
401 //===----------------------------------------------------------------------===//
402 
403 /// LLVM dialect structure type representing a collection of different-typed
404 /// elements manipulated together. Structured can optionally be packed, meaning
405 /// that their elements immediately follow each other in memory without
406 /// accounting for potential alignment.
407 ///
408 /// Structure types can be identified (named) or literal. Literal structures
409 /// are uniquely represented by the list of types they contain and packedness.
410 /// Literal structure types are immutable after construction.
411 ///
412 /// Identified structures are uniquely represented by their name, a string. They
413 /// have a mutable component, consisting of the list of types they contain,
414 /// the packedness and the opacity bits. Identified structs can be created
415 /// without providing the lists of element types, making them suitable to
416 /// represent recursive, i.e. self-referring, structures. Identified structs
417 /// without body are considered opaque. For such structs, one can set the body.
418 /// Identified structs can be created as intentionally-opaque, implying that the
419 /// caller does not intend to ever set the body (e.g. forward-declarations of
420 /// structs from another module) and wants to disallow further modification of
421 /// the body. For intentionally-opaque structs or non-opaque structs with the
422 /// body, one is not allowed to set another body (however, one can set exactly
423 /// the same body).
424 ///
425 /// Note that the packedness of the struct takes place in uniquing of literal
426 /// structs, but does not in uniquing of identified structs.
427 class LLVMStructType : public Type::TypeBase<LLVMStructType, LLVMType,
428                                              detail::LLVMStructTypeStorage> {
429 public:
430   /// Inherit base constructors.
431   using Base::Base;
432 
433   /// Checks if the given type can be contained in a structure type.
434   static bool isValidElementType(LLVMType type);
435 
436   /// Gets or creates an identified struct with the given name in the provided
437   /// context. Note that unlike llvm::StructType::create, this function will
438   /// _NOT_ rename a struct in case a struct with the same name already exists
439   /// in the context. Instead, it will just return the existing struct,
440   /// similarly to the rest of MLIR type ::get methods.
441   static LLVMStructType getIdentified(MLIRContext *context, StringRef name);
442   static LLVMStructType getIdentifiedChecked(Location loc, StringRef name);
443 
444   /// Gets or creates a literal struct with the given body in the provided
445   /// context.
446   static LLVMStructType getLiteral(MLIRContext *context,
447                                    ArrayRef<LLVMType> types,
448                                    bool isPacked = false);
449   static LLVMStructType getLiteralChecked(Location loc,
450                                           ArrayRef<LLVMType> types,
451                                           bool isPacked = false);
452 
453   /// Gets or creates an intentionally-opaque identified struct. Such a struct
454   /// cannot have its body set. To create an opaque struct with a mutable body,
455   /// use `getIdentified`. Note that unlike llvm::StructType::create, this
456   /// function will _NOT_ rename a struct in case a struct with the same name
457   /// already exists in the context. Instead, it will just return the existing
458   /// struct, similarly to the rest of MLIR type ::get methods.
459   static LLVMStructType getOpaque(StringRef name, MLIRContext *context);
460   static LLVMStructType getOpaqueChecked(Location loc, StringRef name);
461 
462   /// Set the body of an identified struct. Returns failure if the body could
463   /// not be set, e.g. if the struct already has a body or if it was marked as
464   /// intentionally opaque. This might happen in a multi-threaded context when a
465   /// different thread modified the struct after it was created. Most callers
466   /// are likely to assert this always succeeds, but it is possible to implement
467   /// a local renaming scheme based on the result of this call.
468   LogicalResult setBody(ArrayRef<LLVMType> types, bool isPacked);
469 
470   /// Checks if a struct is packed.
471   bool isPacked();
472 
473   /// Checks if a struct is identified.
474   bool isIdentified();
475 
476   /// Checks if a struct is opaque.
477   bool isOpaque();
478 
479   /// Checks if a struct is initialized.
480   bool isInitialized();
481 
482   /// Returns the name of an identified struct.
483   StringRef getName();
484 
485   /// Returns the list of element types contained in a non-opaque struct.
486   ArrayRef<LLVMType> getBody();
487 
488   /// Verifies that the type about to be constructed is well-formed.
489   static LogicalResult verifyConstructionInvariants(Location, StringRef, bool);
490   static LogicalResult
491   verifyConstructionInvariants(Location loc, ArrayRef<LLVMType> types, bool);
492 };
493 
494 //===----------------------------------------------------------------------===//
495 // LLVMVectorType.
496 //===----------------------------------------------------------------------===//
497 
498 /// LLVM dialect vector type, represents a sequence of elements that can be
499 /// processed as one, typically in SIMD context. This is a base class for fixed
500 /// and scalable vectors.
501 class LLVMVectorType : public LLVMType {
502 public:
503   /// Inherit base constructor.
504   using LLVMType::LLVMType;
505 
506   /// Support type casting functionality.
507   static bool classof(Type type);
508 
509   /// Checks if the given type can be used in a vector type.
510   static bool isValidElementType(LLVMType type);
511 
512   /// Returns the element type of the vector.
513   LLVMType getElementType();
514 
515   /// Returns the number of elements in the vector.
516   llvm::ElementCount getElementCount();
517 
518   /// Verifies that the type about to be constructed is well-formed.
519   static LogicalResult verifyConstructionInvariants(Location loc,
520                                                     LLVMType elementType,
521                                                     unsigned numElements);
522 };
523 
524 //===----------------------------------------------------------------------===//
525 // LLVMFixedVectorType.
526 //===----------------------------------------------------------------------===//
527 
528 /// LLVM dialect fixed vector type, represents a sequence of elements of known
529 /// length that can be processed as one.
530 class LLVMFixedVectorType
531     : public Type::TypeBase<LLVMFixedVectorType, LLVMVectorType,
532                             detail::LLVMTypeAndSizeStorage> {
533 public:
534   /// Inherit base constructor.
535   using Base::Base;
536   using LLVMVectorType::verifyConstructionInvariants;
537 
538   /// Gets or creates a fixed vector type containing `numElements` of
539   /// `elementType` in the same context as `elementType`.
540   static LLVMFixedVectorType get(LLVMType elementType, unsigned numElements);
541   static LLVMFixedVectorType getChecked(Location loc, LLVMType elementType,
542                                         unsigned numElements);
543 
544   /// Returns the number of elements in the fixed vector.
545   unsigned getNumElements();
546 };
547 
548 //===----------------------------------------------------------------------===//
549 // LLVMScalableVectorType.
550 //===----------------------------------------------------------------------===//
551 
552 /// LLVM dialect scalable vector type, represents a sequence of elements of
553 /// unknown length that is known to be divisible by some constant. These
554 /// elements can be processed as one in SIMD context.
555 class LLVMScalableVectorType
556     : public Type::TypeBase<LLVMScalableVectorType, LLVMVectorType,
557                             detail::LLVMTypeAndSizeStorage> {
558 public:
559   /// Inherit base constructor.
560   using Base::Base;
561   using LLVMVectorType::verifyConstructionInvariants;
562 
563   /// Gets or creates a scalable vector type containing a non-zero multiple of
564   /// `minNumElements` of `elementType` in the same context as `elementType`.
565   static LLVMScalableVectorType get(LLVMType elementType,
566                                     unsigned minNumElements);
567   static LLVMScalableVectorType getChecked(Location loc, LLVMType elementType,
568                                            unsigned minNumElements);
569 
570   /// Returns the scaling factor of the number of elements in the vector. The
571   /// vector contains at least the resulting number of elements, or any non-zero
572   /// multiple of this number.
573   unsigned getMinNumElements();
574 };
575 
576 //===----------------------------------------------------------------------===//
577 // Printing and parsing.
578 //===----------------------------------------------------------------------===//
579 
580 namespace detail {
581 /// Parses an LLVM dialect type.
582 LLVMType parseType(DialectAsmParser &parser);
583 
584 /// Prints an LLVM Dialect type.
585 void printType(LLVMType type, DialectAsmPrinter &printer);
586 } // namespace detail
587 
588 } // namespace LLVM
589 } // namespace mlir
590 
591 //===----------------------------------------------------------------------===//
592 // Support for hashing and containers.
593 //===----------------------------------------------------------------------===//
594 
595 namespace llvm {
596 
597 // LLVMType instances hash just like pointers.
598 template <>
599 struct DenseMapInfo<mlir::LLVM::LLVMType> {
600   static mlir::LLVM::LLVMType getEmptyKey() {
601     void *pointer = llvm::DenseMapInfo<void *>::getEmptyKey();
602     return mlir::LLVM::LLVMType(
603         static_cast<mlir::LLVM::LLVMType::ImplType *>(pointer));
604   }
605   static mlir::LLVM::LLVMType getTombstoneKey() {
606     void *pointer = llvm::DenseMapInfo<void *>::getTombstoneKey();
607     return mlir::LLVM::LLVMType(
608         static_cast<mlir::LLVM::LLVMType::ImplType *>(pointer));
609   }
610   static unsigned getHashValue(mlir::LLVM::LLVMType val) {
611     return mlir::hash_value(val);
612   }
613   static bool isEqual(mlir::LLVM::LLVMType lhs, mlir::LLVM::LLVMType rhs) {
614     return lhs == rhs;
615   }
616 };
617 
618 // LLVMType behaves like a pointer similarly to mlir::Type.
619 template <>
620 struct PointerLikeTypeTraits<mlir::LLVM::LLVMType> {
621   static inline void *getAsVoidPointer(mlir::LLVM::LLVMType type) {
622     return const_cast<void *>(type.getAsOpaquePointer());
623   }
624   static inline mlir::LLVM::LLVMType getFromVoidPointer(void *ptr) {
625     return mlir::LLVM::LLVMType::getFromOpaquePointer(ptr);
626   }
627   static constexpr int NumLowBitsAvailable =
628       PointerLikeTypeTraits<mlir::Type>::NumLowBitsAvailable;
629 };
630 
631 } // namespace llvm
632 
633 #endif // MLIR_DIALECT_LLVMIR_LLVMTYPES_H_
634