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 verify(function_ref<InFlightDiagnostic()> emitError,
184  StringRef, bool);
185  static LogicalResult verify(function_ref<InFlightDiagnostic()> emitError,
186  ArrayRef<Type> types, bool);
187  using Base::verify;
188 
189  /// Hooks for DataLayoutTypeInterface. Should not be called directly. Obtain a
190  /// DataLayout instance and query it instead.
191  llvm::TypeSize getTypeSizeInBits(const DataLayout &dataLayout,
192  DataLayoutEntryListRef params) const;
193 
194  uint64_t getABIAlignment(const DataLayout &dataLayout,
195  DataLayoutEntryListRef params) const;
196 
197  uint64_t getPreferredAlignment(const DataLayout &dataLayout,
198  DataLayoutEntryListRef params) const;
199 
200  bool areCompatible(DataLayoutEntryListRef oldLayout,
201  DataLayoutEntryListRef newLayout) const;
202 
203  LogicalResult verifyEntries(DataLayoutEntryListRef entries,
204  Location loc) const;
205 
206  /// Destructs the struct into its indexed field types.
207  std::optional<DenseMap<Attribute, Type>> getSubelementIndexMap();
208 
209  /// Returns which type is stored at a given integer index within the struct.
211 };
212 
213 //===----------------------------------------------------------------------===//
214 // Printing and parsing.
215 //===----------------------------------------------------------------------===//
216 
217 namespace detail {
218 /// Parses an LLVM dialect type.
220 
221 /// Prints an LLVM Dialect type.
222 void printType(Type type, AsmPrinter &printer);
223 } // namespace detail
224 
225 /// Parse any MLIR type or a concise syntax for LLVM types.
226 ParseResult parsePrettyLLVMType(AsmParser &p, Type &type);
227 /// Print any MLIR type or a concise syntax for LLVM types.
228 void printPrettyLLVMType(AsmPrinter &p, Type type);
229 
230 //===----------------------------------------------------------------------===//
231 // Utility functions.
232 //===----------------------------------------------------------------------===//
233 
234 /// Returns `true` if the given type is compatible with the LLVM dialect. This
235 /// is an alias to `LLVMDialect::isCompatibleType`.
236 bool isCompatibleType(Type type);
237 
238 /// Returns `true` if the given outer type is compatible with the LLVM dialect
239 /// without checking its potential nested types such as struct elements.
240 bool isCompatibleOuterType(Type type);
241 
242 /// Returns `true` if the given type is a floating-point type compatible with
243 /// the LLVM dialect.
245 
246 /// Returns `true` if the given type is a vector type compatible with the LLVM
247 /// dialect. Compatible types include 1D built-in vector types of built-in
248 /// integers and floating-point values, LLVM dialect fixed vector types of LLVM
249 /// dialect pointers and LLVM dialect scalable vector types.
250 bool isCompatibleVectorType(Type type);
251 
252 /// Returns the element type of any vector type compatible with the LLVM
253 /// dialect.
255 
256 /// Returns the element count of any LLVM-compatible vector type.
257 llvm::ElementCount getVectorNumElements(Type type);
258 
259 /// Returns whether a vector type is scalable or not.
260 bool isScalableVectorType(Type vectorType);
261 
262 /// Creates an LLVM dialect-compatible vector type with the given element type
263 /// and length.
264 Type getVectorType(Type elementType, unsigned numElements,
265  bool isScalable = false);
266 
267 /// Creates an LLVM dialect-compatible vector type with the given element type
268 /// and length.
269 Type getVectorType(Type elementType, const llvm::ElementCount &numElements);
270 
271 /// Creates an LLVM dialect-compatible type with the given element type and
272 /// length.
273 Type getFixedVectorType(Type elementType, unsigned numElements);
274 
275 /// Creates an LLVM dialect-compatible type with the given element type and
276 /// length.
277 Type getScalableVectorType(Type elementType, unsigned numElements);
278 
279 /// Returns the size of the given primitive LLVM dialect-compatible type
280 /// (including vectors) in bits, for example, the size of i16 is 16 and
281 /// the size of vector<4xi16> is 64. Returns 0 for non-primitive
282 /// (aggregates such as struct) or types that don't have a size (such as void).
283 llvm::TypeSize getPrimitiveTypeSizeInBits(Type type);
284 
285 /// The positions of different values in the data layout entry for pointers.
286 enum class PtrDLEntryPos { Size = 0, Abi = 1, Preferred = 2, Index = 3 };
287 
288 /// Returns the value that corresponds to named position `pos` from the
289 /// data layout entry `attr` assuming it's a dense integer elements attribute.
290 /// Returns `std::nullopt` if `pos` is not present in the entry.
291 /// Currently only `PtrDLEntryPos::Index` is optional, and all other positions
292 /// may be assumed to be present.
293 std::optional<uint64_t> extractPointerSpecValue(Attribute attr,
294  PtrDLEntryPos pos);
295 
296 } // namespace LLVM
297 } // namespace mlir
298 
299 #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:313
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:459
LogicalResult setBody(ArrayRef< Type > types, bool isPacked)
Set the body of an identified struct.
Definition: LLVMTypes.cpp:475
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:489
static LLVMStructType getOpaqueChecked(function_ref< InFlightDiagnostic()> emitError, MLIRContext *context, StringRef name)
Definition: LLVMTypes.cpp:470
LogicalResult verifyEntries(DataLayoutEntryListRef entries, Location loc) const
Definition: LLVMTypes.cpp:622
bool isPacked() const
Checks if a struct is packed.
Definition: LLVMTypes.cpp:482
static LLVMStructType getIdentifiedChecked(function_ref< InFlightDiagnostic()> emitError, MLIRContext *context, StringRef name)
Definition: LLVMTypes.cpp:430
ArrayRef< Type > getBody() const
Returns the list of element types contained in a non-opaque struct.
Definition: LLVMTypes.cpp:490
bool isInitialized()
Checks if a struct is initialized.
Definition: LLVMTypes.cpp:488
bool isOpaque()
Checks if a struct is opaque.
Definition: LLVMTypes.cpp:484
static LogicalResult verify(function_ref< InFlightDiagnostic()> emitError, StringRef, bool)
Verifies that the type about to be constructed is well-formed.
Definition: LLVMTypes.cpp:495
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:453
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:436
static LLVMStructType getIdentified(MLIRContext *context, StringRef name)
Gets or creates an identified struct with the given name in the provided context.
Definition: LLVMTypes.cpp:425
static LLVMStructType getOpaque(StringRef name, MLIRContext *context)
Gets or creates an intentionally-opaque identified struct.
Definition: LLVMTypes.cpp:465
uint64_t getPreferredAlignment(const DataLayout &dataLayout, DataLayoutEntryListRef params) const
Definition: LLVMTypes.cpp:588
bool isIdentified() const
Checks if a struct is identified.
Definition: LLVMTypes.cpp:483
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:63
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.
Include the generated interface declarations.
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:926
llvm::TypeSize getPrimitiveTypeSizeInBits(Type type)
Returns the size of the given primitive LLVM dialect-compatible type (including vectors) in bits,...
Definition: LLVMTypes.cpp:979
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:917
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:874
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:953
PtrDLEntryPos
The positions of different values in the data layout entry for pointers.
Definition: LLVMTypes.h:286
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:856
Type getScalableVectorType(Type elementType, unsigned numElements)
Creates an LLVM dialect-compatible type with the given element type and length.
Definition: LLVMTypes.cpp:964
bool isCompatibleFloatingPointType(Type type)
Returns true if the given type is a floating-point type compatible with the LLVM dialect.
Definition: LLVMTypes.cpp:869
llvm::ElementCount getVectorNumElements(Type type)
Returns the element count of any LLVM-compatible vector type.
Definition: LLVMTypes.cpp:899
Type getVectorElementType(Type type)
Returns the element type of any vector type compatible with the LLVM dialect.
Definition: LLVMTypes.cpp:890
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs,...
Definition: Verifier.cpp:421