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 17 #include "mlir/Conversion/LLVMCommon/LoweringOptions.h" 18 #include "mlir/Transforms/DialectConversion.h" 19 20 namespace mlir { 21 22 class DataLayoutAnalysis; 23 class LowerToLLVMOptions; 24 25 namespace LLVM { 26 class LLVMDialect; 27 } // namespace LLVM 28 29 /// Conversion from types in the Standard dialect to the LLVM IR dialect. 30 class LLVMTypeConverter : public TypeConverter { 31 /// Give structFuncArgTypeConverter access to memref-specific functions. 32 friend LogicalResult 33 structFuncArgTypeConverter(LLVMTypeConverter &converter, Type type, 34 SmallVectorImpl<Type> &result); 35 36 public: 37 using TypeConverter::convertType; 38 39 /// Create an LLVMTypeConverter using the default LowerToLLVMOptions. 40 /// Optionally takes a data layout analysis to use in conversions. 41 LLVMTypeConverter(MLIRContext *ctx, 42 const DataLayoutAnalysis *analysis = nullptr); 43 44 /// Create an LLVMTypeConverter using custom LowerToLLVMOptions. Optionally 45 /// takes a data layout analysis to use in conversions. 46 LLVMTypeConverter(MLIRContext *ctx, const LowerToLLVMOptions &options, 47 const DataLayoutAnalysis *analysis = nullptr); 48 49 /// Convert a function type. The arguments and results are converted one by 50 /// one and results are packed into a wrapped LLVM IR structure type. `result` 51 /// is populated with argument mapping. 52 Type convertFunctionSignature(FunctionType funcTy, bool isVariadic, 53 SignatureConversion &result); 54 55 /// Convert a non-empty list of types to be returned from a function into a 56 /// supported LLVM IR type. In particular, if more than one value is 57 /// returned, create an LLVM IR structure type with elements that correspond 58 /// to each of the MLIR types converted with `convertType`. 59 Type packFunctionResults(TypeRange types); 60 61 /// Convert a type in the context of the default or bare pointer calling 62 /// convention. Calling convention sensitive types, such as MemRefType and 63 /// UnrankedMemRefType, are converted following the specific rules for the 64 /// calling convention. Calling convention independent types are converted 65 /// following the default LLVM type conversions. 66 Type convertCallingConventionType(Type type); 67 68 /// Promote the bare pointers in 'values' that resulted from memrefs to 69 /// descriptors. 'stdTypes' holds the types of 'values' before the conversion 70 /// to the LLVM-IR dialect (i.e., MemRefType, or any other builtin type). 71 void promoteBarePtrsToDescriptors(ConversionPatternRewriter &rewriter, 72 Location loc, ArrayRef<Type> stdTypes, 73 SmallVectorImpl<Value> &values); 74 75 /// Returns the MLIR context. 76 MLIRContext &getContext(); 77 78 /// Returns the LLVM dialect. getDialect()79 LLVM::LLVMDialect *getDialect() { return llvmDialect; } 80 getOptions()81 const LowerToLLVMOptions &getOptions() const { return options; } 82 83 /// Promote the LLVM representation of all operands including promoting MemRef 84 /// descriptors to stack and use pointers to struct to avoid the complexity 85 /// of the platform-specific C/C++ ABI lowering related to struct argument 86 /// passing. 87 SmallVector<Value, 4> promoteOperands(Location loc, ValueRange opOperands, 88 ValueRange operands, 89 OpBuilder &builder); 90 91 /// Promote the LLVM struct representation of one MemRef descriptor to stack 92 /// and use pointer to struct to avoid the complexity of the platform-specific 93 /// C/C++ ABI lowering related to struct argument passing. 94 Value promoteOneMemRefDescriptor(Location loc, Value operand, 95 OpBuilder &builder); 96 97 /// Converts the function type to a C-compatible format, in particular using 98 /// pointers to memref descriptors for arguments. Also converts the return 99 /// type to a pointer argument if it is a struct. Returns true if this 100 /// was the case. 101 std::pair<Type, bool> convertFunctionTypeCWrapper(FunctionType type); 102 103 /// Returns the data layout to use during and after conversion. getDataLayout()104 const llvm::DataLayout &getDataLayout() { return options.dataLayout; } 105 106 /// Returns the data layout analysis to query during conversion. getDataLayoutAnalysis()107 const DataLayoutAnalysis *getDataLayoutAnalysis() const { 108 return dataLayoutAnalysis; 109 } 110 111 /// Gets the LLVM representation of the index type. The returned type is an 112 /// integer type with the size configured for this type converter. 113 Type getIndexType(); 114 115 /// Gets the bitwidth of the index type when converted to LLVM. getIndexTypeBitwidth()116 unsigned getIndexTypeBitwidth() { return options.getIndexBitwidth(); } 117 118 /// Gets the pointer bitwidth. 119 unsigned getPointerBitwidth(unsigned addressSpace = 0); 120 121 /// Returns the size of the memref descriptor object in bytes. 122 unsigned getMemRefDescriptorSize(MemRefType type, const DataLayout &layout); 123 124 /// Returns the size of the unranked memref descriptor object in bytes. 125 unsigned getUnrankedMemRefDescriptorSize(UnrankedMemRefType type, 126 const DataLayout &layout); 127 128 protected: 129 /// Pointer to the LLVM dialect. 130 LLVM::LLVMDialect *llvmDialect; 131 132 private: 133 /// Convert a function type. The arguments and results are converted one by 134 /// one. Additionally, if the function returns more than one value, pack the 135 /// results into an LLVM IR structure type so that the converted function type 136 /// returns at most one result. 137 Type convertFunctionType(FunctionType type); 138 139 /// Convert the index type. Uses llvmModule data layout to create an integer 140 /// of the pointer bitwidth. 141 Type convertIndexType(IndexType type); 142 143 /// Convert an integer type `i*` to `!llvm<"i*">`. 144 Type convertIntegerType(IntegerType type); 145 146 /// Convert a floating point type: `f16` to `f16`, `f32` to 147 /// `f32` and `f64` to `f64`. `bf16` is not supported 148 /// by LLVM. 149 Type convertFloatType(FloatType type); 150 151 /// Convert complex number type: `complex<f16>` to `!llvm<"{ half, half }">`, 152 /// `complex<f32>` to `!llvm<"{ float, float }">`, and `complex<f64>` to 153 /// `!llvm<"{ double, double }">`. `complex<bf16>` is not supported. 154 Type convertComplexType(ComplexType type); 155 156 /// Convert a memref type into an LLVM type that captures the relevant data. 157 Type convertMemRefType(MemRefType type); 158 159 /// Convert a memref type into a list of LLVM IR types that will form the 160 /// memref descriptor. If `unpackAggregates` is true the `sizes` and `strides` 161 /// arrays in the descriptors are unpacked to individual index-typed elements, 162 /// else they are are kept as rank-sized arrays of index type. In particular, 163 /// the list will contain: 164 /// - two pointers to the memref element type, followed by 165 /// - an index-typed offset, followed by 166 /// - (if unpackAggregates = true) 167 /// - one index-typed size per dimension of the memref, followed by 168 /// - one index-typed stride per dimension of the memref. 169 /// - (if unpackArrregates = false) 170 /// - one rank-sized array of index-type for the size of each dimension 171 /// - one rank-sized array of index-type for the stride of each dimension 172 /// 173 /// For example, memref<?x?xf32> is converted to the following list: 174 /// - `!llvm<"float*">` (allocated pointer), 175 /// - `!llvm<"float*">` (aligned pointer), 176 /// - `i64` (offset), 177 /// - `i64`, `i64` (sizes), 178 /// - `i64`, `i64` (strides). 179 /// These types can be recomposed to a memref descriptor struct. 180 SmallVector<Type, 5> getMemRefDescriptorFields(MemRefType type, 181 bool unpackAggregates); 182 183 /// Convert an unranked memref type into a list of non-aggregate LLVM IR types 184 /// that will form the unranked memref descriptor. In particular, this list 185 /// contains: 186 /// - an integer rank, followed by 187 /// - a pointer to the memref descriptor struct. 188 /// For example, memref<*xf32> is converted to the following list: 189 /// i64 (rank) 190 /// !llvm<"i8*"> (type-erased pointer). 191 /// These types can be recomposed to a unranked memref descriptor struct. 192 SmallVector<Type, 2> getUnrankedMemRefDescriptorFields(); 193 194 // Convert an unranked memref type to an LLVM type that captures the 195 // runtime rank and a pointer to the static ranked memref desc 196 Type convertUnrankedMemRefType(UnrankedMemRefType type); 197 198 /// Convert a memref type to a bare pointer to the memref element type. 199 Type convertMemRefToBarePtr(BaseMemRefType type); 200 201 /// Convert a 1D vector type into an LLVM vector type. 202 Type convertVectorType(VectorType type); 203 204 /// Options for customizing the llvm lowering. 205 LowerToLLVMOptions options; 206 207 /// Data layout analysis mapping scopes to layouts active in them. 208 const DataLayoutAnalysis *dataLayoutAnalysis; 209 }; 210 211 /// Callback to convert function argument types. It converts a MemRef function 212 /// argument to a list of non-aggregate types containing descriptor 213 /// information, and an UnrankedmemRef function argument to a list containing 214 /// the rank and a pointer to a descriptor struct. 215 LogicalResult structFuncArgTypeConverter(LLVMTypeConverter &converter, 216 Type type, 217 SmallVectorImpl<Type> &result); 218 219 /// Callback to convert function argument types. It converts MemRef function 220 /// arguments to bare pointers to the MemRef element type. 221 LogicalResult barePtrFuncArgTypeConverter(LLVMTypeConverter &converter, 222 Type type, 223 SmallVectorImpl<Type> &result); 224 225 } // namespace mlir 226 227 #endif // MLIR_CONVERSION_LLVMCOMMON_TYPECONVERTER_H 228