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