57 return builder.
create<LLVM::ConstantOp>(loc, resultType,
77 for (
int i = 0, e = indices.size(); i < e; ++i) {
78 Value increment = indices[i];
79 if (strides[i] != 1) {
81 ShapedType::isDynamic(strides[i])
82 ? memRefDescriptor.stride(rewriter, loc, i)
84 increment = rewriter.
create<LLVM::MulOp>(loc, increment, stride);
87 index ? rewriter.
create<LLVM::AddOp>(loc, index, increment) : increment;
90 Type elementPtrType = memRefDescriptor.getElementPtrType();
91 return index ? rewriter.
create<LLVM::GEPOp>(
101 MemRefType type)
const {
104 return type.getLayout().isIdentity();
119 "layout maps must have been normalized away");
120 assert(count(memRefType.getShape(), ShapedType::kDynamic) ==
121 static_cast<ssize_t
>(dynamicSizes.size()) &&
122 "dynamicSizes size doesn't match dynamic sizes count in memref shape");
124 sizes.reserve(memRefType.getRank());
125 unsigned dynamicIndex = 0;
127 for (int64_t size : memRefType.getShape()) {
129 size == ShapedType::kDynamic
130 ? dynamicSizes[dynamicIndex++]
137 strides.resize(memRefType.getRank());
138 for (
auto i = memRefType.getRank(); i-- > 0;) {
139 strides[i] = runningStride;
141 int64_t staticSize = memRefType.getShape()[i];
144 bool useSizeAsStride = stride == 1;
145 if (staticSize == ShapedType::kDynamic)
146 stride = ShapedType::kDynamic;
147 if (stride != ShapedType::kDynamic)
148 stride *= staticSize;
151 runningStride = sizes[i];
152 else if (stride == ShapedType::kDynamic)
154 rewriter.
create<LLVM::MulOp>(loc, runningStride, sizes[i]);
162 Value nullPtr = rewriter.
create<LLVM::ZeroOp>(loc, elementPtrType);
164 loc, elementPtrType, elementType, nullPtr, runningStride);
167 size = runningStride;
180 auto nullPtr = rewriter.
create<LLVM::ZeroOp>(loc, convertedPtrType);
181 auto gep = rewriter.
create<LLVM::GEPOp>(loc, convertedPtrType, llvmType,
189 assert(count(memRefType.getShape(), ShapedType::kDynamic) ==
190 static_cast<ssize_t
>(dynamicSizes.size()) &&
191 "dynamicSizes size doesn't match dynamic sizes count in memref shape");
194 Value numElements = memRefType.getRank() == 0
197 unsigned dynamicIndex = 0;
200 for (int64_t staticSize : memRefType.getShape()) {
203 staticSize == ShapedType::kDynamic
204 ? dynamicSizes[dynamicIndex++]
206 numElements = rewriter.
create<LLVM::MulOp>(loc, numElements, size);
209 staticSize == ShapedType::kDynamic
210 ? dynamicSizes[dynamicIndex++]
226 memRefDescriptor.setAllocatedPtr(rewriter, loc, allocatedPtr);
229 memRefDescriptor.setAlignedPtr(rewriter, loc, alignedPtr);
233 memRefDescriptor.setOffset(
238 memRefDescriptor.setSize(rewriter, loc, en.index(), en.value());
242 memRefDescriptor.setStride(rewriter, loc, en.index(), en.value());
244 return memRefDescriptor;
250 assert(origTypes.size() == operands.size() &&
251 "expected as may original types as operands");
256 for (
unsigned i = 0, e = operands.size(); i < e; ++i) {
257 if (
auto memRefType = dyn_cast<UnrankedMemRefType>(origTypes[i])) {
258 unrankedMemrefs.emplace_back(operands[i]);
263 unrankedAddressSpaces.emplace_back(*addressSpace);
267 if (unrankedMemrefs.empty())
273 unrankedMemrefs, unrankedAddressSpaces,
281 LLVM::LLVMFuncOp freeFunc, mallocFunc;
287 unsigned unrankedMemrefPos = 0;
288 for (
unsigned i = 0, e = operands.size(); i < e; ++i) {
289 Type type = origTypes[i];
290 if (!isa<UnrankedMemRefType>(type))
292 Value allocationSize = sizes[unrankedMemrefPos++];
298 ? builder.
create<LLVM::CallOp>(loc, mallocFunc, allocationSize)
305 builder.
create<LLVM::MemcpyOp>(loc, memory, source, allocationSize,
false);
307 builder.
create<LLVM::CallOp>(loc, freeFunc, source);
319 updatedDesc.setRank(builder, loc, rank);
320 updatedDesc.setMemRefDescPtr(builder, loc, memory);
322 operands[i] = updatedDesc;
333 IntegerOverflowFlags overflowFlags) {
334 if (
auto iface = dyn_cast<IntegerOverflowFlagsInterface>(op))
335 iface.setOverflowFlags(overflowFlags);
344 IntegerOverflowFlags overflowFlags) {
348 if (numResults != 0) {
349 resultTypes.push_back(
351 if (!resultTypes.back())
358 resultTypes, targetAttrs);
371 results.reserve(numResults);
372 for (
unsigned i = 0; i < numResults; ++i) {
373 results.push_back(rewriter.
create<LLVM::ExtractValueOp>(
IntegerAttr getIndexAttr(int64_t value)
StringAttr getStringAttr(const Twine &bytes)
MLIRContext * getContext() const
This class implements a pattern rewriter for use with ConversionPatterns.
void replaceOp(Operation *op, ValueRange newValues) override
PatternRewriter hook for replacing an operation.
void eraseOp(Operation *op) override
PatternRewriter hook for erasing a dead operation.
Base class for the conversion patterns.
const TypeConverter * typeConverter
An optional type converter for use by this pattern.
const TypeConverter * getTypeConverter() const
Return the type converter held by this pattern, or nullptr if the pattern does not require type conve...
Type getVoidType() const
Gets the MLIR type wrapping the LLVM void type.
MemRefDescriptor createMemRefDescriptor(Location loc, MemRefType memRefType, Value allocatedPtr, Value alignedPtr, ArrayRef< Value > sizes, ArrayRef< Value > strides, ConversionPatternRewriter &rewriter) const
Creates and populates a canonical memref descriptor struct.
ConvertToLLVMPattern(StringRef rootOpName, MLIRContext *context, const LLVMTypeConverter &typeConverter, PatternBenefit benefit=1)
void getMemRefDescriptorSizes(Location loc, MemRefType memRefType, ValueRange dynamicSizes, ConversionPatternRewriter &rewriter, SmallVectorImpl< Value > &sizes, SmallVectorImpl< Value > &strides, Value &size, bool sizeInBytes=true) const
Computes sizes, strides and buffer size of memRefType with identity layout.
Type getIndexType() const
Gets the MLIR type wrapping the LLVM integer type whose bit width is defined by the used type convert...
const LLVMTypeConverter * getTypeConverter() const
Value getStridedElementPtr(Location loc, MemRefType type, Value memRefDesc, ValueRange indices, ConversionPatternRewriter &rewriter) const
Value getNumElements(Location loc, MemRefType memRefType, ValueRange dynamicSizes, ConversionPatternRewriter &rewriter) const
Computes total number of elements for the given MemRef and dynamicSizes.
LLVM::LLVMDialect & getDialect() const
Returns the LLVM dialect.
Value getSizeInBytes(Location loc, Type type, ConversionPatternRewriter &rewriter) const
Computes the size of type in bytes.
Type getIntPtrType(unsigned addressSpace=0) const
Gets the MLIR type wrapping the LLVM integer type whose bit width corresponds to that of a LLVM point...
LogicalResult copyUnrankedDescriptors(OpBuilder &builder, Location loc, TypeRange origTypes, SmallVectorImpl< Value > &operands, bool toDynamic) const
Copies the memory descriptor for any operands that were unranked descriptors originally to heap-alloc...
Type getElementPtrType(MemRefType type) const
Returns the type of a pointer to an element of the memref.
static Value createIndexAttrConstant(OpBuilder &builder, Location loc, Type resultType, int64_t value)
Create a constant Op producing a value of resultType from an index-typed integer attribute.
bool isConvertibleAndHasIdentityMaps(MemRefType type) const
Returns if the given memref has identity maps and the element type is convertible to LLVM.
Type getVoidPtrType() const
Get the MLIR type wrapping the LLVM i8* type.
This class provides support for representing a failure result, or a valid value of type T.
Conversion from types to the LLVM IR dialect.
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.
LogicalResult convertType(Type t, SmallVectorImpl< Type > &results) const
Convert the given type.
FailureOr< unsigned > getMemRefAddressSpace(BaseMemRefType type) const
Return the LLVM address space corresponding to the memory space of the memref type type or failure if...
Type getIndexType() const
Gets the LLVM representation of the index type.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
MLIRContext is the top-level object for a collection of MLIR operations.
Helper class to produce LLVM dialect operations extracting or inserting elements of a MemRef descript...
static MemRefDescriptor undef(OpBuilder &builder, Location loc, Type descriptorType)
Builds IR creating an undef value of the descriptor type.
This class helps build Operations.
Block::iterator getInsertionPoint() const
Returns the current insertion point of the builder.
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
Operation is the basic unit of execution within MLIR.
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
Location getLoc()
The source location the operation was defined or derived from.
result_type_range getResultTypes()
unsigned getNumResults()
Return the number of results held by this operation.
This class represents the benefit of a pattern match in a unitless scheme that ranges from 0 (very li...
MLIRContext * getContext() const
Return the MLIRContext used to create this pattern.
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.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Value memRefDescPtr(OpBuilder &builder, Location loc) const
Builds IR extracting ranked memref descriptor ptr.
static UnrankedMemRefDescriptor undef(OpBuilder &builder, Location loc, Type descriptorType)
Builds IR creating an undef value of the descriptor type.
static void computeSizes(OpBuilder &builder, Location loc, const LLVMTypeConverter &typeConverter, ArrayRef< UnrankedMemRefDescriptor > values, ArrayRef< unsigned > addressSpaces, SmallVectorImpl< Value > &sizes)
Builds IR computing the sizes in bytes (suitable for opaque allocation) and appends the corresponding...
Value rank(OpBuilder &builder, Location loc) const
Builds IR extracting the rank from the descriptor.
This class provides an abstraction over the different types of ranges over Values.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
LogicalResult oneToOneRewrite(Operation *op, StringRef targetOp, ValueRange operands, ArrayRef< NamedAttribute > targetAttrs, const LLVMTypeConverter &typeConverter, ConversionPatternRewriter &rewriter, IntegerOverflowFlags overflowFlags=IntegerOverflowFlags::none)
Replaces the given operation "op" with a new operation of type "targetOp" and given operands.
void setNativeProperties(Operation *op, IntegerOverflowFlags overflowFlags)
Handle generically setting flags as native properties on LLVM operations.
LLVM::LLVMFuncOp lookupOrCreateFreeFn(ModuleOp moduleOp)
LLVM::LLVMFuncOp lookupOrCreateMallocFn(ModuleOp moduleOp, Type indexType)
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
Include the generated interface declarations.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
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.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value.
This class represents an efficient way to signal success or failure.