MLIR  20.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`.
78  bool useBarePointerCallConv = false) const;
79 
80  /// Convert a non-empty list of types of values produced by an operation into
81  /// an LLVM-compatible type. In particular, if more than one value is
82  /// produced, create a literal structure with elements that correspond to each
83  /// of the LLVM-compatible types converted with `convertType`.
84  Type packOperationResults(TypeRange types) const;
85 
86  /// Convert a type in the context of the default or bare pointer calling
87  /// convention. Calling convention sensitive types, such as MemRefType and
88  /// UnrankedMemRefType, are converted following the specific rules for the
89  /// calling convention. Calling convention independent types are converted
90  /// following the default LLVM type conversions.
92  bool useBarePointerCallConv = false) const;
93 
94  /// Promote the bare pointers in 'values' that resulted from memrefs to
95  /// descriptors. 'stdTypes' holds the types of 'values' before the conversion
96  /// to the LLVM-IR dialect (i.e., MemRefType, or any other builtin type).
98  Location loc, ArrayRef<Type> stdTypes,
99  SmallVectorImpl<Value> &values) 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.
114  ValueRange operands, OpBuilder &builder,
115  bool useBarePtrCallConv = false) const;
116 
117  /// Promote the LLVM struct representation of one MemRef descriptor to stack
118  /// and use pointer to struct to avoid the complexity of the platform-specific
119  /// C/C++ ABI lowering related to struct argument passing.
121  OpBuilder &builder) const;
122 
123  /// Converts the function type to a C-compatible format, in particular using
124  /// pointers to memref descriptors for arguments. Also converts the return
125  /// type to a pointer argument if it is a struct. Returns true if this
126  /// was the case.
127  std::pair<LLVM::LLVMFunctionType, LLVM::LLVMStructType>
128  convertFunctionTypeCWrapper(FunctionType type) const;
129 
130  /// Returns the data layout to use during and after conversion.
131  const llvm::DataLayout &getDataLayout() const { return options.dataLayout; }
132 
133  /// Returns the data layout analysis to query during conversion.
135  return dataLayoutAnalysis;
136  }
137 
138  /// Gets the LLVM representation of the index type. The returned type is an
139  /// integer type with the size configured for this type converter.
140  Type getIndexType() const;
141 
142  /// Gets the bitwidth of the index type when converted to LLVM.
143  unsigned getIndexTypeBitwidth() const { return options.getIndexBitwidth(); }
144 
145  /// Gets the pointer bitwidth.
146  unsigned getPointerBitwidth(unsigned addressSpace = 0) const;
147 
148  /// Returns the size of the memref descriptor object in bytes.
149  unsigned getMemRefDescriptorSize(MemRefType type,
150  const DataLayout &layout) const;
151 
152  /// Returns the size of the unranked memref descriptor object in bytes.
154  const DataLayout &layout) const;
155 
156  /// Return the LLVM address space corresponding to the memory space of the
157  /// memref type `type` or failure if the memory space cannot be converted to
158  /// an integer.
159  FailureOr<unsigned> getMemRefAddressSpace(BaseMemRefType type) const;
160 
161  /// Check if a memref type can be converted to a bare pointer.
162  static bool canConvertToBarePtr(BaseMemRefType type);
163 
164 protected:
165  /// Pointer to the LLVM dialect.
166  LLVM::LLVMDialect *llvmDialect;
167 
168  // Recursive structure detection.
169  // We store one entry per thread here, and rely on locking.
171  llvm::sys::SmartRWMutex<true> callStackMutex;
173 
174 private:
175  /// Convert a function type. The arguments and results are converted one by
176  /// one. Additionally, if the function returns more than one value, pack the
177  /// results into an LLVM IR structure type so that the converted function type
178  /// returns at most one result.
179  Type convertFunctionType(FunctionType type) const;
180 
181  /// Common implementation for `convertFunctionSignature` methods. Convert a
182  /// function type. The arguments and results are converted one by one and
183  /// results are packed into a wrapped LLVM IR structure type. `result` is
184  /// populated with argument mapping. If `byValRefNonPtrAttrs` is provided,
185  /// converted types of `llvm.byval` and `llvm.byref` function arguments which
186  /// are not LLVM pointers are overridden with LLVM pointers. `llvm.byval` and
187  /// `llvm.byref` arguments that were already converted to LLVM pointer types
188  /// are removed from 'byValRefNonPtrAttrs`.
189  Type convertFunctionSignatureImpl(
190  FunctionType funcTy, bool isVariadic, bool useBarePtrCallConv,
192  SmallVectorImpl<std::optional<NamedAttribute>> *byValRefNonPtrAttrs)
193  const;
194 
195  /// Convert the index type. Uses llvmModule data layout to create an integer
196  /// of the pointer bitwidth.
197  Type convertIndexType(IndexType type) const;
198 
199  /// Convert an integer type `i*` to `!llvm<"i*">`.
200  Type convertIntegerType(IntegerType type) const;
201 
202  /// Convert a floating point type: `f16` to `f16`, `f32` to
203  /// `f32` and `f64` to `f64`. `bf16` is not supported
204  /// by LLVM. 8-bit float types are converted to 8-bit integers as this is how
205  /// all LLVM backends that support them currently represent them.
206  Type convertFloatType(FloatType type) const;
207 
208  /// Convert complex number type: `complex<f16>` to `!llvm<"{ half, half }">`,
209  /// `complex<f32>` to `!llvm<"{ float, float }">`, and `complex<f64>` to
210  /// `!llvm<"{ double, double }">`. `complex<bf16>` is not supported.
211  Type convertComplexType(ComplexType type) const;
212 
213  /// Convert a memref type into an LLVM type that captures the relevant data.
214  Type convertMemRefType(MemRefType type) const;
215 
216  /// Convert a memref type into a list of LLVM IR types that will form the
217  /// memref descriptor. If `unpackAggregates` is true the `sizes` and `strides`
218  /// arrays in the descriptors are unpacked to individual index-typed elements,
219  /// else they are kept as rank-sized arrays of index type. In particular,
220  /// the list will contain:
221  /// - two pointers to the memref element type, followed by
222  /// - an index-typed offset, followed by
223  /// - (if unpackAggregates = true)
224  /// - one index-typed size per dimension of the memref, followed by
225  /// - one index-typed stride per dimension of the memref.
226  /// - (if unpackArrregates = false)
227  /// - one rank-sized array of index-type for the size of each dimension
228  /// - one rank-sized array of index-type for the stride of each dimension
229  ///
230  /// For example, memref<?x?xf32> is converted to the following list:
231  /// - `!llvm<"float*">` (allocated pointer),
232  /// - `!llvm<"float*">` (aligned pointer),
233  /// - `i64` (offset),
234  /// - `i64`, `i64` (sizes),
235  /// - `i64`, `i64` (strides).
236  /// These types can be recomposed to a memref descriptor struct.
237  SmallVector<Type, 5> getMemRefDescriptorFields(MemRefType type,
238  bool unpackAggregates) const;
239 
240  /// Convert an unranked memref type into a list of non-aggregate LLVM IR types
241  /// that will form the unranked memref descriptor. In particular, this list
242  /// contains:
243  /// - an integer rank, followed by
244  /// - a pointer to the memref descriptor struct.
245  /// For example, memref<*xf32> is converted to the following list:
246  /// i64 (rank)
247  /// !llvm<"i8*"> (type-erased pointer).
248  /// These types can be recomposed to a unranked memref descriptor struct.
249  SmallVector<Type, 2> getUnrankedMemRefDescriptorFields() const;
250 
251  /// Convert an unranked memref type to an LLVM type that captures the
252  /// runtime rank and a pointer to the static ranked memref desc
253  Type convertUnrankedMemRefType(UnrankedMemRefType type) const;
254 
255  /// Convert a memref type to a bare pointer to the memref element type.
256  Type convertMemRefToBarePtr(BaseMemRefType type) const;
257 
258  /// Convert a 1D vector type into an LLVM vector type.
259  FailureOr<Type> convertVectorType(VectorType type) const;
260 
261  /// Options for customizing the llvm lowering.
262  LowerToLLVMOptions options;
263 
264  /// Data layout analysis mapping scopes to layouts active in them.
265  const DataLayoutAnalysis *dataLayoutAnalysis;
266 };
267 
268 /// Callback to convert function argument types. It converts a MemRef function
269 /// argument to a list of non-aggregate types containing descriptor
270 /// information, and an UnrankedmemRef function argument to a list containing
271 /// the rank and a pointer to a descriptor struct.
272 LogicalResult structFuncArgTypeConverter(const LLVMTypeConverter &converter,
273  Type type,
274  SmallVectorImpl<Type> &result);
275 
276 /// Callback to convert function argument types. It converts MemRef function
277 /// arguments to bare pointers to the MemRef element type.
278 LogicalResult barePtrFuncArgTypeConverter(const LLVMTypeConverter &converter,
279  Type type,
280  SmallVectorImpl<Type> &result);
281 
282 } // namespace mlir
283 
284 #endif // MLIR_CONVERSION_LLVMCOMMON_TYPECONVERTER_H
This class provides a shared interface for ranked and unranked memref types.
Definition: BuiltinTypes.h:149
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.
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.
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
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...
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:66
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:215
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:381
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:96
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.