MLIR 23.0.0git
ExpandOps.cpp
Go to the documentation of this file.
1//===- ExpandDivs.cpp - Expansion patterns for MemRef operations ----------===//
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
15
16namespace mlir {
17namespace memref {
18#define GEN_PASS_DEF_EXPANDOPSPASS
19#include "mlir/Dialect/MemRef/Transforms/Passes.h.inc"
20} // namespace memref
21} // namespace mlir
22
23using namespace mlir;
24
25namespace {
26
27/// Converts `memref.reshape` that has a target shape of a statically-known
28/// size to `memref.reinterpret_cast`.
29struct MemRefReshapeOpConverter : public OpRewritePattern<memref::ReshapeOp> {
30public:
32
33 LogicalResult matchAndRewrite(memref::ReshapeOp op,
34 PatternRewriter &rewriter) const final {
35 auto shapeType = cast<MemRefType>(op.getShape().getType());
36 if (!shapeType.hasStaticShape())
37 return failure();
38
39 int64_t rank = cast<MemRefType>(shapeType).getDimSize(0);
40 SmallVector<OpFoldResult, 4> sizes, strides;
41 sizes.resize(rank);
42 strides.resize(rank);
43
44 Location loc = op.getLoc();
45 Value stride = nullptr;
46 int64_t staticStride = 1;
47 MemRefType resultType = cast<MemRefType>(op.getType());
48 for (int i = rank - 1; i >= 0; --i) {
49 Value size;
50 // Load dynamic sizes from the shape input, use constants for static dims.
51 if (resultType.isDynamicDim(i)) {
52 Value index = arith::ConstantIndexOp::create(rewriter, loc, i);
53 size = memref::LoadOp::create(rewriter, loc, op.getShape(), index);
54 if (!isa<IndexType>(size.getType()))
55 size = arith::IndexCastOp::create(rewriter, loc,
56 rewriter.getIndexType(), size);
57 sizes[i] = size;
58 } else {
59 auto sizeAttr = rewriter.getIndexAttr(resultType.getDimSize(i));
60 size = arith::ConstantOp::create(rewriter, loc, sizeAttr);
61 sizes[i] = sizeAttr;
62 }
63 if (stride)
64 strides[i] = stride;
65 else
66 strides[i] = rewriter.getIndexAttr(staticStride);
67
68 if (i > 0) {
69 if (stride) {
70 stride = arith::MulIOp::create(rewriter, loc, stride, size);
71 } else if (resultType.isDynamicDim(i)) {
72 stride = arith::MulIOp::create(
73 rewriter, loc,
74 arith::ConstantIndexOp::create(rewriter, loc, staticStride),
75 size);
76 } else {
77 staticStride *= resultType.getDimSize(i);
78 }
79 }
80 }
81 rewriter.replaceOpWithNewOp<memref::ReinterpretCastOp>(
82 op, resultType, op.getSource(), /*offset=*/rewriter.getIndexAttr(0),
83 sizes, strides);
84 return success();
85 }
86};
87
88struct ExpandOpsPass : public memref::impl::ExpandOpsPassBase<ExpandOpsPass> {
89 void runOnOperation() override {
90 MLIRContext &ctx = getContext();
91
92 RewritePatternSet patterns(&ctx);
94 ConversionTarget target(ctx);
95
96 target.addLegalDialect<arith::ArithDialect, memref::MemRefDialect>();
97 target.addDynamicallyLegalOp<memref::ReshapeOp>([](memref::ReshapeOp op) {
98 return !cast<MemRefType>(op.getShape().getType()).hasStaticShape();
99 });
100 if (failed(applyPartialConversion(getOperation(), target,
101 std::move(patterns))))
102 signalPassFailure();
103 }
104};
105
106} // namespace
107
109 patterns.add<MemRefReshapeOpConverter>(patterns.getContext());
110}
return success()
b getContext())
IntegerAttr getIndexAttr(int64_t value)
Definition Builders.cpp:112
IndexType getIndexType()
Definition Builders.cpp:55
MLIRContext * getContext() const
RewritePatternSet & add(ConstructorArg &&arg, ConstructorArgs &&...args)
Add an instance of each of the pattern types 'Ts' to the pattern list with the given arguments.
OpTy replaceOpWithNewOp(Operation *op, Args &&...args)
Replace the results of the given (original) op with a new op that is created without verification (re...
Type getType() const
Return the type of this value.
Definition Value.h:105
static ConstantIndexOp create(OpBuilder &builder, Location location, int64_t value)
Definition ArithOps.cpp:384
void populateExpandOpsPatterns(RewritePatternSet &patterns)
Collects a set of patterns to rewrite ops within the memref dialect.
detail::InFlightRemark failed(Location loc, RemarkOpts opts)
Report an optimization remark that failed.
Definition Remarks.h:717
Include the generated interface declarations.
OpRewritePattern is a wrapper around RewritePattern that allows for matching and rewriting against an...
OpRewritePattern(MLIRContext *context, PatternBenefit benefit=1, ArrayRef< StringRef > generatedNames={})
Patterns must specify the root operation name they match against, and can also specify the benefit of...