MLIR  18.0.0git
TypeConverter.h
Go to the documentation of this file.
1 //===- TypeConverter.h - Convert builtin to 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 // Provides a type converter configuration for converting most builtin types to
10 // LLVM dialect types.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef MLIR_CONVERSION_LLVMCOMMON_TYPECONVERTER_H
15 #define MLIR_CONVERSION_LLVMCOMMON_TYPECONVERTER_H
16 
19 
20 namespace mlir {
21 
22 class DataLayoutAnalysis;
23 class LowerToLLVMOptions;
24 
25 namespace LLVM {
26 class LLVMDialect;
27 class LLVMPointerType;
28 class LLVMFunctionType;
29 class LLVMStructType;
30 } // namespace LLVM
31 
32 /// Conversion from types to the LLVM IR dialect.
34  /// Give structFuncArgTypeConverter access to memref-specific functions.
35  friend LogicalResult
37  SmallVectorImpl<Type> &result);
38 
39 public:
41 
42  /// Create an LLVMTypeConverter using the default LowerToLLVMOptions.
43  /// Optionally takes a data layout analysis to use in conversions.
45  const DataLayoutAnalysis *analysis = nullptr);
46 
47  /// Create an LLVMTypeConverter using custom LowerToLLVMOptions. Optionally
48  /// takes a data layout analysis to use in conversions.
50  const DataLayoutAnalysis *analysis = nullptr);
51 
52  /// Convert a function type. The arguments and results are converted one by
53  /// one and results are packed into a wrapped LLVM IR structure type. `result`
54  /// is populated with argument mapping.
55  Type convertFunctionSignature(FunctionType funcTy, bool isVariadic,
56  bool useBarePtrCallConv,
57  SignatureConversion &result) const;
58 
59  /// Convert a non-empty list of types to be returned from a function into an
60  /// LLVM-compatible type. In particular, if more than one value is returned,
61  /// create an LLVM dialect structure type with elements that correspond to
62  /// each of the types converted with `convertCallingConventionType`.
64  bool useBarePointerCallConv = false) const;
65 
66  /// Convert a non-empty list of types of values produced by an operation into
67  /// an LLVM-compatible type. In particular, if more than one value is
68  /// produced, create a literal structure with elements that correspond to each
69  /// of the LLVM-compatible types converted with `convertType`.
70  Type packOperationResults(TypeRange types) const;
71 
72  /// Convert a type in the context of the default or bare pointer calling
73  /// convention. Calling convention sensitive types, such as MemRefType and
74  /// UnrankedMemRefType, are converted following the specific rules for the
75  /// calling convention. Calling convention independent types are converted
76  /// following the default LLVM type conversions.
78  bool useBarePointerCallConv = false) const;
79 
80  /// Promote the bare pointers in 'values' that resulted from memrefs to
81  /// descriptors. 'stdTypes' holds the types of 'values' before the conversion
82  /// to the LLVM-IR dialect (i.e., MemRefType, or any other builtin type).
84  Location loc, ArrayRef<Type> stdTypes,
85  SmallVectorImpl<Value> &values) const;
86 
87  /// Returns the MLIR context.
88  MLIRContext &getContext() const;
89 
90  /// Returns the LLVM dialect.
91  LLVM::LLVMDialect *getDialect() const { return llvmDialect; }
92 
93  const LowerToLLVMOptions &getOptions() const { return options; }
94 
95  /// Promote the LLVM representation of all operands including promoting MemRef
96  /// descriptors to stack and use pointers to struct to avoid the complexity
97  /// of the platform-specific C/C++ ABI lowering related to struct argument
98  /// passing.
100  ValueRange operands, OpBuilder &builder,
101  bool useBarePtrCallConv = false) const;
102 
103  /// Promote the LLVM struct representation of one MemRef descriptor to stack
104  /// and use pointer to struct to avoid the complexity of the platform-specific
105  /// C/C++ ABI lowering related to struct argument passing.
107  OpBuilder &builder) const;
108 
109  /// Converts the function type to a C-compatible format, in particular using
110  /// pointers to memref descriptors for arguments. Also converts the return
111  /// type to a pointer argument if it is a struct. Returns true if this
112  /// was the case.
113  std::pair<LLVM::LLVMFunctionType, LLVM::LLVMStructType>
114  convertFunctionTypeCWrapper(FunctionType type) const;
115 
116  /// Returns the data layout to use during and after conversion.
117  const llvm::DataLayout &getDataLayout() const { return options.dataLayout; }
118 
119  /// Returns the data layout analysis to query during conversion.
121  return dataLayoutAnalysis;
122  }
123 
124  /// Gets the LLVM representation of the index type. The returned type is an
125  /// integer type with the size configured for this type converter.
126  Type getIndexType() const;
127 
128  /// Returns true if using opaque pointers was enabled in the lowering options.
129  bool useOpaquePointers() const { return getOptions().useOpaquePointers; }
130 
131  /// Creates an LLVM pointer type with the given element type and address
132  /// space.
133  /// This function is meant to be used in code supporting both typed and opaque
134  /// pointers, as it will create an opaque pointer with the given address space
135  /// if opaque pointers are enabled in the lowering options.
136  LLVM::LLVMPointerType getPointerType(Type elementType,
137  unsigned addressSpace = 0) const;
138 
139  /// Gets the bitwidth of the index type when converted to LLVM.
140  unsigned getIndexTypeBitwidth() const { return options.getIndexBitwidth(); }
141 
142  /// Gets the pointer bitwidth.
143  unsigned getPointerBitwidth(unsigned addressSpace = 0) const;
144 
145  /// Returns the size of the memref descriptor object in bytes.
146  unsigned getMemRefDescriptorSize(MemRefType type,
147  const DataLayout &layout) const;
148 
149  /// Returns the size of the unranked memref descriptor object in bytes.
151  const DataLayout &layout) const;
152 
153  /// Return the LLVM address space corresponding to the memory space of the
154  /// memref type `type` or failure if the memory space cannot be converted to
155  /// an integer.
157 
158  /// Check if a memref type can be converted to a bare pointer.
159  static bool canConvertToBarePtr(BaseMemRefType type);
160 
161 protected:
162  /// Pointer to the LLVM dialect.
163  LLVM::LLVMDialect *llvmDialect;
164 
165  // Recursive structure detection.
166  // We store one entry per thread here, and rely on locking.
168  llvm::sys::SmartRWMutex<true> callStackMutex;
170 
171 private:
172  /// Convert a function type. The arguments and results are converted one by
173  /// one. Additionally, if the function returns more than one value, pack the
174  /// results into an LLVM IR structure type so that the converted function type
175  /// returns at most one result.
176  Type convertFunctionType(FunctionType type) const;
177 
178  /// Convert the index type. Uses llvmModule data layout to create an integer
179  /// of the pointer bitwidth.
180  Type convertIndexType(IndexType type) const;
181 
182  /// Convert an integer type `i*` to `!llvm<"i*">`.
183  Type convertIntegerType(IntegerType type) const;
184 
185  /// Convert a floating point type: `f16` to `f16`, `f32` to
186  /// `f32` and `f64` to `f64`. `bf16` is not supported
187  /// by LLVM. 8-bit float types are converted to 8-bit integers as this is how
188  /// all LLVM backends that support them currently represent them.
189  Type convertFloatType(FloatType type) const;
190 
191  /// Convert complex number type: `complex<f16>` to `!llvm<"{ half, half }">`,
192  /// `complex<f32>` to `!llvm<"{ float, float }">`, and `complex<f64>` to
193  /// `!llvm<"{ double, double }">`. `complex<bf16>` is not supported.
194  Type convertComplexType(ComplexType type) const;
195 
196  /// Convert a memref type into an LLVM type that captures the relevant data.
197  Type convertMemRefType(MemRefType type) const;
198 
199  /// Convert a memref type into a list of LLVM IR types that will form the
200  /// memref descriptor. If `unpackAggregates` is true the `sizes` and `strides`
201  /// arrays in the descriptors are unpacked to individual index-typed elements,
202  /// else they are kept as rank-sized arrays of index type. In particular,
203  /// the list will contain:
204  /// - two pointers to the memref element type, followed by
205  /// - an index-typed offset, followed by
206  /// - (if unpackAggregates = true)
207  /// - one index-typed size per dimension of the memref, followed by
208  /// - one index-typed stride per dimension of the memref.
209  /// - (if unpackArrregates = false)
210  /// - one rank-sized array of index-type for the size of each dimension
211  /// - one rank-sized array of index-type for the stride of each dimension
212  ///
213  /// For example, memref<?x?xf32> is converted to the following list:
214  /// - `!llvm<"float*">` (allocated pointer),
215  /// - `!llvm<"float*">` (aligned pointer),
216  /// - `i64` (offset),
217  /// - `i64`, `i64` (sizes),
218  /// - `i64`, `i64` (strides).
219  /// These types can be recomposed to a memref descriptor struct.
220  SmallVector<Type, 5> getMemRefDescriptorFields(MemRefType type,
221  bool unpackAggregates) const;
222 
223  /// Convert an unranked memref type into a list of non-aggregate LLVM IR types
224  /// that will form the unranked memref descriptor. In particular, this list
225  /// contains:
226  /// - an integer rank, followed by
227  /// - a pointer to the memref descriptor struct.
228  /// For example, memref<*xf32> is converted to the following list:
229  /// i64 (rank)
230  /// !llvm<"i8*"> (type-erased pointer).
231  /// These types can be recomposed to a unranked memref descriptor struct.
232  SmallVector<Type, 2> getUnrankedMemRefDescriptorFields() const;
233 
234  /// Convert an unranked memref type to an LLVM type that captures the
235  /// runtime rank and a pointer to the static ranked memref desc
236  Type convertUnrankedMemRefType(UnrankedMemRefType type) const;
237 
238  /// Convert a memref type to a bare pointer to the memref element type.
239  Type convertMemRefToBarePtr(BaseMemRefType type) const;
240 
241  /// Convert a 1D vector type into an LLVM vector type.
242  FailureOr<Type> convertVectorType(VectorType type) const;
243 
244  /// Options for customizing the llvm lowering.
245  LowerToLLVMOptions options;
246 
247  /// Data layout analysis mapping scopes to layouts active in them.
248  const DataLayoutAnalysis *dataLayoutAnalysis;
249 };
250 
251 /// Callback to convert function argument types. It converts a MemRef function
252 /// argument to a list of non-aggregate types containing descriptor
253 /// information, and an UnrankedmemRef function argument to a list containing
254 /// the rank and a pointer to a descriptor struct.
256  Type type,
257  SmallVectorImpl<Type> &result);
258 
259 /// Callback to convert function argument types. It converts MemRef function
260 /// arguments to bare pointers to the MemRef element type.
262  Type type,
263  SmallVectorImpl<Type> &result);
264 
265 } // namespace mlir
266 
267 #endif // MLIR_CONVERSION_LLVMCOMMON_TYPECONVERTER_H
This class provides a shared interface for ranked and unranked memref types.
Definition: BuiltinTypes.h:137
This class implements a pattern rewriter for use with ConversionPatterns.
Stores data layout objects for each operation that specifies the data layout above and below the give...
The main mechanism for performing data layout queries.
This class provides support for representing a failure result, or a valid value of type T.
Definition: LogicalResult.h:78
Conversion from types to the LLVM IR dialect.
Definition: TypeConverter.h:33
LLVM::LLVMDialect * llvmDialect
Pointer to the LLVM dialect.
llvm::sys::SmartRWMutex< true > callStackMutex
Type packOperationResults(TypeRange types) const
Convert a non-empty list of types of values produced by an operation into an LLVM-compatible type.
LLVM::LLVMDialect * getDialect() const
Returns the LLVM dialect.
Definition: TypeConverter.h:91
Type packFunctionResults(TypeRange types, bool useBarePointerCallConv=false) const
Convert a non-empty list of types to be returned from a function into an LLVM-compatible type.
const LowerToLLVMOptions & getOptions() const
Definition: TypeConverter.h:93
unsigned getUnrankedMemRefDescriptorSize(UnrankedMemRefType type, const DataLayout &layout) const
Returns the size of the unranked memref descriptor object in bytes.
Type convertFunctionSignature(FunctionType funcTy, bool isVariadic, bool useBarePtrCallConv, SignatureConversion &result) const
Convert a function type.
void promoteBarePtrsToDescriptors(ConversionPatternRewriter &rewriter, Location loc, ArrayRef< Type > stdTypes, SmallVectorImpl< Value > &values) const
Promote the bare pointers in 'values' that resulted from memrefs to descriptors.
const DataLayoutAnalysis * getDataLayoutAnalysis() const
Returns the data layout analysis to query during conversion.
DenseMap< uint64_t, std::unique_ptr< SmallVector< Type > > > conversionCallStack
SmallVector< Type > & getCurrentThreadRecursiveStack()
Value promoteOneMemRefDescriptor(Location loc, Value operand, OpBuilder &builder) const
Promote the LLVM struct representation of one MemRef descriptor to stack and use pointer to struct to...
Type convertCallingConventionType(Type type, bool useBarePointerCallConv=false) const
Convert a type in the context of the default or bare pointer calling convention.
SmallVector< Value, 4 > promoteOperands(Location loc, ValueRange opOperands, ValueRange operands, OpBuilder &builder, bool useBarePtrCallConv=false) const
Promote the LLVM representation of all operands including promoting MemRef descriptors to stack and u...
LLVMTypeConverter(MLIRContext *ctx, const DataLayoutAnalysis *analysis=nullptr)
Create an LLVMTypeConverter using the default LowerToLLVMOptions.
unsigned getPointerBitwidth(unsigned addressSpace=0) const
Gets the pointer bitwidth.
FailureOr< unsigned > getMemRefAddressSpace(BaseMemRefType type) const
Return the LLVM address space corresponding to the memory space of the memref type type or failure if...
LLVM::LLVMPointerType getPointerType(Type elementType, unsigned addressSpace=0) const
Creates an LLVM pointer type with the given element type and address space.
const llvm::DataLayout & getDataLayout() const
Returns the data layout to use during and after conversion.
static bool canConvertToBarePtr(BaseMemRefType type)
Check if a memref type can be converted to a bare pointer.
MLIRContext & getContext() const
Returns the MLIR context.
unsigned getMemRefDescriptorSize(MemRefType type, const DataLayout &layout) const
Returns the size of the memref descriptor object in bytes.
std::pair< LLVM::LLVMFunctionType, LLVM::LLVMStructType > convertFunctionTypeCWrapper(FunctionType type) const
Converts the function type to a C-compatible format, in particular using pointers to memref descripto...
unsigned getIndexTypeBitwidth() const
Gets the bitwidth of the index type when converted to LLVM.
Type getIndexType() const
Gets the LLVM representation of the index type.
bool useOpaquePointers() const
Returns true if using opaque pointers was enabled in the lowering options.
friend LogicalResult structFuncArgTypeConverter(const LLVMTypeConverter &converter, Type type, SmallVectorImpl< Type > &result)
Give structFuncArgTypeConverter access to memref-specific functions.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:63
Options to control the LLVM lowering.
llvm::DataLayout dataLayout
The data layout of the module to produce.
unsigned getIndexBitwidth() const
Get the index bitwidth.
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
This class helps build Operations.
Definition: Builders.h:206
This class provides all of the information necessary to convert a type signature.
Type conversion class.
LogicalResult convertType(Type t, SmallVectorImpl< Type > &results) const
Convert the given type.
This class provides an abstraction over the various different ranges of value types.
Definition: TypeRange.h:36
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
This class provides an abstraction over the different types of ranges over Values.
Definition: ValueRange.h:372
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:93
This header declares functions that assist transformations in the MemRef dialect.
LogicalResult barePtrFuncArgTypeConverter(const LLVMTypeConverter &converter, Type type, SmallVectorImpl< Type > &result)
Callback to convert function argument types.
LogicalResult structFuncArgTypeConverter(const LLVMTypeConverter &converter, Type type, SmallVectorImpl< Type > &result)
Callback to convert function argument types.
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26