MLIR  22.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 
18 #include "mlir/IR/BuiltinTypes.h"
20 
21 namespace mlir {
22 
23 class DataLayoutAnalysis;
24 class FunctionOpInterface;
25 class LowerToLLVMOptions;
26 
27 namespace LLVM {
28 class LLVMDialect;
29 class LLVMPointerType;
30 class LLVMFunctionType;
31 class LLVMStructType;
32 } // namespace LLVM
33 
34 /// Conversion from types to the LLVM IR dialect.
36  /// Give structFuncArgTypeConverter access to memref-specific functions.
37  friend LogicalResult
39  SmallVectorImpl<Type> &result);
40 
41 public:
43 
44  /// Create an LLVMTypeConverter using the default LowerToLLVMOptions.
45  /// Optionally takes a data layout analysis to use in conversions.
47  const DataLayoutAnalysis *analysis = nullptr);
48 
49  /// Create an LLVMTypeConverter using custom LowerToLLVMOptions. Optionally
50  /// takes a data layout analysis to use in conversions.
52  const DataLayoutAnalysis *analysis = nullptr);
53 
54  /// Convert a function type. The arguments and results are converted one by
55  /// one and results are packed into a wrapped LLVM IR structure type. `result`
56  /// is populated with argument mapping.
57  Type convertFunctionSignature(FunctionType funcTy, bool isVariadic,
58  bool useBarePtrCallConv,
59  SignatureConversion &result) const;
60 
61  /// Convert a function type. The arguments and results are converted one by
62  /// one and results are packed into a wrapped LLVM IR structure type. `result`
63  /// is populated with argument mapping. Converted types of `llvm.byval` and
64  /// `llvm.byref` function arguments which are not LLVM pointers are overridden
65  /// with LLVM pointers. Overridden arguments are returned in
66  /// `byValRefNonPtrAttrs`.
67  Type convertFunctionSignature(FunctionOpInterface funcOp, bool isVariadic,
68  bool useBarePtrCallConv,
70  SmallVectorImpl<std::optional<NamedAttribute>>
71  &byValRefNonPtrAttrs) const;
72 
73  /// Convert a non-empty list of types to be returned from a function into an
74  /// LLVM-compatible type. In particular, if more than one value is returned,
75  /// create an LLVM dialect structure type with elements that correspond to
76  /// each of the types converted with `convertCallingConventionType`.
77  ///
78  /// Populate the converted (unpacked) types into `groupedTypes`, if provided.
79  /// `groupedType` contains one nested vector per input type. In case of a 1:N
80  /// conversion, a nested vector may contain 0 or more then 1 converted type.
81  Type
82  packFunctionResults(TypeRange types, bool useBarePointerCallConv = false,
83  SmallVector<SmallVector<Type>> *groupedTypes = nullptr,
84  int64_t *numConvertedTypes = nullptr) const;
85 
86  /// Convert a non-empty list of types of values produced by an operation into
87  /// an LLVM-compatible type. In particular, if more than one value is
88  /// produced, create a literal structure with elements that correspond to each
89  /// of the LLVM-compatible types converted with `convertType`.
90  Type packOperationResults(TypeRange types) const;
91 
92  /// Convert a type in the context of the default or bare pointer calling
93  /// convention. Calling convention sensitive types, such as MemRefType and
94  /// UnrankedMemRefType, are converted following the specific rules for the
95  /// calling convention. Calling convention independent types are converted
96  /// following the default LLVM type conversions.
97  LogicalResult
99  bool useBarePointerCallConv = false) const;
100 
101  /// Returns the MLIR context.
102  MLIRContext &getContext() const;
103 
104  /// Returns the LLVM dialect.
105  LLVM::LLVMDialect *getDialect() const { return llvmDialect; }
106 
107  const LowerToLLVMOptions &getOptions() const { return options; }
108 
109  /// Promote the LLVM representation of all operands including promoting MemRef
110  /// descriptors to stack and use pointers to struct to avoid the complexity
111  /// of the platform-specific C/C++ ABI lowering related to struct argument
112  /// passing. (The ArrayRef variant is for 1:N.)
114  ArrayRef<ValueRange> adaptorOperands,
115  OpBuilder &builder,
116  bool useBarePtrCallConv = false) const;
118  ValueRange adaptorOperands,
119  OpBuilder &builder,
120  bool useBarePtrCallConv = false) const;
121 
122  /// Promote the LLVM struct representation of one MemRef descriptor to stack
123  /// and use pointer to struct to avoid the complexity of the platform-specific
124  /// C/C++ ABI lowering related to struct argument passing.
126  OpBuilder &builder) const;
127 
128  /// Converts the function type to a C-compatible format, in particular using
129  /// pointers to memref descriptors for arguments. Also converts the return
130  /// type to a pointer argument if it is a struct. Returns true if this
131  /// was the case.
132  std::pair<LLVM::LLVMFunctionType, LLVM::LLVMStructType>
133  convertFunctionTypeCWrapper(FunctionType type) const;
134 
135  /// Returns the data layout to use during and after conversion.
136  const llvm::DataLayout &getDataLayout() const { return options.dataLayout; }
137 
138  /// Returns the data layout analysis to query during conversion.
140  return dataLayoutAnalysis;
141  }
142 
143  /// Gets the LLVM representation of the index type. The returned type is an
144  /// integer type with the size configured for this type converter.
145  Type getIndexType() const;
146 
147  /// Gets the bitwidth of the index type when converted to LLVM.
148  unsigned getIndexTypeBitwidth() const { return options.getIndexBitwidth(); }
149 
150  /// Gets the pointer bitwidth.
151  unsigned getPointerBitwidth(unsigned addressSpace = 0) const;
152 
153  /// Returns the size of the memref descriptor object in bytes.
154  unsigned getMemRefDescriptorSize(MemRefType type,
155  const DataLayout &layout) const;
156 
157  /// Returns the size of the unranked memref descriptor object in bytes.
159  const DataLayout &layout) const;
160 
161  /// Return the LLVM address space corresponding to the memory space of the
162  /// memref type `type` or failure if the memory space cannot be converted to
163  /// an integer.
164  FailureOr<unsigned> getMemRefAddressSpace(BaseMemRefType type) const;
165 
166  /// Check if a memref type can be converted to a bare pointer.
167  static bool canConvertToBarePtr(BaseMemRefType type);
168 
169  /// Convert a memref type into a list of LLVM IR types that will form the
170  /// memref descriptor. If `unpackAggregates` is true the `sizes` and `strides`
171  /// arrays in the descriptors are unpacked to individual index-typed elements,
172  /// else they are kept as rank-sized arrays of index type. In particular,
173  /// the list will contain:
174  /// - two pointers to the memref element type, followed by
175  /// - an index-typed offset, followed by
176  /// - (if unpackAggregates = true)
177  /// - one index-typed size per dimension of the memref, followed by
178  /// - one index-typed stride per dimension of the memref.
179  /// - (if unpackArrregates = false)
180  /// - one rank-sized array of index-type for the size of each dimension
181  /// - one rank-sized array of index-type for the stride of each dimension
182  ///
183  /// For example, memref<?x?xf32> is converted to the following list:
184  /// - `!llvm<"float*">` (allocated pointer),
185  /// - `!llvm<"float*">` (aligned pointer),
186  /// - `i64` (offset),
187  /// - `i64`, `i64` (sizes),
188  /// - `i64`, `i64` (strides).
189  /// These types can be recomposed to a memref descriptor struct.
191  bool unpackAggregates) const;
192 
193  /// Convert an unranked memref type into a list of non-aggregate LLVM IR types
194  /// that will form the unranked memref descriptor. In particular, this list
195  /// contains:
196  /// - an integer rank, followed by
197  /// - a pointer to the memref descriptor struct.
198  /// For example, memref<*xf32> is converted to the following list:
199  /// i64 (rank)
200  /// !llvm<"i8*"> (type-erased pointer).
201  /// These types can be recomposed to a unranked memref descriptor struct.
203 
204 protected:
205  /// Pointer to the LLVM dialect.
206  LLVM::LLVMDialect *llvmDialect;
207 
208  // Recursive structure detection.
209  // We store one entry per thread here, and rely on locking.
211  llvm::sys::SmartRWMutex<true> callStackMutex;
213 
214 private:
215  /// Convert a function type. The arguments and results are converted one by
216  /// one. Additionally, if the function returns more than one value, pack the
217  /// results into an LLVM IR structure type so that the converted function type
218  /// returns at most one result.
219  Type convertFunctionType(FunctionType type) const;
220 
221  /// Common implementation for `convertFunctionSignature` methods. Convert a
222  /// function type. The arguments and results are converted one by one and
223  /// results are packed into a wrapped LLVM IR structure type. `result` is
224  /// populated with argument mapping. If `byValRefNonPtrAttrs` is provided,
225  /// converted types of `llvm.byval` and `llvm.byref` function arguments which
226  /// are not LLVM pointers are overridden with LLVM pointers. `llvm.byval` and
227  /// `llvm.byref` arguments that were already converted to LLVM pointer types
228  /// are removed from 'byValRefNonPtrAttrs`.
229  Type convertFunctionSignatureImpl(
230  FunctionType funcTy, bool isVariadic, bool useBarePtrCallConv,
232  SmallVectorImpl<std::optional<NamedAttribute>> *byValRefNonPtrAttrs)
233  const;
234 
235  /// Convert the index type. Uses llvmModule data layout to create an integer
236  /// of the pointer bitwidth.
237  Type convertIndexType(IndexType type) const;
238 
239  /// Convert an integer type `i*` to `!llvm<"i*">`.
240  Type convertIntegerType(IntegerType type) const;
241 
242  /// Convert a floating point type: `f16` to `f16`, `f32` to
243  /// `f32` and `f64` to `f64`. `bf16` is not supported
244  /// by LLVM. 8-bit float types are converted to 8-bit integers as this is how
245  /// all LLVM backends that support them currently represent them.
246  Type convertFloatType(FloatType type) const;
247 
248  /// Convert complex number type: `complex<f16>` to `!llvm<"{ half, half }">`,
249  /// `complex<f32>` to `!llvm<"{ float, float }">`, and `complex<f64>` to
250  /// `!llvm<"{ double, double }">`. `complex<bf16>` is not supported.
251  Type convertComplexType(ComplexType type) const;
252 
253  /// Convert a memref type into an LLVM type that captures the relevant data.
254  Type convertMemRefType(MemRefType type) const;
255 
256  /// Convert an unranked memref type to an LLVM type that captures the
257  /// runtime rank and a pointer to the static ranked memref desc
258  Type convertUnrankedMemRefType(UnrankedMemRefType type) const;
259 
260  /// Convert a memref type to a bare pointer to the memref element type.
261  Type convertMemRefToBarePtr(BaseMemRefType type) const;
262 
263  /// Convert a 1D vector type into an LLVM vector type.
264  FailureOr<Type> convertVectorType(VectorType type) const;
265 
266  /// Options for customizing the llvm lowering.
267  LowerToLLVMOptions options;
268 
269  /// Data layout analysis mapping scopes to layouts active in them.
270  const DataLayoutAnalysis *dataLayoutAnalysis;
271 };
272 
273 /// Callback to convert function argument types. It converts a MemRef function
274 /// argument to a list of non-aggregate types containing descriptor
275 /// information, and an UnrankedmemRef function argument to a list containing
276 /// the rank and a pointer to a descriptor struct.
277 LogicalResult structFuncArgTypeConverter(const LLVMTypeConverter &converter,
278  Type type,
279  SmallVectorImpl<Type> &result);
280 
281 /// Callback to convert function argument types. It converts MemRef function
282 /// arguments to bare pointers to the MemRef element type.
283 LogicalResult barePtrFuncArgTypeConverter(const LLVMTypeConverter &converter,
284  Type type,
285  SmallVectorImpl<Type> &result);
286 
287 } // namespace mlir
288 
289 #endif // MLIR_CONVERSION_LLVMCOMMON_TYPECONVERTER_H
This class provides a shared interface for ranked and unranked memref types.
Definition: BuiltinTypes.h:104
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.
Conversion from types to the LLVM IR dialect.
Definition: TypeConverter.h:35
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.
SmallVector< Value, 4 > promoteOperands(Location loc, ValueRange opOperands, ArrayRef< ValueRange > adaptorOperands, OpBuilder &builder, bool useBarePtrCallConv=false) const
Promote the LLVM representation of all operands including promoting MemRef descriptors to stack and u...
Type packFunctionResults(TypeRange types, bool useBarePointerCallConv=false, SmallVector< SmallVector< Type >> *groupedTypes=nullptr, int64_t *numConvertedTypes=nullptr) const
Convert a non-empty list of types to be returned from a function into an LLVM-compatible type.
LogicalResult convertCallingConventionType(Type type, SmallVectorImpl< Type > &result, bool useBarePointerCallConv=false) const
Convert a type in the context of the default or bare pointer calling convention.
const LowerToLLVMOptions & getOptions() const
unsigned getUnrankedMemRefDescriptorSize(UnrankedMemRefType type, const DataLayout &layout) const
Returns the size of the unranked memref descriptor object in bytes.
SmallVector< Type, 5 > getMemRefDescriptorFields(MemRefType type, bool unpackAggregates) const
Convert a memref type into a list of LLVM IR types that will form the memref descriptor.
Type convertFunctionSignature(FunctionType funcTy, bool isVariadic, bool useBarePtrCallConv, SignatureConversion &result) const
Convert a function type.
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...
LLVMTypeConverter(MLIRContext *ctx, const DataLayoutAnalysis *analysis=nullptr)
Create an LLVMTypeConverter using the default LowerToLLVMOptions.
unsigned getPointerBitwidth(unsigned addressSpace=0) const
Gets the pointer bitwidth.
SmallVector< Type, 2 > getUnrankedMemRefDescriptorFields() const
Convert an unranked memref type into a list of non-aggregate LLVM IR types that will form the unranke...
FailureOr< unsigned > getMemRefAddressSpace(BaseMemRefType type) const
Return the LLVM address space corresponding to the memory space of the memref type type or failure if...
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.
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:76
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:63
This class helps build Operations.
Definition: Builders.h:207
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:37
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:387
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:96
detail::InFlightRemark analysis(Location loc, RemarkOpts opts)
Report an optimization analysis remark.
Definition: Remarks.h:497
Include the generated interface declarations.
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.