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 #include "mlir/Interfaces/DataLayoutInterfaces.h" 19 20 namespace llvm { 21 class ElementCount; 22 class TypeSize; 23 } // namespace llvm 24 25 namespace mlir { 26 27 class DialectAsmParser; 28 class DialectAsmPrinter; 29 30 namespace LLVM { 31 class LLVMDialect; 32 33 namespace detail { 34 struct LLVMFunctionTypeStorage; 35 struct LLVMPointerTypeStorage; 36 struct LLVMStructTypeStorage; 37 struct LLVMTypeAndSizeStorage; 38 } // namespace detail 39 } // namespace LLVM 40 } // namespace mlir 41 42 #include "mlir/Dialect/LLVMIR/LLVMTypeInterfaces.h.inc" 43 44 namespace mlir { 45 namespace LLVM { 46 47 //===----------------------------------------------------------------------===// 48 // Trivial types. 49 //===----------------------------------------------------------------------===// 50 51 // Batch-define trivial types. 52 #define DEFINE_TRIVIAL_LLVM_TYPE(ClassName) \ 53 class ClassName : public Type::TypeBase<ClassName, Type, TypeStorage> { \ 54 public: \ 55 using Base::Base; \ 56 } 57 58 DEFINE_TRIVIAL_LLVM_TYPE(LLVMVoidType); 59 DEFINE_TRIVIAL_LLVM_TYPE(LLVMPPCFP128Type); 60 DEFINE_TRIVIAL_LLVM_TYPE(LLVMX86MMXType); 61 DEFINE_TRIVIAL_LLVM_TYPE(LLVMTokenType); 62 DEFINE_TRIVIAL_LLVM_TYPE(LLVMLabelType); 63 DEFINE_TRIVIAL_LLVM_TYPE(LLVMMetadataType); 64 65 #undef DEFINE_TRIVIAL_LLVM_TYPE 66 67 //===----------------------------------------------------------------------===// 68 // LLVMArrayType. 69 //===----------------------------------------------------------------------===// 70 71 /// LLVM dialect array type. It is an aggregate type representing consecutive 72 /// elements in memory, parameterized by the number of elements and the element 73 /// type. 74 class LLVMArrayType : public Type::TypeBase<LLVMArrayType, Type, 75 detail::LLVMTypeAndSizeStorage> { 76 public: 77 /// Inherit base constructors. 78 using Base::Base; 79 using Base::getChecked; 80 81 /// Checks if the given type can be used inside an array type. 82 static bool isValidElementType(Type type); 83 84 /// Gets or creates an instance of LLVM dialect array type containing 85 /// `numElements` of `elementType`, in the same context as `elementType`. 86 static LLVMArrayType get(Type elementType, unsigned numElements); 87 static LLVMArrayType getChecked(function_ref<InFlightDiagnostic()> emitError, 88 Type elementType, unsigned numElements); 89 90 /// Returns the element type of the array. 91 Type getElementType(); 92 93 /// Returns the number of elements in the array type. 94 unsigned getNumElements(); 95 96 /// Verifies that the type about to be constructed is well-formed. 97 static LogicalResult verify(function_ref<InFlightDiagnostic()> emitError, 98 Type elementType, unsigned numElements); 99 }; 100 101 //===----------------------------------------------------------------------===// 102 // LLVMFunctionType. 103 //===----------------------------------------------------------------------===// 104 105 /// LLVM dialect function type. It consists of a single return type (unlike MLIR 106 /// which can have multiple), a list of parameter types and can optionally be 107 /// variadic. 108 class LLVMFunctionType 109 : public Type::TypeBase<LLVMFunctionType, Type, 110 detail::LLVMFunctionTypeStorage> { 111 public: 112 /// Inherit base constructors. 113 using Base::Base; 114 using Base::getChecked; 115 116 /// Checks if the given type can be used an argument in a function type. 117 static bool isValidArgumentType(Type type); 118 119 /// Checks if the given type can be used as a result in a function type. 120 static bool isValidResultType(Type type); 121 122 /// Returns whether the function is variadic. 123 bool isVarArg(); 124 125 /// Gets or creates an instance of LLVM dialect function in the same context 126 /// as the `result` type. 127 static LLVMFunctionType get(Type result, ArrayRef<Type> arguments, 128 bool isVarArg = false); 129 static LLVMFunctionType 130 getChecked(function_ref<InFlightDiagnostic()> emitError, Type result, 131 ArrayRef<Type> arguments, bool isVarArg = false); 132 133 /// Returns the result type of the function. 134 Type getReturnType(); 135 136 /// Returns the number of arguments to the function. 137 unsigned getNumParams(); 138 139 /// Returns `i`-th argument of the function. Asserts on out-of-bounds. 140 Type getParamType(unsigned i); 141 142 /// Returns a list of argument types of the function. 143 ArrayRef<Type> getParams(); params()144 ArrayRef<Type> params() { return getParams(); } 145 146 /// Verifies that the type about to be constructed is well-formed. 147 static LogicalResult verify(function_ref<InFlightDiagnostic()> emitError, 148 Type result, ArrayRef<Type> arguments, bool); 149 }; 150 151 //===----------------------------------------------------------------------===// 152 // LLVMPointerType. 153 //===----------------------------------------------------------------------===// 154 155 /// LLVM dialect pointer type. This type typically represents a reference to an 156 /// object in memory. It is parameterized by the element type and the address 157 /// space. 158 class LLVMPointerType : public Type::TypeBase<LLVMPointerType, Type, 159 detail::LLVMPointerTypeStorage, 160 DataLayoutTypeInterface::Trait> { 161 public: 162 /// Inherit base constructors. 163 using Base::Base; 164 using Base::getChecked; 165 166 /// Checks if the given type can have a pointer type pointing to it. 167 static bool isValidElementType(Type type); 168 169 /// Gets or creates an instance of LLVM dialect pointer type pointing to an 170 /// object of `pointee` type in the given address space. The pointer type is 171 /// created in the same context as `pointee`. 172 static LLVMPointerType get(Type pointee, unsigned addressSpace = 0); 173 static LLVMPointerType 174 getChecked(function_ref<InFlightDiagnostic()> emitError, Type pointee, 175 unsigned addressSpace = 0); 176 177 /// Returns the pointed-to type. 178 Type getElementType() const; 179 180 /// Returns the address space of the pointer. 181 unsigned getAddressSpace() const; 182 183 /// Verifies that the type about to be constructed is well-formed. 184 static LogicalResult verify(function_ref<InFlightDiagnostic()> emitError, 185 Type pointee, unsigned); 186 187 /// Hooks for DataLayoutTypeInterface. Should not be called directly. Obtain a 188 /// DataLayout instance and query it instead. 189 unsigned getTypeSizeInBits(const DataLayout &dataLayout, 190 DataLayoutEntryListRef params) const; 191 unsigned getABIAlignment(const DataLayout &dataLayout, 192 DataLayoutEntryListRef params) const; 193 unsigned getPreferredAlignment(const DataLayout &dataLayout, 194 DataLayoutEntryListRef params) const; 195 bool areCompatible(DataLayoutEntryListRef oldLayout, 196 DataLayoutEntryListRef newLayout) const; 197 LogicalResult verifyEntries(DataLayoutEntryListRef entries, 198 Location loc) const; 199 }; 200 201 //===----------------------------------------------------------------------===// 202 // LLVMStructType. 203 //===----------------------------------------------------------------------===// 204 205 /// LLVM dialect structure type representing a collection of different-typed 206 /// elements manipulated together. Structured can optionally be packed, meaning 207 /// that their elements immediately follow each other in memory without 208 /// accounting for potential alignment. 209 /// 210 /// Structure types can be identified (named) or literal. Literal structures 211 /// are uniquely represented by the list of types they contain and packedness. 212 /// Literal structure types are immutable after construction. 213 /// 214 /// Identified structures are uniquely represented by their name, a string. They 215 /// have a mutable component, consisting of the list of types they contain, 216 /// the packedness and the opacity bits. Identified structs can be created 217 /// without providing the lists of element types, making them suitable to 218 /// represent recursive, i.e. self-referring, structures. Identified structs 219 /// without body are considered opaque. For such structs, one can set the body. 220 /// Identified structs can be created as intentionally-opaque, implying that the 221 /// caller does not intend to ever set the body (e.g. forward-declarations of 222 /// structs from another module) and wants to disallow further modification of 223 /// the body. For intentionally-opaque structs or non-opaque structs with the 224 /// body, one is not allowed to set another body (however, one can set exactly 225 /// the same body). 226 /// 227 /// Note that the packedness of the struct takes place in uniquing of literal 228 /// structs, but does not in uniquing of identified structs. 229 class LLVMStructType : public Type::TypeBase<LLVMStructType, Type, 230 detail::LLVMStructTypeStorage> { 231 public: 232 /// Inherit base constructors. 233 using Base::Base; 234 235 /// Checks if the given type can be contained in a structure type. 236 static bool isValidElementType(Type type); 237 238 /// Gets or creates an identified struct with the given name in the provided 239 /// context. Note that unlike llvm::StructType::create, this function will 240 /// _NOT_ rename a struct in case a struct with the same name already exists 241 /// in the context. Instead, it will just return the existing struct, 242 /// similarly to the rest of MLIR type ::get methods. 243 static LLVMStructType getIdentified(MLIRContext *context, StringRef name); 244 static LLVMStructType 245 getIdentifiedChecked(function_ref<InFlightDiagnostic()> emitError, 246 MLIRContext *context, StringRef name); 247 248 /// Gets a new identified struct with the given body. The body _cannot_ be 249 /// changed later. If a struct with the given name already exists, renames 250 /// the struct by appending a `.` followed by a number to the name. Renaming 251 /// happens even if the existing struct has the same body. 252 static LLVMStructType getNewIdentified(MLIRContext *context, StringRef name, 253 ArrayRef<Type> elements, 254 bool isPacked = false); 255 256 /// Gets or creates a literal struct with the given body in the provided 257 /// context. 258 static LLVMStructType getLiteral(MLIRContext *context, ArrayRef<Type> types, 259 bool isPacked = false); 260 static LLVMStructType 261 getLiteralChecked(function_ref<InFlightDiagnostic()> emitError, 262 MLIRContext *context, ArrayRef<Type> types, 263 bool isPacked = false); 264 265 /// Gets or creates an intentionally-opaque identified struct. Such a struct 266 /// cannot have its body set. To create an opaque struct with a mutable body, 267 /// use `getIdentified`. Note that unlike llvm::StructType::create, this 268 /// function will _NOT_ rename a struct in case a struct with the same name 269 /// already exists in the context. Instead, it will just return the existing 270 /// struct, similarly to the rest of MLIR type ::get methods. 271 static LLVMStructType getOpaque(StringRef name, MLIRContext *context); 272 static LLVMStructType 273 getOpaqueChecked(function_ref<InFlightDiagnostic()> emitError, 274 MLIRContext *context, StringRef name); 275 276 /// Set the body of an identified struct. Returns failure if the body could 277 /// not be set, e.g. if the struct already has a body or if it was marked as 278 /// intentionally opaque. This might happen in a multi-threaded context when a 279 /// different thread modified the struct after it was created. Most callers 280 /// are likely to assert this always succeeds, but it is possible to implement 281 /// a local renaming scheme based on the result of this call. 282 LogicalResult setBody(ArrayRef<Type> types, bool isPacked); 283 284 /// Checks if a struct is packed. 285 bool isPacked(); 286 287 /// Checks if a struct is identified. 288 bool isIdentified(); 289 290 /// Checks if a struct is opaque. 291 bool isOpaque(); 292 293 /// Checks if a struct is initialized. 294 bool isInitialized(); 295 296 /// Returns the name of an identified struct. 297 StringRef getName(); 298 299 /// Returns the list of element types contained in a non-opaque struct. 300 ArrayRef<Type> getBody(); 301 302 /// Verifies that the type about to be constructed is well-formed. 303 static LogicalResult verify(function_ref<InFlightDiagnostic()> emitError, 304 StringRef, bool); 305 static LogicalResult verify(function_ref<InFlightDiagnostic()> emitError, 306 ArrayRef<Type> types, bool); 307 }; 308 309 //===----------------------------------------------------------------------===// 310 // LLVMVectorType. 311 //===----------------------------------------------------------------------===// 312 313 /// LLVM dialect vector type, represents a sequence of elements that can be 314 /// processed as one, typically in SIMD context. This is a base class for fixed 315 /// and scalable vectors. 316 class LLVMVectorType : public Type { 317 public: 318 /// Inherit base constructor. 319 using Type::Type; 320 321 /// Support type casting functionality. 322 static bool classof(Type type); 323 324 /// Checks if the given type can be used in a vector type. 325 static bool isValidElementType(Type type); 326 327 /// Returns the element type of the vector. 328 Type getElementType(); 329 330 /// Returns the number of elements in the vector. 331 llvm::ElementCount getElementCount(); 332 333 /// Verifies that the type about to be constructed is well-formed. 334 static LogicalResult verify(function_ref<InFlightDiagnostic()> emitError, 335 Type elementType, unsigned numElements); 336 }; 337 338 //===----------------------------------------------------------------------===// 339 // LLVMFixedVectorType. 340 //===----------------------------------------------------------------------===// 341 342 /// LLVM dialect fixed vector type, represents a sequence of elements of known 343 /// length that can be processed as one. 344 class LLVMFixedVectorType 345 : public Type::TypeBase<LLVMFixedVectorType, Type, 346 detail::LLVMTypeAndSizeStorage> { 347 public: 348 /// Inherit base constructor. 349 using Base::Base; 350 using Base::getChecked; 351 352 /// Gets or creates a fixed vector type containing `numElements` of 353 /// `elementType` in the same context as `elementType`. 354 static LLVMFixedVectorType get(Type elementType, unsigned numElements); 355 static LLVMFixedVectorType 356 getChecked(function_ref<InFlightDiagnostic()> emitError, Type elementType, 357 unsigned numElements); 358 359 /// Checks if the given type can be used in a vector type. This type supports 360 /// only a subset of LLVM dialect types that don't have a built-in 361 /// counter-part, e.g., pointers. 362 static bool isValidElementType(Type type); 363 364 /// Returns the element type of the vector. 365 Type getElementType(); 366 367 /// Returns the number of elements in the fixed vector. 368 unsigned getNumElements(); 369 370 /// Verifies that the type about to be constructed is well-formed. 371 static LogicalResult verify(function_ref<InFlightDiagnostic()> emitError, 372 Type elementType, unsigned numElements); 373 }; 374 375 //===----------------------------------------------------------------------===// 376 // LLVMScalableVectorType. 377 //===----------------------------------------------------------------------===// 378 379 /// LLVM dialect scalable vector type, represents a sequence of elements of 380 /// unknown length that is known to be divisible by some constant. These 381 /// elements can be processed as one in SIMD context. 382 class LLVMScalableVectorType 383 : public Type::TypeBase<LLVMScalableVectorType, Type, 384 detail::LLVMTypeAndSizeStorage> { 385 public: 386 /// Inherit base constructor. 387 using Base::Base; 388 using Base::getChecked; 389 390 /// Gets or creates a scalable vector type containing a non-zero multiple of 391 /// `minNumElements` of `elementType` in the same context as `elementType`. 392 static LLVMScalableVectorType get(Type elementType, unsigned minNumElements); 393 static LLVMScalableVectorType 394 getChecked(function_ref<InFlightDiagnostic()> emitError, Type elementType, 395 unsigned minNumElements); 396 397 /// Checks if the given type can be used in a vector type. 398 static bool isValidElementType(Type type); 399 400 /// Returns the element type of the vector. 401 Type getElementType(); 402 403 /// Returns the scaling factor of the number of elements in the vector. The 404 /// vector contains at least the resulting number of elements, or any non-zero 405 /// multiple of this number. 406 unsigned getMinNumElements(); 407 408 /// Verifies that the type about to be constructed is well-formed. 409 static LogicalResult verify(function_ref<InFlightDiagnostic()> emitError, 410 Type elementType, unsigned minNumElements); 411 }; 412 413 //===----------------------------------------------------------------------===// 414 // Printing and parsing. 415 //===----------------------------------------------------------------------===// 416 417 namespace detail { 418 /// Parses an LLVM dialect type. 419 Type parseType(DialectAsmParser &parser); 420 421 /// Prints an LLVM Dialect type. 422 void printType(Type type, DialectAsmPrinter &printer); 423 } // namespace detail 424 425 //===----------------------------------------------------------------------===// 426 // Utility functions. 427 //===----------------------------------------------------------------------===// 428 429 /// Returns `true` if the given type is compatible with the LLVM dialect. 430 bool isCompatibleType(Type type); 431 432 /// Returns `true` if the given type is a floating-point type compatible with 433 /// the LLVM dialect. 434 bool isCompatibleFloatingPointType(Type type); 435 436 /// Returns `true` if the given type is a vector type compatible with the LLVM 437 /// dialect. Compatible types include 1D built-in vector types of built-in 438 /// integers and floating-point values, LLVM dialect fixed vector types of LLVM 439 /// dialect pointers and LLVM dialect scalable vector types. 440 bool isCompatibleVectorType(Type type); 441 442 /// Returns the element type of any vector type compatible with the LLVM 443 /// dialect. 444 Type getVectorElementType(Type type); 445 446 /// Returns the element count of any LLVM-compatible vector type. 447 llvm::ElementCount getVectorNumElements(Type type); 448 449 /// Creates an LLVM dialect-compatible type with the given element type and 450 /// length. 451 Type getFixedVectorType(Type elementType, unsigned numElements); 452 453 /// Returns the size of the given primitive LLVM dialect-compatible type 454 /// (including vectors) in bits, for example, the size of i16 is 16 and 455 /// the size of vector<4xi16> is 64. Returns 0 for non-primitive 456 /// (aggregates such as struct) or types that don't have a size (such as void). 457 llvm::TypeSize getPrimitiveTypeSizeInBits(Type type); 458 459 } // namespace LLVM 460 } // namespace mlir 461 462 #endif // MLIR_DIALECT_LLVMIR_LLVMTYPES_H_ 463