MLIR 24.0.0git
Pattern.h
Go to the documentation of this file.
1//===- Pattern.h - Pattern for conversion to the LLVM dialect ---*- 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#ifndef MLIR_CONVERSION_LLVMCOMMON_PATTERN_H
10#define MLIR_CONVERSION_LLVMCOMMON_PATTERN_H
11
16
17namespace mlir {
18class CallOpInterface;
19
20namespace LLVM {
21namespace detail {
22/// Replaces the given operation "op" with a new operation of type "targetOp"
23/// and given operands.
24LogicalResult oneToOneRewrite(Operation *op, StringRef targetOp,
25 ValueRange operands,
26 ArrayRef<NamedAttribute> targetAttrs,
27 Attribute propertiesAttr,
28 const LLVMTypeConverter &typeConverter,
29 ConversionPatternRewriter &rewriter);
30
31/// Replaces the given operation "op" with a call to an LLVM intrinsic with the
32/// specified name "intrinsic" and operands.
33///
34/// The rewrite performs a simple one-to-one matching between the op and LLVM
35/// intrinsic. For example:
36///
37/// ```mlir
38/// %res = intr.op %val : vector<16xf32>
39/// ```
40///
41/// can be converted to
42///
43/// ```mlir
44/// %res = llvm.call_intrinsic "intrinsic"(%val)
45/// ```
46///
47/// The provided operands must be LLVM-compatible.
48///
49/// Upholds a convention that multi-result operations get converted into an
50/// operation returning the LLVM IR structure type, in which case individual
51/// values are first extracted before replacing the original results.
52LogicalResult intrinsicRewrite(Operation *op, StringRef intrinsic,
53 ValueRange operands,
54 const LLVMTypeConverter &typeConverter,
55 RewriterBase &rewriter);
56
57/// Return "true" if the given type is an unsupported floating point type.
58/// In case of a vector type, return "true" if the element type is an
59/// unsupported floating point type.
60bool isUnsupportedFloatingPointType(const TypeConverter &typeConverter,
61 Type type);
62/// Return "true" if the given op has any unsupported floating point
63/// types (either operands or results).
65 const TypeConverter &typeConverter);
66} // namespace detail
67
68/// Decomposes a `src` value into a set of values of type `dstType` through
69/// series of bitcasts and vector ops. Handles int, float, vector types as well
70/// as LLVM aggregate types (LLVMArrayType, LLVMStructType) by recursively
71/// extracting elements.
72///
73/// When a non-aggregate's bitwidth is not evenly divisible by the bitwidth of
74/// `dstType` width, the source value will be zero-extended to the next
75/// (multiple of) that bitwidth before decomposition.
76///
77/// When `permitVariablySizedScalars` is true, leaf types that have no fixed
78/// bit width (e.g., `!llvm.ptr`) are passed through as-is (1 element in
79/// result). When false (default), encountering such a type returns failure.
80LogicalResult decomposeValue(OpBuilder &builder, Location loc, Value src,
82 bool permitVariablySizedScalars = false);
83
84/// Composes a set of `src` values into a single value of type `dstType` through
85/// series of bitcasts and vector ops, and aggregate builders. This is the
86/// inverse of `decomposeValue` and expects the values in `src` to have the
87/// order and padding bits that that function would produce.
89 Type dstType);
90
91/// Creates an `llvm.mlir.constant` producing `value` as `resultType`, which is
92/// expected to be the converted index type. The value attribute is built from
93/// `resultType` so that the two agree.
94Value createIndexAttrConstant(OpBuilder &builder, Location loc, Type resultType,
95 int64_t value);
96
97/// Performs the index computation to get to the element at `indices` of the
98/// memory pointed to by `memRefDesc`, using the layout map of `type`.
99/// The indices are linearized as:
100/// `base_offset + index_0 * stride_0 + ... + index_n * stride_n`.
102 OpBuilder &builder, Location loc, const LLVMTypeConverter &converter,
103 MemRefType type, Value memRefDesc, ValueRange indices,
104 LLVM::GEPNoWrapFlags noWrapFlags = LLVM::GEPNoWrapFlags::none);
105} // namespace LLVM
106
107/// Base class for operation conversions targeting the LLVM IR dialect. It
108/// provides the conversion patterns with access to the LLVMTypeConverter and
109/// the LowerToLLVMOptions. The class captures the LLVMTypeConverter and the
110/// LowerToLLVMOptions by reference meaning the references have to remain alive
111/// during the entire pattern lifetime.
112class ConvertToLLVMPattern : public ConversionPattern {
113public:
114 ConvertToLLVMPattern(StringRef rootOpName, MLIRContext *context,
115 const LLVMTypeConverter &typeConverter,
116 PatternBenefit benefit = 1);
117
118protected:
119 /// See `ConversionPattern::ConversionPattern` for information on the other
120 /// available constructors.
121 using ConversionPattern::ConversionPattern;
122
123 /// Returns the LLVM dialect.
124 LLVM::LLVMDialect &getDialect() const;
125
126 const LLVMTypeConverter *getTypeConverter() const;
127
128 /// Gets the MLIR type wrapping the LLVM integer type whose bit width is
129 /// defined by the used type converter.
130 Type getIndexType() const;
131
132 /// Gets the MLIR type wrapping the LLVM integer type whose bit width
133 /// corresponds to that of a LLVM pointer type.
134 Type getIntPtrType(unsigned addressSpace = 0) const;
135
136 /// Gets the MLIR type wrapping the LLVM void type.
137 Type getVoidType() const;
138
139 /// Get the MLIR type wrapping the LLVM i8* type.
140 [[deprecated("Use getPtrType() instead!")]]
141 Type getVoidPtrType() const;
142
143 /// Get the MLIR type wrapping the LLVM ptr type.
144 Type getPtrType(unsigned addressSpace = 0) const;
145
146 /// Create a constant Op producing a value of `resultType` from an index-typed
147 /// integer attribute.
148 static Value createIndexAttrConstant(OpBuilder &builder, Location loc,
149 Type resultType, int64_t value);
150
151 /// Convenience wrapper for the corresponding helper utility.
152 /// This is a strided getElementPtr variant with linearized subscripts.
154 ConversionPatternRewriter &rewriter, Location loc, MemRefType type,
155 Value memRefDesc, ValueRange indices,
156 LLVM::GEPNoWrapFlags noWrapFlags = LLVM::GEPNoWrapFlags::none) const;
157
158 /// Returns if the given memref type is convertible to LLVM and has an
159 /// identity layout map.
160 bool isConvertibleAndHasIdentityMaps(MemRefType type) const;
161
162 /// Returns the type of a pointer to an element of the memref.
163 Type getElementPtrType(MemRefType type) const;
164
165 /// Computes sizes, strides and buffer size of `memRefType` with identity
166 /// layout. Emits constant ops for the static sizes of `memRefType`, and uses
167 /// `dynamicSizes` for the others. Emits instructions to compute strides and
168 /// buffer size from these sizes.
169 ///
170 /// For example, memref<4x?xf32> with `sizeInBytes = true` emits:
171 /// `sizes[0]` = llvm.mlir.constant(4 : i64) : i64
172 /// `sizes[1]` = `dynamicSizes[0]`
173 /// `strides[1]` = llvm.mlir.constant(1 : i64) : i64
174 /// `strides[0]` = `sizes[0]`
175 /// %size = llvm.mul `sizes[0]`, `sizes[1]` : i64
176 /// %nullptr = llvm.mlir.zero : !llvm.ptr
177 /// %gep = llvm.getelementptr %nullptr[%size]
178 /// : (!llvm.ptr, i64) -> !llvm.ptr, f32
179 /// `sizeBytes` = llvm.ptrtoint %gep : !llvm.ptr to i64
180 ///
181 /// If `sizeInBytes = false`, memref<4x?xf32> emits:
182 /// `sizes[0]` = llvm.mlir.constant(4 : i64) : i64
183 /// `sizes[1]` = `dynamicSizes[0]`
184 /// `strides[1]` = llvm.mlir.constant(1 : i64) : i64
185 /// `strides[0]` = `sizes[0]`
186 /// %size = llvm.mul `sizes[0]`, `sizes[1]` : i64
187 void getMemRefDescriptorSizes(Location loc, MemRefType memRefType,
188 ValueRange dynamicSizes,
189 ConversionPatternRewriter &rewriter,
191 SmallVectorImpl<Value> &strides, Value &size,
192 bool sizeInBytes = true) const;
193
194 /// Computes the size of type in bytes.
196 ConversionPatternRewriter &rewriter) const;
197
198 /// Computes total number of elements for the given MemRef and dynamicSizes.
199 Value getNumElements(Location loc, MemRefType memRefType,
200 ValueRange dynamicSizes,
201 ConversionPatternRewriter &rewriter) const;
202
203 /// Creates and populates a canonical memref descriptor struct.
205 createMemRefDescriptor(Location loc, MemRefType memRefType,
206 Value allocatedPtr, Value alignedPtr,
207 ArrayRef<Value> sizes, ArrayRef<Value> strides,
208 ConversionPatternRewriter &rewriter) const;
209
210 /// Copies the given unranked memory descriptor to heap-allocated memory (if
211 /// toDynamic is true) or to stack-allocated memory (otherwise) and returns
212 /// the new descriptor. Also frees the previously used memory (that is assumed
213 /// to be heap-allocated) if toDynamic is false. Returns a "null" SSA value
214 /// on failure.
216 UnrankedMemRefType memRefType, Value operand,
217 bool toDynamic) const;
218
219 /// Copies the memory descriptor for any operands that were unranked
220 /// descriptors originally to heap-allocated memory (if toDynamic is true) or
221 /// to stack-allocated memory (otherwise). The vector of descriptors is
222 /// updated in place. Also frees the previously used memory (that is assumed
223 /// to be heap-allocated) if toDynamic is false.
224 LogicalResult copyUnrankedDescriptors(OpBuilder &builder, Location loc,
225 TypeRange origTypes,
226 SmallVectorImpl<Value> &operands,
227 bool toDynamic) const;
228};
229
230/// Utility class for operation conversions targeting the LLVM dialect that
231/// match exactly one source operation.
232template <typename SourceOp, bool FailOnUnsupportedFP = false>
234public:
235 using OpAdaptor = typename SourceOp::Adaptor;
237 typename SourceOp::template GenericAdaptor<ArrayRef<ValueRange>>;
238
239 explicit ConvertOpToLLVMPattern(const LLVMTypeConverter &typeConverter,
240 PatternBenefit benefit = 1)
241 : ConvertToLLVMPattern(SourceOp::getOperationName(),
242 &typeConverter.getContext(), typeConverter,
243 benefit) {}
244
245 /// Wrappers around the RewritePattern methods that pass the derived op type.
246 LogicalResult
248 ConversionPatternRewriter &rewriter) const final {
249 // Bail on unsupported floating point types. (These are type-converted to
250 // integer types.)
251 if (FailOnUnsupportedFP && LLVM::detail::opHasUnsupportedFloatingPointTypes(
252 op, *this->typeConverter)) {
253 return rewriter.notifyMatchFailure(op, "unsupported floating point type");
254 }
255 auto sourceOp = cast<SourceOp>(op);
256 return matchAndRewrite(sourceOp, OpAdaptor(operands, sourceOp), rewriter);
257 }
258 LogicalResult
260 ConversionPatternRewriter &rewriter) const final {
261 // Bail on unsupported floating point types. (These are type-converted to
262 // integer types.)
263 if (FailOnUnsupportedFP && LLVM::detail::opHasUnsupportedFloatingPointTypes(
264 op, *this->typeConverter)) {
265 return rewriter.notifyMatchFailure(op, "unsupported floating point type");
266 }
267 auto sourceOp = cast<SourceOp>(op);
268 return matchAndRewrite(sourceOp, OneToNOpAdaptor(operands, sourceOp),
269 rewriter);
270 }
271
272 /// Methods that operate on the SourceOp type. One of these must be
273 /// overridden by the derived pattern class.
274 virtual LogicalResult
275 matchAndRewrite(SourceOp op, OpAdaptor adaptor,
276 ConversionPatternRewriter &rewriter) const {
277 llvm_unreachable("matchAndRewrite is not implemented");
278 }
279 virtual LogicalResult
280 matchAndRewrite(SourceOp op, OneToNOpAdaptor adaptor,
281 ConversionPatternRewriter &rewriter) const {
282 return dispatchTo1To1(*this, op, adaptor, rewriter);
283 }
284
285private:
286 using ConvertToLLVMPattern::matchAndRewrite;
287};
288
289/// Utility class for operation conversions targeting the LLVM dialect that
290/// allows for matching and rewriting against an instance of an OpInterface
291/// class.
292template <typename SourceOp>
294public:
296 const LLVMTypeConverter &typeConverter, PatternBenefit benefit = 1)
297 : ConvertToLLVMPattern(typeConverter, Pattern::MatchInterfaceOpTypeTag(),
298 SourceOp::getInterfaceID(), benefit,
299 &typeConverter.getContext()) {}
300
301 /// Wrappers around the RewritePattern methods that pass the derived op type.
302 LogicalResult
304 ConversionPatternRewriter &rewriter) const final {
305 return matchAndRewrite(cast<SourceOp>(op), operands, rewriter);
306 }
307 LogicalResult
309 ConversionPatternRewriter &rewriter) const final {
310 return matchAndRewrite(cast<SourceOp>(op), operands, rewriter);
311 }
312
313 /// Methods that operate on the SourceOp type. One of these must be
314 /// overridden by the derived pattern class.
315 virtual LogicalResult
316 matchAndRewrite(SourceOp op, ArrayRef<Value> operands,
317 ConversionPatternRewriter &rewriter) const {
318 llvm_unreachable("matchAndRewrite is not implemented");
319 }
320 virtual LogicalResult
322 ConversionPatternRewriter &rewriter) const {
323 return dispatchTo1To1(*this, op, operands, rewriter);
324 }
325
326private:
327 using ConvertToLLVMPattern::matchAndRewrite;
328};
329
330/// Generic implementation of one-to-one conversion from "SourceOp" to
331/// "TargetOp" where the latter belongs to the LLVM dialect or an equivalent.
332/// Upholds a convention that multi-result operations get converted into an
333/// operation returning the LLVM IR structure type, in which case individual
334/// values must be extracted from using LLVM::ExtractValueOp before being used.
335template <typename SourceOp, typename TargetOp>
337public:
340
341 /// Converts the type of the result to an LLVM type, pass operands as is,
342 /// preserve attributes.
343 LogicalResult
344 matchAndRewrite(SourceOp op, typename SourceOp::Adaptor adaptor,
345 ConversionPatternRewriter &rewriter) const override {
347 op, TargetOp::getOperationName(), adaptor.getOperands(),
348 op->getDiscardableAttrDictionary().getValue(),
349 op->getPropertiesAsAttribute(), *this->getTypeConverter(), rewriter);
350 }
351};
352
353} // namespace mlir
354
355#endif // MLIR_CONVERSION_LLVMCOMMON_PATTERN_H
b getContext())
Attributes are known-constant values of operations.
Definition Attributes.h:25
LogicalResult matchAndRewrite(Operation *op, ArrayRef< Value > operands, ConversionPatternRewriter &rewriter) const final
Wrappers around the RewritePattern methods that pass the derived op type.
Definition Pattern.h:303
virtual LogicalResult matchAndRewrite(SourceOp op, ArrayRef< ValueRange > operands, ConversionPatternRewriter &rewriter) const
Definition Pattern.h:321
ConvertOpInterfaceToLLVMPattern(const LLVMTypeConverter &typeConverter, PatternBenefit benefit=1)
Definition Pattern.h:295
virtual LogicalResult matchAndRewrite(SourceOp op, ArrayRef< Value > operands, ConversionPatternRewriter &rewriter) const
Methods that operate on the SourceOp type.
Definition Pattern.h:316
LogicalResult matchAndRewrite(Operation *op, ArrayRef< ValueRange > operands, ConversionPatternRewriter &rewriter) const final
Definition Pattern.h:308
ConvertOpToLLVMPattern(const LLVMTypeConverter &typeConverter, PatternBenefit benefit=1)
Definition Pattern.h:239
LogicalResult matchAndRewrite(Operation *op, ArrayRef< Value > operands, ConversionPatternRewriter &rewriter) const final
Wrappers around the RewritePattern methods that pass the derived op type.
Definition Pattern.h:247
typename SourceOp::template GenericAdaptor< ArrayRef< ValueRange > > OneToNOpAdaptor
Definition Pattern.h:236
virtual LogicalResult matchAndRewrite(SourceOp op, OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const
Methods that operate on the SourceOp type.
Definition Pattern.h:275
virtual LogicalResult matchAndRewrite(SourceOp op, OneToNOpAdaptor adaptor, ConversionPatternRewriter &rewriter) const
Definition Pattern.h:280
LogicalResult matchAndRewrite(Operation *op, ArrayRef< ValueRange > operands, ConversionPatternRewriter &rewriter) const final
Definition Pattern.h:259
typename SourceOp::Adaptor OpAdaptor
Definition Pattern.h:235
Type getVoidType() const
Gets the MLIR type wrapping the LLVM void type.
Definition Pattern.cpp:47
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.
Definition Pattern.cpp:207
ConvertToLLVMPattern(StringRef rootOpName, MLIRContext *context, const LLVMTypeConverter &typeConverter, PatternBenefit benefit=1)
Definition Pattern.cpp:24
Value getStridedElementPtr(ConversionPatternRewriter &rewriter, Location loc, MemRefType type, Value memRefDesc, ValueRange indices, LLVM::GEPNoWrapFlags noWrapFlags=LLVM::GEPNoWrapFlags::none) const
Convenience wrapper for the corresponding helper utility.
Definition Pattern.cpp:71
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.
Definition Pattern.cpp:95
Type getPtrType(unsigned addressSpace=0) const
Get the MLIR type wrapping the LLVM ptr type.
Definition Pattern.cpp:51
Type getIndexType() const
Gets the MLIR type wrapping the LLVM integer type whose bit width is defined by the used type convert...
Definition Pattern.cpp:38
const LLVMTypeConverter * getTypeConverter() const
Definition Pattern.cpp:29
Value getNumElements(Location loc, MemRefType memRefType, ValueRange dynamicSizes, ConversionPatternRewriter &rewriter) const
Computes total number of elements for the given MemRef and dynamicSizes.
Definition Pattern.cpp:175
LLVM::LLVMDialect & getDialect() const
Returns the LLVM dialect.
Definition Pattern.cpp:34
Value getSizeInBytes(Location loc, Type type, ConversionPatternRewriter &rewriter) const
Computes the size of type in bytes.
Definition Pattern.cpp:160
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...
Definition Pattern.cpp:42
Value copyUnrankedDescriptor(OpBuilder &builder, Location loc, UnrankedMemRefType memRefType, Value operand, bool toDynamic) const
Copies the given unranked memory descriptor to heap-allocated memory (if toDynamic is true) or to sta...
Definition Pattern.cpp:236
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...
Definition Pattern.cpp:295
Type getElementPtrType(MemRefType type) const
Returns the type of a pointer to an element of the memref.
Definition Pattern.cpp:88
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.
Definition Pattern.cpp:64
bool isConvertibleAndHasIdentityMaps(MemRefType type) const
Returns if the given memref type is convertible to LLVM and has an identity layout map.
Definition Pattern.cpp:81
Type getVoidPtrType() const
Get the MLIR type wrapping the LLVM i8* type.
Definition Pattern.cpp:56
Conversion from types to the LLVM IR dialect.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition Location.h:76
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:63
Helper class to produce LLVM dialect operations extracting or inserting elements of a MemRef descript...
Generic implementation of one-to-one conversion from "SourceOp" to "TargetOp" where the latter belong...
Definition Pattern.h:336
OneToOneConvertToLLVMPattern< SourceOp, TargetOp > Super
Definition Pattern.h:339
LogicalResult matchAndRewrite(SourceOp op, typename SourceOp::Adaptor adaptor, ConversionPatternRewriter &rewriter) const override
Converts the type of the result to an LLVM type, pass operands as is, preserve attributes.
Definition Pattern.h:344
This class helps build Operations.
Definition Builders.h:210
Operation is the basic unit of execution within MLIR.
Definition Operation.h:87
This class represents the benefit of a pattern match in a unitless scheme that ranges from 0 (very li...
This class contains all of the data related to a pattern, but does not contain any methods or logic f...
This class coordinates the application of a rewrite on a set of IR, providing a way for clients to tr...
This class provides an abstraction over the various different ranges of value types.
Definition TypeRange.h:40
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition Types.h:74
This class provides an abstraction over the different types of ranges over Values.
Definition ValueRange.h:389
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
bool isUnsupportedFloatingPointType(const TypeConverter &typeConverter, Type type)
Return "true" if the given type is an unsupported floating point type.
Definition Pattern.cpp:678
LogicalResult oneToOneRewrite(Operation *op, StringRef targetOp, ValueRange operands, ArrayRef< NamedAttribute > targetAttrs, Attribute propertiesAttr, const LLVMTypeConverter &typeConverter, ConversionPatternRewriter &rewriter)
Replaces the given operation "op" with a new operation of type "targetOp" and given operands.
Definition Pattern.cpp:318
bool opHasUnsupportedFloatingPointTypes(Operation *op, const TypeConverter &typeConverter)
Return "true" if the given op has any unsupported floating point types (either operands or results).
Definition Pattern.cpp:689
LogicalResult intrinsicRewrite(Operation *op, StringRef intrinsic, ValueRange operands, const LLVMTypeConverter &typeConverter, RewriterBase &rewriter)
Replaces the given operation "op" with a call to an LLVM intrinsic with the specified name "intrinsic...
Definition Pattern.cpp:357
Value getStridedElementPtr(OpBuilder &builder, Location loc, const LLVMTypeConverter &converter, MemRefType type, Value memRefDesc, ValueRange indices, LLVM::GEPNoWrapFlags noWrapFlags=LLVM::GEPNoWrapFlags::none)
Performs the index computation to get to the element at indices of the memory pointed to by memRefDes...
Definition Pattern.cpp:620
LogicalResult decomposeValue(OpBuilder &builder, Location loc, Value src, Type dstType, SmallVectorImpl< Value > &result, bool permitVariablySizedScalars=false)
Decomposes a src value into a set of values of type dstType through series of bitcasts and vector ops...
Definition Pattern.cpp:512
Value createIndexAttrConstant(OpBuilder &builder, Location loc, Type resultType, int64_t value)
Creates an llvm.mlir.constant producing value as resultType, which is expected to be the converted in...
Definition Pattern.cpp:58
Value composeValue(OpBuilder &builder, Location loc, ValueRange src, Type dstType)
Composes a set of src values into a single value of type dstType through series of bitcasts and vecto...
Definition Pattern.cpp:611
Include the generated interface declarations.