MLIR  19.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(LLVMX86MMXType, "llvm.x86_mmx");
71 DEFINE_TRIVIAL_LLVM_TYPE(LLVMTokenType, "llvm.token");
72 DEFINE_TRIVIAL_LLVM_TYPE(LLVMLabelType, "llvm.label");
73 DEFINE_TRIVIAL_LLVM_TYPE(LLVMMetadataType, "llvm.metadata");
74 
75 #undef DEFINE_TRIVIAL_LLVM_TYPE
76 
77 //===----------------------------------------------------------------------===//
78 // LLVMStructType.
79 //===----------------------------------------------------------------------===//
80 
81 /// LLVM dialect structure type representing a collection of different-typed
82 /// elements manipulated together. Structured can optionally be packed, meaning
83 /// that their elements immediately follow each other in memory without
84 /// accounting for potential alignment.
85 ///
86 /// Structure types can be identified (named) or literal. Literal structures
87 /// are uniquely represented by the list of types they contain and packedness.
88 /// Literal structure types are immutable after construction.
89 ///
90 /// Identified structures are uniquely represented by their name, a string. They
91 /// have a mutable component, consisting of the list of types they contain,
92 /// the packedness and the opacity bits. Identified structs can be created
93 /// without providing the lists of element types, making them suitable to
94 /// represent recursive, i.e. self-referring, structures. Identified structs
95 /// without body are considered opaque. For such structs, one can set the body.
96 /// Identified structs can be created as intentionally-opaque, implying that the
97 /// caller does not intend to ever set the body (e.g. forward-declarations of
98 /// structs from another module) and wants to disallow further modification of
99 /// the body. For intentionally-opaque structs or non-opaque structs with the
100 /// body, one is not allowed to set another body (however, one can set exactly
101 /// the same body).
102 ///
103 /// Note that the packedness of the struct takes place in uniquing of literal
104 /// structs, but does not in uniquing of identified structs.
106  : public Type::TypeBase<LLVMStructType, Type, detail::LLVMStructTypeStorage,
107  DataLayoutTypeInterface::Trait,
108  DestructurableTypeInterface::Trait,
109  TypeTrait::IsMutable> {
110 public:
111  /// Inherit base constructors.
112  using Base::Base;
113 
114  static constexpr StringLiteral name = "llvm.struct";
115 
116  /// Checks if the given type can be contained in a structure type.
117  static bool isValidElementType(Type type);
118 
119  /// Gets or creates an identified struct with the given name in the provided
120  /// context. Note that unlike llvm::StructType::create, this function will
121  /// _NOT_ rename a struct in case a struct with the same name already exists
122  /// in the context. Instead, it will just return the existing struct,
123  /// similarly to the rest of MLIR type ::get methods.
124  static LLVMStructType getIdentified(MLIRContext *context, StringRef name);
125  static LLVMStructType
127  MLIRContext *context, StringRef name);
128 
129  /// Gets a new identified struct with the given body. The body _cannot_ be
130  /// changed later. If a struct with the given name already exists, renames
131  /// the struct by appending a `.` followed by a number to the name. Renaming
132  /// happens even if the existing struct has the same body.
133  static LLVMStructType getNewIdentified(MLIRContext *context, StringRef name,
134  ArrayRef<Type> elements,
135  bool isPacked = false);
136 
137  /// Gets or creates a literal struct with the given body in the provided
138  /// context.
139  static LLVMStructType getLiteral(MLIRContext *context, ArrayRef<Type> types,
140  bool isPacked = false);
141  static LLVMStructType
143  MLIRContext *context, ArrayRef<Type> types,
144  bool isPacked = false);
145 
146  /// Gets or creates an intentionally-opaque identified struct. Such a struct
147  /// cannot have its body set. To create an opaque struct with a mutable body,
148  /// use `getIdentified`. Note that unlike llvm::StructType::create, this
149  /// function will _NOT_ rename a struct in case a struct with the same name
150  /// already exists in the context. Instead, it will just return the existing
151  /// struct, similarly to the rest of MLIR type ::get methods.
152  static LLVMStructType getOpaque(StringRef name, MLIRContext *context);
153  static LLVMStructType
155  MLIRContext *context, StringRef name);
156 
157  /// Set the body of an identified struct. Returns failure if the body could
158  /// not be set, e.g. if the struct already has a body or if it was marked as
159  /// intentionally opaque. This might happen in a multi-threaded context when a
160  /// different thread modified the struct after it was created. Most callers
161  /// are likely to assert this always succeeds, but it is possible to implement
162  /// a local renaming scheme based on the result of this call.
163  LogicalResult setBody(ArrayRef<Type> types, bool isPacked);
164 
165  /// Checks if a struct is packed.
166  bool isPacked() const;
167 
168  /// Checks if a struct is identified.
169  bool isIdentified() const;
170 
171  /// Checks if a struct is opaque.
172  bool isOpaque();
173 
174  /// Checks if a struct is initialized.
175  bool isInitialized();
176 
177  /// Returns the name of an identified struct.
178  StringRef getName();
179 
180  /// Returns the list of element types contained in a non-opaque struct.
181  ArrayRef<Type> getBody() const;
182 
183  /// Verifies that the type about to be constructed is well-formed.
184  static LogicalResult verify(function_ref<InFlightDiagnostic()> emitError,
185  StringRef, bool);
186  static LogicalResult verify(function_ref<InFlightDiagnostic()> emitError,
187  ArrayRef<Type> types, bool);
188  using Base::verify;
189 
190  /// Hooks for DataLayoutTypeInterface. Should not be called directly. Obtain a
191  /// DataLayout instance and query it instead.
192  llvm::TypeSize getTypeSizeInBits(const DataLayout &dataLayout,
193  DataLayoutEntryListRef params) const;
194 
195  uint64_t getABIAlignment(const DataLayout &dataLayout,
196  DataLayoutEntryListRef params) const;
197 
198  uint64_t getPreferredAlignment(const DataLayout &dataLayout,
199  DataLayoutEntryListRef params) const;
200 
201  bool areCompatible(DataLayoutEntryListRef oldLayout,
202  DataLayoutEntryListRef newLayout) const;
203 
204  LogicalResult verifyEntries(DataLayoutEntryListRef entries,
205  Location loc) const;
206 
207  /// Destructs the struct into its indexed field types.
208  std::optional<DenseMap<Attribute, Type>> getSubelementIndexMap();
209 
210  /// Returns which type is stored at a given integer index within the struct.
212 };
213 
214 //===----------------------------------------------------------------------===//
215 // Printing and parsing.
216 //===----------------------------------------------------------------------===//
217 
218 namespace detail {
219 /// Parses an LLVM dialect type.
221 
222 /// Prints an LLVM Dialect type.
223 void printType(Type type, AsmPrinter &printer);
224 } // namespace detail
225 
226 /// Parse any MLIR type or a concise syntax for LLVM types.
227 ParseResult parsePrettyLLVMType(AsmParser &p, Type &type);
228 /// Print any MLIR type or a concise syntax for LLVM types.
229 void printPrettyLLVMType(AsmPrinter &p, Type type);
230 
231 //===----------------------------------------------------------------------===//
232 // Utility functions.
233 //===----------------------------------------------------------------------===//
234 
235 /// Returns `true` if the given type is compatible with the LLVM dialect. This
236 /// is an alias to `LLVMDialect::isCompatibleType`.
237 bool isCompatibleType(Type type);
238 
239 /// Returns `true` if the given outer type is compatible with the LLVM dialect
240 /// without checking its potential nested types such as struct elements.
241 bool isCompatibleOuterType(Type type);
242 
243 /// Returns `true` if the given type is a floating-point type compatible with
244 /// the LLVM dialect.
246 
247 /// Returns `true` if the given type is a vector type compatible with the LLVM
248 /// dialect. Compatible types include 1D built-in vector types of built-in
249 /// integers and floating-point values, LLVM dialect fixed vector types of LLVM
250 /// dialect pointers and LLVM dialect scalable vector types.
251 bool isCompatibleVectorType(Type type);
252 
253 /// Returns the element type of any vector type compatible with the LLVM
254 /// dialect.
256 
257 /// Returns the element count of any LLVM-compatible vector type.
258 llvm::ElementCount getVectorNumElements(Type type);
259 
260 /// Returns whether a vector type is scalable or not.
261 bool isScalableVectorType(Type vectorType);
262 
263 /// Creates an LLVM dialect-compatible vector type with the given element type
264 /// and length.
265 Type getVectorType(Type elementType, unsigned numElements,
266  bool isScalable = false);
267 
268 /// Creates an LLVM dialect-compatible vector type with the given element type
269 /// and length.
270 Type getVectorType(Type elementType, const llvm::ElementCount &numElements);
271 
272 /// Creates an LLVM dialect-compatible type with the given element type and
273 /// length.
274 Type getFixedVectorType(Type elementType, unsigned numElements);
275 
276 /// Creates an LLVM dialect-compatible type with the given element type and
277 /// length.
278 Type getScalableVectorType(Type elementType, unsigned numElements);
279 
280 /// Returns the size of the given primitive LLVM dialect-compatible type
281 /// (including vectors) in bits, for example, the size of i16 is 16 and
282 /// the size of vector<4xi16> is 64. Returns 0 for non-primitive
283 /// (aggregates such as struct) or types that don't have a size (such as void).
284 llvm::TypeSize getPrimitiveTypeSizeInBits(Type type);
285 
286 /// The positions of different values in the data layout entry for pointers.
287 enum class PtrDLEntryPos { Size = 0, Abi = 1, Preferred = 2, Index = 3 };
288 
289 /// Returns the value that corresponds to named position `pos` from the
290 /// data layout entry `attr` assuming it's a dense integer elements attribute.
291 /// Returns `std::nullopt` if `pos` is not present in the entry.
292 /// Currently only `PtrDLEntryPos::Index` is optional, and all other positions
293 /// may be assumed to be present.
294 std::optional<uint64_t> extractPointerSpecValue(Attribute attr,
295  PtrDLEntryPos pos);
296 
297 } // namespace LLVM
298 } // namespace mlir
299 
300 #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:307
LLVM dialect structure type representing a collection of different-typed elements manipulated togethe...
Definition: LLVMTypes.h:109
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:114
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: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:287
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.
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs,...
Definition: Verifier.cpp:421