MLIR  20.0.0git
LLVMTypes.h
Go to the documentation of this file.
1 //===- LLVMTypes.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"
20 #include <optional>
21 
22 namespace llvm {
23 class ElementCount;
24 class TypeSize;
25 } // namespace llvm
26 
27 namespace mlir {
28 
29 class AsmParser;
30 class AsmPrinter;
31 
32 namespace LLVM {
33 class LLVMDialect;
34 
35 namespace detail {
36 struct LLVMFunctionTypeStorage;
37 struct LLVMPointerTypeStorage;
38 struct LLVMStructTypeStorage;
39 struct LLVMTypeAndSizeStorage;
40 } // namespace detail
41 } // namespace LLVM
42 } // namespace mlir
43 
44 //===----------------------------------------------------------------------===//
45 // ODS-Generated Declarations
46 //===----------------------------------------------------------------------===//
47 
48 #include "mlir/Dialect/LLVMIR/LLVMTypeInterfaces.h.inc"
49 
50 #define GET_TYPEDEF_CLASSES
51 #include "mlir/Dialect/LLVMIR/LLVMTypes.h.inc"
52 
53 namespace mlir {
54 namespace LLVM {
55 
56 //===----------------------------------------------------------------------===//
57 // Trivial types.
58 //===----------------------------------------------------------------------===//
59 
60 // Batch-define trivial types.
61 #define DEFINE_TRIVIAL_LLVM_TYPE(ClassName, TypeName) \
62  class ClassName : public Type::TypeBase<ClassName, Type, TypeStorage> { \
63  public: \
64  using Base::Base; \
65  static constexpr StringLiteral name = TypeName; \
66  }
67 
68 DEFINE_TRIVIAL_LLVM_TYPE(LLVMVoidType, "llvm.void");
69 DEFINE_TRIVIAL_LLVM_TYPE(LLVMPPCFP128Type, "llvm.ppc_fp128");
70 DEFINE_TRIVIAL_LLVM_TYPE(LLVMTokenType, "llvm.token");
71 DEFINE_TRIVIAL_LLVM_TYPE(LLVMLabelType, "llvm.label");
72 DEFINE_TRIVIAL_LLVM_TYPE(LLVMMetadataType, "llvm.metadata");
73 
74 #undef DEFINE_TRIVIAL_LLVM_TYPE
75 
76 //===----------------------------------------------------------------------===//
77 // LLVMStructType.
78 //===----------------------------------------------------------------------===//
79 
80 /// LLVM dialect structure type representing a collection of different-typed
81 /// elements manipulated together. Structured can optionally be packed, meaning
82 /// that their elements immediately follow each other in memory without
83 /// accounting for potential alignment.
84 ///
85 /// Structure types can be identified (named) or literal. Literal structures
86 /// are uniquely represented by the list of types they contain and packedness.
87 /// Literal structure types are immutable after construction.
88 ///
89 /// Identified structures are uniquely represented by their name, a string. They
90 /// have a mutable component, consisting of the list of types they contain,
91 /// the packedness and the opacity bits. Identified structs can be created
92 /// without providing the lists of element types, making them suitable to
93 /// represent recursive, i.e. self-referring, structures. Identified structs
94 /// without body are considered opaque. For such structs, one can set the body.
95 /// Identified structs can be created as intentionally-opaque, implying that the
96 /// caller does not intend to ever set the body (e.g. forward-declarations of
97 /// structs from another module) and wants to disallow further modification of
98 /// the body. For intentionally-opaque structs or non-opaque structs with the
99 /// body, one is not allowed to set another body (however, one can set exactly
100 /// the same body).
101 ///
102 /// Note that the packedness of the struct takes place in uniquing of literal
103 /// structs, but does not in uniquing of identified structs.
105  : public Type::TypeBase<LLVMStructType, Type, detail::LLVMStructTypeStorage,
106  DataLayoutTypeInterface::Trait,
107  DestructurableTypeInterface::Trait,
108  TypeTrait::IsMutable> {
109 public:
110  /// Inherit base constructors.
111  using Base::Base;
112 
113  static constexpr StringLiteral name = "llvm.struct";
114 
115  /// Checks if the given type can be contained in a structure type.
116  static bool isValidElementType(Type type);
117 
118  /// Gets or creates an identified struct with the given name in the provided
119  /// context. Note that unlike llvm::StructType::create, this function will
120  /// _NOT_ rename a struct in case a struct with the same name already exists
121  /// in the context. Instead, it will just return the existing struct,
122  /// similarly to the rest of MLIR type ::get methods.
123  static LLVMStructType getIdentified(MLIRContext *context, StringRef name);
124  static LLVMStructType
126  MLIRContext *context, StringRef name);
127 
128  /// Gets a new identified struct with the given body. The body _cannot_ be
129  /// changed later. If a struct with the given name already exists, renames
130  /// the struct by appending a `.` followed by a number to the name. Renaming
131  /// happens even if the existing struct has the same body.
132  static LLVMStructType getNewIdentified(MLIRContext *context, StringRef name,
133  ArrayRef<Type> elements,
134  bool isPacked = false);
135 
136  /// Gets or creates a literal struct with the given body in the provided
137  /// context.
138  static LLVMStructType getLiteral(MLIRContext *context, ArrayRef<Type> types,
139  bool isPacked = false);
140  static LLVMStructType
142  MLIRContext *context, ArrayRef<Type> types,
143  bool isPacked = false);
144 
145  /// Gets or creates an intentionally-opaque identified struct. Such a struct
146  /// cannot have its body set. To create an opaque struct with a mutable body,
147  /// use `getIdentified`. Note that unlike llvm::StructType::create, this
148  /// function will _NOT_ rename a struct in case a struct with the same name
149  /// already exists in the context. Instead, it will just return the existing
150  /// struct, similarly to the rest of MLIR type ::get methods.
151  static LLVMStructType getOpaque(StringRef name, MLIRContext *context);
152  static LLVMStructType
154  MLIRContext *context, StringRef name);
155 
156  /// Set the body of an identified struct. Returns failure if the body could
157  /// not be set, e.g. if the struct already has a body or if it was marked as
158  /// intentionally opaque. This might happen in a multi-threaded context when a
159  /// different thread modified the struct after it was created. Most callers
160  /// are likely to assert this always succeeds, but it is possible to implement
161  /// a local renaming scheme based on the result of this call.
162  LogicalResult setBody(ArrayRef<Type> types, bool isPacked);
163 
164  /// Checks if a struct is packed.
165  bool isPacked() const;
166 
167  /// Checks if a struct is identified.
168  bool isIdentified() const;
169 
170  /// Checks if a struct is opaque.
171  bool isOpaque();
172 
173  /// Checks if a struct is initialized.
174  bool isInitialized();
175 
176  /// Returns the name of an identified struct.
177  StringRef getName();
178 
179  /// Returns the list of element types contained in a non-opaque struct.
180  ArrayRef<Type> getBody() const;
181 
182  /// Verifies that the type about to be constructed is well-formed.
183  static LogicalResult
185  bool);
186  static LogicalResult
188  ArrayRef<Type> types, bool);
189  using Base::verifyInvariants;
190 
191  /// Hooks for DataLayoutTypeInterface. Should not be called directly. Obtain a
192  /// DataLayout instance and query it instead.
193  llvm::TypeSize getTypeSizeInBits(const DataLayout &dataLayout,
194  DataLayoutEntryListRef params) const;
195 
196  uint64_t getABIAlignment(const DataLayout &dataLayout,
197  DataLayoutEntryListRef params) const;
198 
199  uint64_t getPreferredAlignment(const DataLayout &dataLayout,
200  DataLayoutEntryListRef params) const;
201 
202  bool areCompatible(DataLayoutEntryListRef oldLayout,
203  DataLayoutEntryListRef newLayout) const;
204 
205  LogicalResult verifyEntries(DataLayoutEntryListRef entries,
206  Location loc) const;
207 
208  /// Destructs the struct into its indexed field types.
209  std::optional<DenseMap<Attribute, Type>> getSubelementIndexMap();
210 
211  /// Returns which type is stored at a given integer index within the struct.
213 };
214 
215 //===----------------------------------------------------------------------===//
216 // Printing and parsing.
217 //===----------------------------------------------------------------------===//
218 
219 namespace detail {
220 /// Parses an LLVM dialect type.
222 
223 /// Prints an LLVM Dialect type.
224 void printType(Type type, AsmPrinter &printer);
225 } // namespace detail
226 
227 /// Parse any MLIR type or a concise syntax for LLVM types.
228 ParseResult parsePrettyLLVMType(AsmParser &p, Type &type);
229 /// Print any MLIR type or a concise syntax for LLVM types.
230 void printPrettyLLVMType(AsmPrinter &p, Type type);
231 
232 //===----------------------------------------------------------------------===//
233 // Utility functions.
234 //===----------------------------------------------------------------------===//
235 
236 /// Returns `true` if the given type is compatible with the LLVM dialect. This
237 /// is an alias to `LLVMDialect::isCompatibleType`.
238 bool isCompatibleType(Type type);
239 
240 /// Returns `true` if the given outer type is compatible with the LLVM dialect
241 /// without checking its potential nested types such as struct elements.
242 bool isCompatibleOuterType(Type type);
243 
244 /// Returns `true` if the given type is a floating-point type compatible with
245 /// the LLVM dialect.
247 
248 /// Returns `true` if the given type is a vector type compatible with the LLVM
249 /// dialect. Compatible types include 1D built-in vector types of built-in
250 /// integers and floating-point values, LLVM dialect fixed vector types of LLVM
251 /// dialect pointers and LLVM dialect scalable vector types.
252 bool isCompatibleVectorType(Type type);
253 
254 /// Returns the element type of any vector type compatible with the LLVM
255 /// dialect.
257 
258 /// Returns the element count of any LLVM-compatible vector type.
259 llvm::ElementCount getVectorNumElements(Type type);
260 
261 /// Returns whether a vector type is scalable or not.
262 bool isScalableVectorType(Type vectorType);
263 
264 /// Creates an LLVM dialect-compatible vector type with the given element type
265 /// and length.
266 Type getVectorType(Type elementType, unsigned numElements,
267  bool isScalable = false);
268 
269 /// Creates an LLVM dialect-compatible vector type with the given element type
270 /// and length.
271 Type getVectorType(Type elementType, const llvm::ElementCount &numElements);
272 
273 /// Creates an LLVM dialect-compatible type with the given element type and
274 /// length.
275 Type getFixedVectorType(Type elementType, unsigned numElements);
276 
277 /// Creates an LLVM dialect-compatible type with the given element type and
278 /// length.
279 Type getScalableVectorType(Type elementType, unsigned numElements);
280 
281 /// Returns the size of the given primitive LLVM dialect-compatible type
282 /// (including vectors) in bits, for example, the size of i16 is 16 and
283 /// the size of vector<4xi16> is 64. Returns 0 for non-primitive
284 /// (aggregates such as struct) or types that don't have a size (such as void).
285 llvm::TypeSize getPrimitiveTypeSizeInBits(Type type);
286 
287 /// The positions of different values in the data layout entry for pointers.
288 enum class PtrDLEntryPos { Size = 0, Abi = 1, Preferred = 2, Index = 3 };
289 
290 /// Returns the value that corresponds to named position `pos` from the
291 /// data layout entry `attr` assuming it's a dense integer elements attribute.
292 /// Returns `std::nullopt` if `pos` is not present in the entry.
293 /// Currently only `PtrDLEntryPos::Index` is optional, and all other positions
294 /// may be assumed to be present.
295 std::optional<uint64_t> extractPointerSpecValue(Attribute attr,
296  PtrDLEntryPos pos);
297 
298 } // namespace LLVM
299 } // namespace mlir
300 
301 #endif // MLIR_DIALECT_LLVMIR_LLVMTYPES_H_
This base class exposes generic asm parser hooks, usable across the various derived parsers.
This base class exposes generic asm printer hooks, usable across the various derived printers.
Attributes are known-constant values of operations.
Definition: Attributes.h:25
The main mechanism for performing data layout queries.
The DialectAsmParser has methods for interacting with the asm parser when parsing attributes and type...
This class represents a diagnostic that is inflight and set to be reported.
Definition: Diagnostics.h:314
LLVM dialect structure type representing a collection of different-typed elements manipulated togethe...
Definition: LLVMTypes.h:108
static LLVMStructType getLiteralChecked(function_ref< InFlightDiagnostic()> emitError, MLIRContext *context, ArrayRef< Type > types, bool isPacked=false)
Definition: LLVMTypes.cpp:458
LogicalResult setBody(ArrayRef< Type > types, bool isPacked)
Set the body of an identified struct.
Definition: LLVMTypes.cpp:474
static bool isValidElementType(Type type)
Checks if the given type can be contained in a structure type.
Definition: LLVMTypes.cpp:419
Type getTypeAtIndex(Attribute index)
Returns which type is stored at a given integer index within the struct.
uint64_t getABIAlignment(const DataLayout &dataLayout, DataLayoutEntryListRef params) const
Definition: LLVMTypes.cpp:581
StringRef getName()
Returns the name of an identified struct.
Definition: LLVMTypes.cpp:488
static LLVMStructType getOpaqueChecked(function_ref< InFlightDiagnostic()> emitError, MLIRContext *context, StringRef name)
Definition: LLVMTypes.cpp:469
LogicalResult verifyEntries(DataLayoutEntryListRef entries, Location loc) const
Definition: LLVMTypes.cpp:622
bool isPacked() const
Checks if a struct is packed.
Definition: LLVMTypes.cpp:481
static LLVMStructType getIdentifiedChecked(function_ref< InFlightDiagnostic()> emitError, MLIRContext *context, StringRef name)
Definition: LLVMTypes.cpp:429
ArrayRef< Type > getBody() const
Returns the list of element types contained in a non-opaque struct.
Definition: LLVMTypes.cpp:489
bool isInitialized()
Checks if a struct is initialized.
Definition: LLVMTypes.cpp:487
bool isOpaque()
Checks if a struct is opaque.
Definition: LLVMTypes.cpp:483
std::optional< DenseMap< Attribute, Type > > getSubelementIndexMap()
Destructs the struct into its indexed field types.
bool areCompatible(DataLayoutEntryListRef oldLayout, DataLayoutEntryListRef newLayout) const
Definition: LLVMTypes.cpp:599
llvm::TypeSize getTypeSizeInBits(const DataLayout &dataLayout, DataLayoutEntryListRef params) const
Hooks for DataLayoutTypeInterface.
Definition: LLVMTypes.cpp:511
static LLVMStructType getLiteral(MLIRContext *context, ArrayRef< Type > types, bool isPacked=false)
Gets or creates a literal struct with the given body in the provided context.
Definition: LLVMTypes.cpp:452
static LLVMStructType getNewIdentified(MLIRContext *context, StringRef name, ArrayRef< Type > elements, bool isPacked=false)
Gets a new identified struct with the given body.
Definition: LLVMTypes.cpp:435
static LLVMStructType getIdentified(MLIRContext *context, StringRef name)
Gets or creates an identified struct with the given name in the provided context.
Definition: LLVMTypes.cpp:424
static LLVMStructType getOpaque(StringRef name, MLIRContext *context)
Gets or creates an intentionally-opaque identified struct.
Definition: LLVMTypes.cpp:464
uint64_t getPreferredAlignment(const DataLayout &dataLayout, DataLayoutEntryListRef params) const
Definition: LLVMTypes.cpp:588
static LogicalResult verifyInvariants(function_ref< InFlightDiagnostic()> emitError, StringRef, bool)
Verifies that the type about to be constructed is well-formed.
Definition: LLVMTypes.cpp:495
bool isIdentified() const
Checks if a struct is identified.
Definition: LLVMTypes.cpp:482
static constexpr StringLiteral name
Definition: LLVMTypes.h:113
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:66
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
Utility class for implementing users of storage classes uniqued by a StorageUniquer.
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition: CallGraph.h:229
void printType(Type type, AsmPrinter &printer)
Prints an LLVM Dialect type.
Type parseType(DialectAsmParser &parser)
Parses an LLVM dialect type.
Type getVectorType(Type elementType, unsigned numElements, bool isScalable=false)
Creates an LLVM dialect-compatible vector type with the given element type and length.
Definition: LLVMTypes.cpp:928
llvm::TypeSize getPrimitiveTypeSizeInBits(Type type)
Returns the size of the given primitive LLVM dialect-compatible type (including vectors) in bits,...
Definition: LLVMTypes.cpp:981
void printPrettyLLVMType(AsmPrinter &p, Type type)
Print any MLIR type or a concise syntax for LLVM types.
bool isScalableVectorType(Type vectorType)
Returns whether a vector type is scalable or not.
Definition: LLVMTypes.cpp:919
DEFINE_TRIVIAL_LLVM_TYPE(LLVMVoidType, "llvm.void")
ParseResult parsePrettyLLVMType(AsmParser &p, Type &type)
Parse any MLIR type or a concise syntax for LLVM types.
bool isCompatibleVectorType(Type type)
Returns true if the given type is a vector type compatible with the LLVM dialect.
Definition: LLVMTypes.cpp:876
bool isCompatibleOuterType(Type type)
Returns true if the given outer type is compatible with the LLVM dialect without checking its potenti...
Definition: LLVMTypes.cpp:763
Type getFixedVectorType(Type elementType, unsigned numElements)
Creates an LLVM dialect-compatible type with the given element type and length.
Definition: LLVMTypes.cpp:955
PtrDLEntryPos
The positions of different values in the data layout entry for pointers.
Definition: LLVMTypes.h:288
std::optional< uint64_t > extractPointerSpecValue(Attribute attr, PtrDLEntryPos pos)
Returns the value that corresponds to named position pos from the data layout entry attr assuming it'...
Definition: LLVMTypes.cpp:262
bool isCompatibleType(Type type)
Returns true if the given type is compatible with the LLVM dialect.
Definition: LLVMTypes.cpp:858
Type getScalableVectorType(Type elementType, unsigned numElements)
Creates an LLVM dialect-compatible type with the given element type and length.
Definition: LLVMTypes.cpp:966
bool isCompatibleFloatingPointType(Type type)
Returns true if the given type is a floating-point type compatible with the LLVM dialect.
Definition: LLVMTypes.cpp:871
llvm::ElementCount getVectorNumElements(Type type)
Returns the element count of any LLVM-compatible vector type.
Definition: LLVMTypes.cpp:901
Type getVectorElementType(Type type)
Returns the element type of any vector type compatible with the LLVM dialect.
Definition: LLVMTypes.cpp:892
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.