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