26 :
llvmDialect(ctx->getOrLoadDialect<LLVM::LLVMDialect>()), options(options),
27 dataLayoutAnalysis(analysis) {
28 assert(
llvmDialect &&
"LLVM IR dialect is not registered");
31 addConversion([&](ComplexType type) {
return convertComplexType(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); });
39 addConversion([&](VectorType type) {
return convertVectorType(type); });
62 results.push_back(type);
68 type.getContext(), (
"_Converted_" + type.
getName()).str());
70 while (convertedType.isInitialized()) {
71 assert(counter != UINT_MAX &&
72 "about to overflow struct renaming counter in conversion");
75 (
"_Converted_" + std::to_string(counter) + type.
getName()).str());
77 if (llvm::count(callStack, type) > 1) {
78 results.push_back(convertedType);
83 convertedElemTypes.reserve(type.
getBody().size());
87 if (
failed(convertedType.setBody(convertedElemTypes, type.
isPacked())))
89 results.push_back(convertedType);
94 convertedSubtypes.reserve(type.
getBody().size());
99 type.getContext(), convertedSubtypes, type.
isPacked()));
109 if (!convertedResType)
127 if (inputs.size() == 1)
137 if (inputs.size() == 1)
146 if (inputs.size() != 1)
149 return builder.
create<UnrealizedConversionCastOp>(loc, resultType, inputs)
155 if (inputs.size() != 1)
158 return builder.
create<UnrealizedConversionCastOp>(loc, resultType, inputs)
173 return options.
dataLayout.getPointerSizeInBits(addressSpace);
176 Type LLVMTypeConverter::convertIndexType(IndexType type) {
180 Type LLVMTypeConverter::convertIntegerType(IntegerType type) {
181 return IntegerType::get(&
getContext(), type.getWidth());
184 Type LLVMTypeConverter::convertFloatType(
FloatType type) {
return type; }
190 Type LLVMTypeConverter::convertComplexType(ComplexType type) {
191 auto elementType =
convertType(type.getElementType());
193 {elementType, elementType});
198 Type LLVMTypeConverter::convertFunctionType(FunctionType type) {
210 FunctionType funcTy,
bool isVariadic,
218 Type type = en.value();
220 if (
failed(funcArgConverter(*
this, type, converted)))
228 Type resultType = funcTy.getNumResults() == 0
239 std::pair<Type, bool>
242 bool resultIsNowArg =
false;
244 Type resultType = type.getNumResults() == 0
254 resultType = LLVM::LLVMVoidType::get(&
getContext());
255 resultIsNowArg =
true;
258 for (
Type t : type.getInputs()) {
264 inputs.push_back(converted);
299 LLVMTypeConverter::getMemRefDescriptorFields(MemRefType type,
300 bool unpackAggregates) {
302 "Non-strided layout maps must have been normalized away");
312 auto rank = type.getRank();
316 if (unpackAggregates)
317 results.insert(results.end(), 2 * rank, indexTy);
326 unsigned space = type.getMemorySpaceAsInt();
333 Type LLVMTypeConverter::convertMemRefType(MemRefType type) {
337 getMemRefDescriptorFields(type,
false);
359 unsigned space = type.getMemorySpaceAsInt();
368 getUnrankedMemRefDescriptorFields());
379 auto memrefTy = type.
cast<MemRefType>();
380 if (!memrefTy.hasStaticShape())
388 for (int64_t stride : strides)
389 if (ShapedType::isDynamicStrideOrOffset(stride))
392 return !ShapedType::isDynamicStrideOrOffset(offset);
410 Type LLVMTypeConverter::convertVectorType(VectorType type) {
411 auto elementType =
convertType(type.getElementType());
414 if (type.getShape().empty())
415 return VectorType::get({1}, elementType);
416 Type vectorType = VectorType::get(type.getShape().back(), elementType,
417 type.getNumScalableDims());
419 "expected vector type compatible with the LLVM dialect");
420 auto shape = type.getShape();
421 for (
int i = shape.size() - 2; i >= 0; --i)
434 return convertMemRefToBarePtr(memrefTy);
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>())
450 memrefTy, values[i]);
458 assert(!types.empty() &&
"expected non-empty list of type");
460 if (types.size() == 1)
464 resultTypes.reserve(types.size());
465 for (
auto t : types) {
469 resultTypes.push_back(converted);
478 auto int64Ty = IntegerType::get(builder.
getContext(), 64);
479 auto indexType = IndexType::get(context);
483 Value one = builder.
create<LLVM::ConstantOp>(loc, int64Ty,
484 IntegerAttr::get(indexType, 1));
486 builder.
create<LLVM::AllocaOp>(loc, ptrType, one, 0);
488 builder.
create<LLVM::StoreOp>(loc, operand, allocated);
497 promotedOperands.reserve(operands.size());
498 for (
auto it : llvm::zip(opOperands, operands)) {
499 auto operand = std::get<0>(it);
500 auto llvmOperand = std::get<1>(it);
505 if (
auto memrefType = operand.getType().dyn_cast<MemRefType>()) {
509 llvm_unreachable(
"Unranked memrefs are not supported");
517 if (
auto memrefType = operand.getType().dyn_cast<MemRefType>()) {
524 promotedOperands.push_back(llvmOperand);
526 return promotedOperands;
536 if (
auto memref = type.
dyn_cast<MemRefType>()) {
540 converter.getMemRefDescriptorFields(memref,
true);
541 if (converted.empty())
543 result.append(converted.begin(), converted.end());
547 auto converted = converter.getUnrankedMemRefDescriptorFields();
548 if (converted.empty())
550 result.append(converted.begin(), converted.end());
556 result.push_back(converted);
569 result.push_back(llvmTy);
TODO: Remove this file when SCCP and integer range analysis have been ported to the new framework...
friend LogicalResult structFuncArgTypeConverter(LLVMTypeConverter &converter, Type type, SmallVectorImpl< Type > &result)
Give structFuncArgTypeConverter access to memref-specific functions.
LogicalResult convertTypes(TypeRange types, SmallVectorImpl< Type > &results)
Convert the given set of types, filling 'results' as necessary.
ArrayRef< Type > getConvertedTypes() const
Return the argument types for the new signature.
MLIRContext * getContext() const
StringRef getName()
Returns the name of an identified struct.
void promoteBarePtrsToDescriptors(ConversionPatternRewriter &rewriter, Location loc, ArrayRef< Type > stdTypes, SmallVectorImpl< Value > &values)
Promote the bare pointers in 'values' 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.
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.
LogicalResult convertType(Type t, SmallVectorImpl< Type > &results)
Convert the given type.
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...
LLVM dialect function type.
bool canConvertToBarePtr(BaseMemRefType type)
Check if a memref type can be converted to a bare pointer.
bool isOpaque() const
Returns true if this type is the opaque pointer type, i.e., it has no pointed-to type.
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.
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...
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...
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.
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
This class represents an efficient way to signal success or failure.
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.
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.
bool isVarArg() const
Returns whether the function is variadic.
bool isStrided(MemRefType t)
Return true if the layout for t is compatible with strided semantics.
Helper class to produce LLVM dialect operations extracting or inserting elements of a MemRef descript...
Type getElementType() const
Returns the element type of the array.
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)
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...
unsigned getNumParams()
Returns the number of arguments to the function.
static LLVMPointerType get(MLIRContext *context, unsigned addressSpace=0)
Gets or creates an instance of LLVM dialect pointer type pointing to an object of pointee type in the...
This class provides an abstraction over the various different ranges of value types.
ArrayRef< Type > getBody() const
Returns the list of element types contained in a non-opaque struct.
static LLVMStructType getIdentified(MLIRContext *context, StringRef name)
Gets or creates an identified struct with the given name in the provided context. ...
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...
ArrayRef< Type > getParams() const
Returns a list of argument types of the function.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
unsigned getNumElements() const
Returns the number of elements in the array type.
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.
Value alignedPtr(OpBuilder &builder, Location loc)
Builds IR extracting the aligned pointer from the descriptor.
Type getType() const
Return the type of this value.
This class provides a shared interface for ranked and unranked memref types.
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...
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. ...
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 to the LLVM IR dialect.
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.
bool isIdentified() const
Checks if a struct is identified.
Options to control the LLVM lowering.
This class implements a pattern rewriter for use with ConversionPatterns.
LLVM dialect pointer type.
unsigned getIndexTypeBitwidth()
Gets the bitwidth of the index type when converted to LLVM.
Type getReturnType() const
Returns the result type of the function.
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...
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.
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. It may be null if the pointer is opaque.
LLVM::LLVMDialect * getDialect()
Returns the LLVM dialect.
The main mechanism for performing data layout queries.