1250dcf61SAlexander Belyaev //===- ShapeToShapeLowering.cpp - Prepare for lowering to Standard --------===// 2250dcf61SAlexander Belyaev // 3250dcf61SAlexander Belyaev // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4250dcf61SAlexander Belyaev // See https://llvm.org/LICENSE.txt for license information. 5250dcf61SAlexander Belyaev // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6250dcf61SAlexander Belyaev // 7250dcf61SAlexander Belyaev //===----------------------------------------------------------------------===// 8250dcf61SAlexander Belyaev 9250dcf61SAlexander Belyaev #include "PassDetail.h" 10*a54f4eaeSMogball #include "mlir/Dialect/Arithmetic/IR/Arithmetic.h" 11250dcf61SAlexander Belyaev #include "mlir/Dialect/Shape/IR/Shape.h" 12250dcf61SAlexander Belyaev #include "mlir/Dialect/Shape/Transforms/Passes.h" 136d10d317SStephan Herhut #include "mlir/Dialect/StandardOps/IR/Ops.h" 14250dcf61SAlexander Belyaev #include "mlir/IR/Builders.h" 15250dcf61SAlexander Belyaev #include "mlir/IR/PatternMatch.h" 16250dcf61SAlexander Belyaev #include "mlir/Pass/Pass.h" 17250dcf61SAlexander Belyaev #include "mlir/Transforms/DialectConversion.h" 18250dcf61SAlexander Belyaev 19250dcf61SAlexander Belyaev using namespace mlir; 20250dcf61SAlexander Belyaev using namespace mlir::shape; 21250dcf61SAlexander Belyaev 22250dcf61SAlexander Belyaev namespace { 23250dcf61SAlexander Belyaev /// Converts `shape.num_elements` to `shape.reduce`. 24250dcf61SAlexander Belyaev struct NumElementsOpConverter : public OpRewritePattern<NumElementsOp> { 25250dcf61SAlexander Belyaev public: 26250dcf61SAlexander Belyaev using OpRewritePattern::OpRewritePattern; 27250dcf61SAlexander Belyaev 28250dcf61SAlexander Belyaev LogicalResult matchAndRewrite(NumElementsOp op, 29250dcf61SAlexander Belyaev PatternRewriter &rewriter) const final; 30250dcf61SAlexander Belyaev }; 31250dcf61SAlexander Belyaev } // namespace 32250dcf61SAlexander Belyaev 33250dcf61SAlexander Belyaev LogicalResult 34250dcf61SAlexander Belyaev NumElementsOpConverter::matchAndRewrite(NumElementsOp op, 35250dcf61SAlexander Belyaev PatternRewriter &rewriter) const { 36250dcf61SAlexander Belyaev auto loc = op.getLoc(); 376d10d317SStephan Herhut Type valueType = op.getResult().getType(); 380bf4a82aSChristian Sigg Value init = op->getDialect() 396d10d317SStephan Herhut ->materializeConstant(rewriter, rewriter.getIndexAttr(1), 406d10d317SStephan Herhut valueType, loc) 416d10d317SStephan Herhut ->getResult(0); 42250dcf61SAlexander Belyaev ReduceOp reduce = rewriter.create<ReduceOp>(loc, op.shape(), init); 43250dcf61SAlexander Belyaev 44250dcf61SAlexander Belyaev // Generate reduce operator. 45250dcf61SAlexander Belyaev Block *body = reduce.getBody(); 46250dcf61SAlexander Belyaev OpBuilder b = OpBuilder::atBlockEnd(body); 476d10d317SStephan Herhut Value product = b.create<MulOp>(loc, valueType, body->getArgument(1), 486d10d317SStephan Herhut body->getArgument(2)); 49136eb79aSFrederik Gossen b.create<shape::YieldOp>(loc, product); 50250dcf61SAlexander Belyaev 51250dcf61SAlexander Belyaev rewriter.replaceOp(op, reduce.result()); 52250dcf61SAlexander Belyaev return success(); 53250dcf61SAlexander Belyaev } 54250dcf61SAlexander Belyaev 55250dcf61SAlexander Belyaev namespace { 56250dcf61SAlexander Belyaev struct ShapeToShapeLowering 57250dcf61SAlexander Belyaev : public ShapeToShapeLoweringBase<ShapeToShapeLowering> { 58250dcf61SAlexander Belyaev void runOnFunction() override; 59250dcf61SAlexander Belyaev }; 60250dcf61SAlexander Belyaev } // namespace 61250dcf61SAlexander Belyaev 62250dcf61SAlexander Belyaev void ShapeToShapeLowering::runOnFunction() { 637a9258e9SAlexander Belyaev MLIRContext &ctx = getContext(); 647a9258e9SAlexander Belyaev 65dc4e913bSChris Lattner RewritePatternSet patterns(&ctx); 663a506b31SChris Lattner populateShapeRewritePatterns(patterns); 67250dcf61SAlexander Belyaev 68250dcf61SAlexander Belyaev ConversionTarget target(getContext()); 69*a54f4eaeSMogball target.addLegalDialect<arith::ArithmeticDialect, ShapeDialect, 70*a54f4eaeSMogball StandardOpsDialect>(); 71250dcf61SAlexander Belyaev target.addIllegalOp<NumElementsOp>(); 723fffffa8SRiver Riddle if (failed(mlir::applyPartialConversion(getFunction(), target, 733fffffa8SRiver Riddle std::move(patterns)))) 74250dcf61SAlexander Belyaev signalPassFailure(); 75250dcf61SAlexander Belyaev } 76250dcf61SAlexander Belyaev 77dc4e913bSChris Lattner void mlir::populateShapeRewritePatterns(RewritePatternSet &patterns) { 78dc4e913bSChris Lattner patterns.add<NumElementsOpConverter>(patterns.getContext()); 797a9258e9SAlexander Belyaev } 807a9258e9SAlexander Belyaev 81250dcf61SAlexander Belyaev std::unique_ptr<Pass> mlir::createShapeToShapeLowering() { 82250dcf61SAlexander Belyaev return std::make_unique<ShapeToShapeLowering>(); 83250dcf61SAlexander Belyaev } 84