MLIR  16.0.0git
TypeConverter.cpp
Go to the documentation of this file.
1 //===- TypeConverter.cpp - Convert builtin to LLVM dialect types ----------===//
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 
10 #include "MemRefDescriptor.h"
14 
15 using namespace mlir;
16 
17 /// Create an LLVMTypeConverter using default LowerToLLVMOptions.
19  const DataLayoutAnalysis *analysis)
20  : LLVMTypeConverter(ctx, LowerToLLVMOptions(ctx), analysis) {}
21 
22 /// Create an LLVMTypeConverter using custom LowerToLLVMOptions.
25  const DataLayoutAnalysis *analysis)
26  : llvmDialect(ctx->getOrLoadDialect<LLVM::LLVMDialect>()), options(options),
27  dataLayoutAnalysis(analysis) {
28  assert(llvmDialect && "LLVM IR dialect is not registered");
29 
30  // Register conversions for the builtin types.
31  addConversion([&](ComplexType type) { return convertComplexType(type); });
32  addConversion([&](FloatType type) { return convertFloatType(type); });
33  addConversion([&](FunctionType type) { return convertFunctionType(type); });
34  addConversion([&](IndexType type) { return convertIndexType(type); });
35  addConversion([&](IntegerType type) { return convertIntegerType(type); });
36  addConversion([&](MemRefType type) { return convertMemRefType(type); });
38  [&](UnrankedMemRefType type) { return convertUnrankedMemRefType(type); });
39  addConversion([&](VectorType type) { return convertVectorType(type); });
40 
41  // LLVM-compatible types are legal, so add a pass-through conversion. Do this
42  // before the conversions below since conversions are attempted in reverse
43  // order and those should take priority.
44  addConversion([](Type type) {
45  return LLVM::isCompatibleType(type) ? llvm::Optional<Type>(type)
46  : llvm::None;
47  });
48 
49  // LLVM container types may (recursively) contain other types that must be
50  // converted even when the outer type is compatible.
51  addConversion([&](LLVM::LLVMPointerType type) -> llvm::Optional<Type> {
52  if (type.isOpaque())
53  return type;
54  if (auto pointee = convertType(type.getElementType()))
55  return LLVM::LLVMPointerType::get(pointee, type.getAddressSpace());
56  return llvm::None;
57  });
60  // Fastpath for types that won't be converted by this callback anyway.
61  if (LLVM::isCompatibleType(type)) {
62  results.push_back(type);
63  return success();
64  }
65 
66  if (type.isIdentified()) {
67  auto convertedType = LLVM::LLVMStructType::getIdentified(
68  type.getContext(), ("_Converted_" + type.getName()).str());
69  unsigned counter = 1;
70  while (convertedType.isInitialized()) {
71  assert(counter != UINT_MAX &&
72  "about to overflow struct renaming counter in conversion");
74  type.getContext(),
75  ("_Converted_" + std::to_string(counter) + type.getName()).str());
76  }
77  if (llvm::count(callStack, type) > 1) {
78  results.push_back(convertedType);
79  return success();
80  }
81 
82  SmallVector<Type> convertedElemTypes;
83  convertedElemTypes.reserve(type.getBody().size());
84  if (failed(convertTypes(type.getBody(), convertedElemTypes)))
85  return llvm::None;
86 
87  if (failed(convertedType.setBody(convertedElemTypes, type.isPacked())))
88  return failure();
89  results.push_back(convertedType);
90  return success();
91  }
92 
93  SmallVector<Type> convertedSubtypes;
94  convertedSubtypes.reserve(type.getBody().size());
95  if (failed(convertTypes(type.getBody(), convertedSubtypes)))
96  return llvm::None;
97 
98  results.push_back(LLVM::LLVMStructType::getLiteral(
99  type.getContext(), convertedSubtypes, type.isPacked()));
100  return success();
101  });
102  addConversion([&](LLVM::LLVMArrayType type) -> llvm::Optional<Type> {
103  if (auto element = convertType(type.getElementType()))
104  return LLVM::LLVMArrayType::get(element, type.getNumElements());
105  return llvm::None;
106  });
107  addConversion([&](LLVM::LLVMFunctionType type) -> llvm::Optional<Type> {
108  Type convertedResType = convertType(type.getReturnType());
109  if (!convertedResType)
110  return llvm::None;
111 
112  SmallVector<Type> convertedArgTypes;
113  convertedArgTypes.reserve(type.getNumParams());
114  if (failed(convertTypes(type.getParams(), convertedArgTypes)))
115  return llvm::None;
116 
117  return LLVM::LLVMFunctionType::get(convertedResType, convertedArgTypes,
118  type.isVarArg());
119  });
120 
121  // Materialization for memrefs creates descriptor structs from individual
122  // values constituting them, when descriptors are used, i.e. more than one
123  // value represents a memref.
125  [&](OpBuilder &builder, UnrankedMemRefType resultType, ValueRange inputs,
126  Location loc) -> Optional<Value> {
127  if (inputs.size() == 1)
128  return llvm::None;
129  return UnrankedMemRefDescriptor::pack(builder, loc, *this, resultType,
130  inputs);
131  });
132  addArgumentMaterialization([&](OpBuilder &builder, MemRefType resultType,
133  ValueRange inputs,
134  Location loc) -> Optional<Value> {
135  // TODO: bare ptr conversion could be handled here but we would need a way
136  // to distinguish between FuncOp and other regions.
137  if (inputs.size() == 1)
138  return llvm::None;
139  return MemRefDescriptor::pack(builder, loc, *this, resultType, inputs);
140  });
141  // Add generic source and target materializations to handle cases where
142  // non-LLVM types persist after an LLVM conversion.
143  addSourceMaterialization([&](OpBuilder &builder, Type resultType,
144  ValueRange inputs,
145  Location loc) -> Optional<Value> {
146  if (inputs.size() != 1)
147  return llvm::None;
148 
149  return builder.create<UnrealizedConversionCastOp>(loc, resultType, inputs)
150  .getResult(0);
151  });
152  addTargetMaterialization([&](OpBuilder &builder, Type resultType,
153  ValueRange inputs,
154  Location loc) -> Optional<Value> {
155  if (inputs.size() != 1)
156  return llvm::None;
157 
158  return builder.create<UnrealizedConversionCastOp>(loc, resultType, inputs)
159  .getResult(0);
160  });
161 }
162 
163 /// Returns the MLIR context.
165  return *getDialect()->getContext();
166 }
167 
169  return IntegerType::get(&getContext(), getIndexTypeBitwidth());
170 }
171 
172 unsigned LLVMTypeConverter::getPointerBitwidth(unsigned addressSpace) {
173  return options.dataLayout.getPointerSizeInBits(addressSpace);
174 }
175 
176 Type LLVMTypeConverter::convertIndexType(IndexType type) {
177  return getIndexType();
178 }
179 
180 Type LLVMTypeConverter::convertIntegerType(IntegerType type) {
181  return IntegerType::get(&getContext(), type.getWidth());
182 }
183 
184 Type LLVMTypeConverter::convertFloatType(FloatType type) { return type; }
185 
186 // Convert a `ComplexType` to an LLVM type. The result is a complex number
187 // struct with entries for the
188 // 1. real part and for the
189 // 2. imaginary part.
190 Type LLVMTypeConverter::convertComplexType(ComplexType type) {
191  auto elementType = convertType(type.getElementType());
193  {elementType, elementType});
194 }
195 
196 // Except for signatures, MLIR function types are converted into LLVM
197 // pointer-to-function types.
198 Type LLVMTypeConverter::convertFunctionType(FunctionType type) {
199  SignatureConversion conversion(type.getNumInputs());
200  Type converted =
201  convertFunctionSignature(type, /*isVariadic=*/false, conversion);
202  return LLVM::LLVMPointerType::get(converted);
203 }
204 
205 // Function types are converted to LLVM Function types by recursively converting
206 // argument and result types. If MLIR Function has zero results, the LLVM
207 // Function has one VoidType result. If MLIR Function has more than one result,
208 // they are into an LLVM StructType in their order of appearance.
210  FunctionType funcTy, bool isVariadic,
212  // Select the argument converter depending on the calling convention.
213  auto funcArgConverter = options.useBarePtrCallConv
216  // Convert argument types one by one and check for errors.
217  for (auto &en : llvm::enumerate(funcTy.getInputs())) {
218  Type type = en.value();
219  SmallVector<Type, 8> converted;
220  if (failed(funcArgConverter(*this, type, converted)))
221  return {};
222  result.addInputs(en.index(), converted);
223  }
224 
225  // If function does not return anything, create the void result type,
226  // if it returns on element, convert it, otherwise pack the result types into
227  // a struct.
228  Type resultType = funcTy.getNumResults() == 0
229  ? LLVM::LLVMVoidType::get(&getContext())
230  : packFunctionResults(funcTy.getResults());
231  if (!resultType)
232  return {};
233  return LLVM::LLVMFunctionType::get(resultType, result.getConvertedTypes(),
234  isVariadic);
235 }
236 
237 /// Converts the function type to a C-compatible format, in particular using
238 /// pointers to memref descriptors for arguments.
239 std::pair<Type, bool>
241  SmallVector<Type, 4> inputs;
242  bool resultIsNowArg = false;
243 
244  Type resultType = type.getNumResults() == 0
245  ? LLVM::LLVMVoidType::get(&getContext())
246  : packFunctionResults(type.getResults());
247  if (!resultType)
248  return {};
249 
250  if (auto structType = resultType.dyn_cast<LLVM::LLVMStructType>()) {
251  // Struct types cannot be safely returned via C interface. Make this a
252  // pointer argument, instead.
253  inputs.push_back(LLVM::LLVMPointerType::get(structType));
254  resultType = LLVM::LLVMVoidType::get(&getContext());
255  resultIsNowArg = true;
256  }
257 
258  for (Type t : type.getInputs()) {
259  auto converted = convertType(t);
260  if (!converted || !LLVM::isCompatibleType(converted))
261  return {};
262  if (t.isa<MemRefType, UnrankedMemRefType>())
263  converted = LLVM::LLVMPointerType::get(converted);
264  inputs.push_back(converted);
265  }
266 
267  return {LLVM::LLVMFunctionType::get(resultType, inputs), resultIsNowArg};
268 }
269 
270 /// Convert a memref type into a list of LLVM IR types that will form the
271 /// memref descriptor. The result contains the following types:
272 /// 1. The pointer to the allocated data buffer, followed by
273 /// 2. The pointer to the aligned data buffer, followed by
274 /// 3. A lowered `index`-type integer containing the distance between the
275 /// beginning of the buffer and the first element to be accessed through the
276 /// view, followed by
277 /// 4. An array containing as many `index`-type integers as the rank of the
278 /// MemRef: the array represents the size, in number of elements, of the memref
279 /// along the given dimension. For constant MemRef dimensions, the
280 /// corresponding size entry is a constant whose runtime value must match the
281 /// static value, followed by
282 /// 5. A second array containing as many `index`-type integers as the rank of
283 /// the MemRef: the second array represents the "stride" (in tensor abstraction
284 /// sense), i.e. the number of consecutive elements of the underlying buffer.
285 /// TODO: add assertions for the static cases.
286 ///
287 /// If `unpackAggregates` is set to true, the arrays described in (4) and (5)
288 /// are expanded into individual index-type elements.
289 ///
290 /// template <typename Elem, typename Index, size_t Rank>
291 /// struct {
292 /// Elem *allocatedPtr;
293 /// Elem *alignedPtr;
294 /// Index offset;
295 /// Index sizes[Rank]; // omitted when rank == 0
296 /// Index strides[Rank]; // omitted when rank == 0
297 /// };
299 LLVMTypeConverter::getMemRefDescriptorFields(MemRefType type,
300  bool unpackAggregates) {
301  assert(isStrided(type) &&
302  "Non-strided layout maps must have been normalized away");
303 
304  Type elementType = convertType(type.getElementType());
305  if (!elementType)
306  return {};
307  auto ptrTy =
308  LLVM::LLVMPointerType::get(elementType, type.getMemorySpaceAsInt());
309  auto indexTy = getIndexType();
310 
311  SmallVector<Type, 5> results = {ptrTy, ptrTy, indexTy};
312  auto rank = type.getRank();
313  if (rank == 0)
314  return results;
315 
316  if (unpackAggregates)
317  results.insert(results.end(), 2 * rank, indexTy);
318  else
319  results.insert(results.end(), 2, LLVM::LLVMArrayType::get(indexTy, rank));
320  return results;
321 }
322 
324  const DataLayout &layout) {
325  // Compute the descriptor size given that of its components indicated above.
326  unsigned space = type.getMemorySpaceAsInt();
327  return 2 * llvm::divideCeil(getPointerBitwidth(space), 8) +
328  (1 + 2 * type.getRank()) * layout.getTypeSize(getIndexType());
329 }
330 
331 /// Converts MemRefType to LLVMType. A MemRefType is converted to a struct that
332 /// packs the descriptor fields as defined by `getMemRefDescriptorFields`.
333 Type LLVMTypeConverter::convertMemRefType(MemRefType type) {
334  // When converting a MemRefType to a struct with descriptor fields, do not
335  // unpack the `sizes` and `strides` arrays.
336  SmallVector<Type, 5> types =
337  getMemRefDescriptorFields(type, /*unpackAggregates=*/false);
338  if (types.empty())
339  return {};
341 }
342 
343 /// Convert an unranked memref type into a list of non-aggregate LLVM IR types
344 /// that will form the unranked memref descriptor. In particular, the fields
345 /// for an unranked memref descriptor are:
346 /// 1. index-typed rank, the dynamic rank of this MemRef
347 /// 2. void* ptr, pointer to the static ranked MemRef descriptor. This will be
348 /// stack allocated (alloca) copy of a MemRef descriptor that got casted to
349 /// be unranked.
350 SmallVector<Type, 2> LLVMTypeConverter::getUnrankedMemRefDescriptorFields() {
351  return {getIndexType(),
352  LLVM::LLVMPointerType::get(IntegerType::get(&getContext(), 8))};
353 }
354 
355 unsigned
357  const DataLayout &layout) {
358  // Compute the descriptor size given that of its components indicated above.
359  unsigned space = type.getMemorySpaceAsInt();
360  return layout.getTypeSize(getIndexType()) +
361  llvm::divideCeil(getPointerBitwidth(space), 8);
362 }
363 
364 Type LLVMTypeConverter::convertUnrankedMemRefType(UnrankedMemRefType type) {
365  if (!convertType(type.getElementType()))
366  return {};
368  getUnrankedMemRefDescriptorFields());
369 }
370 
371 // Check if a memref type can be converted to a bare pointer.
373  if (type.isa<UnrankedMemRefType>())
374  // Unranked memref is not supported in the bare pointer calling convention.
375  return false;
376 
377  // Check that the memref has static shape, strides and offset. Otherwise, it
378  // cannot be lowered to a bare pointer.
379  auto memrefTy = type.cast<MemRefType>();
380  if (!memrefTy.hasStaticShape())
381  return false;
382 
383  int64_t offset = 0;
384  SmallVector<int64_t, 4> strides;
385  if (failed(getStridesAndOffset(memrefTy, strides, offset)))
386  return false;
387 
388  for (int64_t stride : strides)
389  if (ShapedType::isDynamic(stride))
390  return false;
391 
392  return !ShapedType::isDynamic(offset);
393 }
394 
395 /// Convert a memref type to a bare pointer to the memref element type.
396 Type LLVMTypeConverter::convertMemRefToBarePtr(BaseMemRefType type) {
397  if (!canConvertToBarePtr(type))
398  return {};
399  Type elementType = convertType(type.getElementType());
400  if (!elementType)
401  return {};
402  return LLVM::LLVMPointerType::get(elementType, type.getMemorySpaceAsInt());
403 }
404 
405 /// Convert an n-D vector type to an LLVM vector type:
406 /// * 0-D `vector<T>` are converted to vector<1xT>
407 /// * 1-D `vector<axT>` remains as is while,
408 /// * n>1 `vector<ax...xkxT>` convert via an (n-1)-D array type to
409 /// `!llvm.array<ax...array<jxvector<kxT>>>`.
410 Type LLVMTypeConverter::convertVectorType(VectorType type) {
411  auto elementType = convertType(type.getElementType());
412  if (!elementType)
413  return {};
414  if (type.getShape().empty())
415  return VectorType::get({1}, elementType);
416  Type vectorType = VectorType::get(type.getShape().back(), elementType,
417  type.getNumScalableDims());
418  assert(LLVM::isCompatibleVectorType(vectorType) &&
419  "expected vector type compatible with the LLVM dialect");
420  auto shape = type.getShape();
421  for (int i = shape.size() - 2; i >= 0; --i)
422  vectorType = LLVM::LLVMArrayType::get(vectorType, shape[i]);
423  return vectorType;
424 }
425 
426 /// Convert a type in the context of the default or bare pointer calling
427 /// convention. Calling convention sensitive types, such as MemRefType and
428 /// UnrankedMemRefType, are converted following the specific rules for the
429 /// calling convention. Calling convention independent types are converted
430 /// following the default LLVM type conversions.
432  if (options.useBarePtrCallConv)
433  if (auto memrefTy = type.dyn_cast<BaseMemRefType>())
434  return convertMemRefToBarePtr(memrefTy);
435 
436  return convertType(type);
437 }
438 
439 /// Promote the bare pointers in 'values' that resulted from memrefs to
440 /// descriptors. 'stdTypes' holds they types of 'values' before the conversion
441 /// to the LLVM-IR dialect (i.e., MemRefType, or any other builtin type).
443  ConversionPatternRewriter &rewriter, Location loc, ArrayRef<Type> stdTypes,
444  SmallVectorImpl<Value> &values) {
445  assert(stdTypes.size() == values.size() &&
446  "The number of types and values doesn't match");
447  for (unsigned i = 0, end = values.size(); i < end; ++i)
448  if (auto memrefTy = stdTypes[i].dyn_cast<MemRefType>())
449  values[i] = MemRefDescriptor::fromStaticShape(rewriter, loc, *this,
450  memrefTy, values[i]);
451 }
452 
453 /// Convert a non-empty list of types to be returned from a function into a
454 /// supported LLVM IR type. In particular, if more than one value is returned,
455 /// create an LLVM IR structure type with elements that correspond to each of
456 /// the MLIR types converted with `convertType`.
458  assert(!types.empty() && "expected non-empty list of type");
459 
460  if (types.size() == 1)
461  return convertCallingConventionType(types.front());
462 
463  SmallVector<Type, 8> resultTypes;
464  resultTypes.reserve(types.size());
465  for (auto t : types) {
466  auto converted = convertCallingConventionType(t);
467  if (!converted || !LLVM::isCompatibleType(converted))
468  return {};
469  resultTypes.push_back(converted);
470  }
471 
472  return LLVM::LLVMStructType::getLiteral(&getContext(), resultTypes);
473 }
474 
476  OpBuilder &builder) {
477  // Alloca with proper alignment. We do not expect optimizations of this
478  // alloca op and so we omit allocating at the entry block.
479  auto ptrType = LLVM::LLVMPointerType::get(operand.getType());
480  Value one = builder.create<LLVM::ConstantOp>(loc, builder.getI64Type(),
481  builder.getIndexAttr(1));
482  Value allocated =
483  builder.create<LLVM::AllocaOp>(loc, ptrType, one, /*alignment=*/0);
484  // Store into the alloca'ed descriptor.
485  builder.create<LLVM::StoreOp>(loc, operand, allocated);
486  return allocated;
487 }
488 
490  ValueRange opOperands,
491  ValueRange operands,
492  OpBuilder &builder) {
493  SmallVector<Value, 4> promotedOperands;
494  promotedOperands.reserve(operands.size());
495  for (auto it : llvm::zip(opOperands, operands)) {
496  auto operand = std::get<0>(it);
497  auto llvmOperand = std::get<1>(it);
498 
499  if (options.useBarePtrCallConv) {
500  // For the bare-ptr calling convention, we only have to extract the
501  // aligned pointer of a memref.
502  if (auto memrefType = operand.getType().dyn_cast<MemRefType>()) {
503  MemRefDescriptor desc(llvmOperand);
504  llvmOperand = desc.alignedPtr(builder, loc);
505  } else if (operand.getType().isa<UnrankedMemRefType>()) {
506  llvm_unreachable("Unranked memrefs are not supported");
507  }
508  } else {
509  if (operand.getType().isa<UnrankedMemRefType>()) {
510  UnrankedMemRefDescriptor::unpack(builder, loc, llvmOperand,
511  promotedOperands);
512  continue;
513  }
514  if (auto memrefType = operand.getType().dyn_cast<MemRefType>()) {
515  MemRefDescriptor::unpack(builder, loc, llvmOperand, memrefType,
516  promotedOperands);
517  continue;
518  }
519  }
520 
521  promotedOperands.push_back(llvmOperand);
522  }
523  return promotedOperands;
524 }
525 
526 /// Callback to convert function argument types. It converts a MemRef function
527 /// argument to a list of non-aggregate types containing descriptor
528 /// information, and an UnrankedmemRef function argument to a list containing
529 /// the rank and a pointer to a descriptor struct.
531  Type type,
532  SmallVectorImpl<Type> &result) {
533  if (auto memref = type.dyn_cast<MemRefType>()) {
534  // In signatures, Memref descriptors are expanded into lists of
535  // non-aggregate values.
536  auto converted =
537  converter.getMemRefDescriptorFields(memref, /*unpackAggregates=*/true);
538  if (converted.empty())
539  return failure();
540  result.append(converted.begin(), converted.end());
541  return success();
542  }
543  if (type.isa<UnrankedMemRefType>()) {
544  auto converted = converter.getUnrankedMemRefDescriptorFields();
545  if (converted.empty())
546  return failure();
547  result.append(converted.begin(), converted.end());
548  return success();
549  }
550  auto converted = converter.convertType(type);
551  if (!converted)
552  return failure();
553  result.push_back(converted);
554  return success();
555 }
556 
557 /// Callback to convert function argument types. It converts MemRef function
558 /// arguments to bare pointers to the MemRef element type.
560  Type type,
561  SmallVectorImpl<Type> &result) {
562  auto llvmTy = converter.convertCallingConventionType(type);
563  if (!llvmTy)
564  return failure();
565 
566  result.push_back(llvmTy);
567  return success();
568 }
static llvm::ManagedStatic< PassManagerOptions > options
This class provides a shared interface for ranked and unranked memref types.
Definition: BuiltinTypes.h:114
unsigned getMemorySpaceAsInt() const
[deprecated] Returns the memory space in old raw integer representation.
Type getElementType() const
Returns the element type of this memref type.
IntegerAttr getIndexAttr(int64_t value)
Definition: Builders.cpp:109
IntegerType getI64Type()
Definition: Builders.cpp:70
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.
unsigned getTypeSize(Type t) const
Returns the size of the given type in the current scope.
Conversion from types to the LLVM IR dialect.
Definition: TypeConverter.h:30
LLVM::LLVMDialect * llvmDialect
Pointer to the LLVM dialect.
unsigned getPointerBitwidth(unsigned addressSpace=0)
Gets the pointer bitwidth.
Type packFunctionResults(TypeRange types)
Convert a non-empty list of types to be returned from a function into a supported LLVM IR type.
LLVM::LLVMDialect * getDialect()
Returns the LLVM dialect.
Definition: TypeConverter.h:79
SmallVector< Value, 4 > promoteOperands(Location loc, ValueRange opOperands, ValueRange operands, OpBuilder &builder)
Promote the LLVM representation of all operands including promoting MemRef descriptors to stack and u...
MLIRContext & getContext()
Returns the MLIR context.
Type convertCallingConventionType(Type type)
Convert a type in the context of the default or bare pointer calling convention.
Type getIndexType()
Gets the LLVM representation of the index type.
unsigned getMemRefDescriptorSize(MemRefType type, const DataLayout &layout)
Returns the size of the memref descriptor object in bytes.
void promoteBarePtrsToDescriptors(ConversionPatternRewriter &rewriter, Location loc, ArrayRef< Type > stdTypes, SmallVectorImpl< Value > &values)
Promote the bare pointers in 'values' that resulted from memrefs to descriptors.
Type convertFunctionSignature(FunctionType funcTy, bool isVariadic, SignatureConversion &result)
Convert a function type.
LogicalResult convertType(Type t, SmallVectorImpl< Type > &results)
Convert the given type.
std::pair< Type, bool > convertFunctionTypeCWrapper(FunctionType type)
Converts the function type to a C-compatible format, in particular using pointers to memref descripto...
friend LogicalResult structFuncArgTypeConverter(LLVMTypeConverter &converter, Type type, SmallVectorImpl< Type > &result)
Give structFuncArgTypeConverter access to memref-specific functions.
LLVMTypeConverter(MLIRContext *ctx, const DataLayoutAnalysis *analysis=nullptr)
Create an LLVMTypeConverter using the default LowerToLLVMOptions.
static bool canConvertToBarePtr(BaseMemRefType type)
Check if a memref type can be converted to a bare pointer.
unsigned getIndexTypeBitwidth()
Gets the bitwidth of the index type when converted to LLVM.
Value promoteOneMemRefDescriptor(Location loc, Value operand, OpBuilder &builder)
Promote the LLVM struct representation of one MemRef descriptor to stack and use pointer to struct to...
unsigned getUnrankedMemRefDescriptorSize(UnrankedMemRefType type, const DataLayout &layout)
Returns the size of the unranked memref descriptor object in bytes.
LLVM dialect structure type representing a collection of different-typed elements manipulated togethe...
Definition: LLVMTypes.h:107
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:449
static LLVMStructType getIdentified(MLIRContext *context, StringRef name)
Gets or creates an identified struct with the given name in the provided context.
Definition: LLVMTypes.cpp:421
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:64
Options to control the LLVM lowering.
llvm::DataLayout dataLayout
The data layout of the module to produce.
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:56
Helper class to produce LLVM dialect operations extracting or inserting elements of a MemRef descript...
Definition: MemRefBuilder.h:33
static Value pack(OpBuilder &builder, Location loc, LLVMTypeConverter &converter, MemRefType type, ValueRange values)
Builds IR populating a MemRef descriptor structure from a list of individual values composing that de...
static MemRefDescriptor fromStaticShape(OpBuilder &builder, Location loc, LLVMTypeConverter &typeConverter, MemRefType type, Value memory)
Builds IR creating a MemRef descriptor that represents type and populates it with static shape and st...
Value alignedPtr(OpBuilder &builder, Location loc)
Builds IR extracting the aligned pointer from the descriptor.
static void unpack(OpBuilder &builder, Location loc, Value packed, MemRefType type, SmallVectorImpl< Value > &results)
Builds IR extracting individual elements of a MemRef descriptor structure and returning them as resul...
This class helps build Operations.
Definition: Builders.h:198
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
Definition: Builders.cpp:422
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
Definition: Operation.h:324
This class provides all of the information necessary to convert a type signature.
void addInputs(unsigned origInputNo, ArrayRef< Type > types)
Remap an input of the original signature with a new set of types.
ArrayRef< Type > getConvertedTypes() const
Return the argument types for the new signature.
void addConversion(FnT &&callback)
Register a conversion function.
void addArgumentMaterialization(FnT &&callback)
Register a materialization function, which must be convertible to the following form: Optional<Value>...
LogicalResult convertTypes(TypeRange types, SmallVectorImpl< Type > &results)
Convert the given set of types, filling 'results' as necessary.
void addSourceMaterialization(FnT &&callback)
This method registers a materialization that will be called when converting a legal type to an illega...
void addTargetMaterialization(FnT &&callback)
This method registers a materialization that will be called when converting type from an illegal,...
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
U cast() const
Definition: Types.h:280
U dyn_cast() const
Definition: Types.h:270
bool isa() const
Definition: Types.h:260
static void unpack(OpBuilder &builder, Location loc, Value packed, SmallVectorImpl< Value > &results)
Builds IR extracting individual elements that compose an unranked memref descriptor and returns them ...
static Value pack(OpBuilder &builder, Location loc, LLVMTypeConverter &converter, UnrankedMemRefType type, ValueRange values)
Builds IR populating an unranked MemRef descriptor structure from a list of individual constituent va...
This class provides an abstraction over the different types of ranges over Values.
Definition: ValueRange.h:349
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:85
Type getType() const
Return the type of this value.
Definition: Value.h:114
bool isCompatibleVectorType(Type type)
Returns true if the given type is a vector type compatible with the LLVM dialect.
Definition: LLVMTypes.cpp:857
bool isCompatibleType(Type type)
Returns true if the given type is compatible with the LLVM dialect.
Definition: LLVMTypes.cpp:839
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
Definition: Matchers.h:230
Include the generated interface declarations.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
LogicalResult barePtrFuncArgTypeConverter(LLVMTypeConverter &converter, Type type, SmallVectorImpl< Type > &result)
Callback to convert function argument types.
LogicalResult getStridesAndOffset(MemRefType t, SmallVectorImpl< int64_t > &strides, int64_t &offset)
Returns the strides of the MemRef if the layout map is in strided form.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
LogicalResult structFuncArgTypeConverter(LLVMTypeConverter &converter, Type type, SmallVectorImpl< Type > &result)
Callback to convert function argument types.
bool isStrided(MemRefType t)
Return true if the layout for t is compatible with strided semantics.
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
Definition: LogicalResult.h:72
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26