| //===- OptimizeArrayRepacking.cpp -----------------------------------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| //===----------------------------------------------------------------------===// | |
| /// \file | |
| /// This pass removes redundant fir.pack_array operations, if it can prove | |
| /// that the source array is contiguous. In this case, it relink all uses | |
| /// of fir.pack_array result to the source. If such a rewrite happens, | |
| /// it may turn the using fir.unpack_array operation into one with the same | |
| /// temp and original operands - these are also removed as redundant. | |
| //===----------------------------------------------------------------------===// | |
| #include "flang/Optimizer/Builder/HLFIRTools.h" | |
| #include "flang/Optimizer/Dialect/FIRDialect.h" | |
| #include "flang/Optimizer/Dialect/FIROps.h" | |
| #include "flang/Optimizer/Support/Utils.h" | |
| #include "flang/Optimizer/Transforms/Passes.h" | |
| #include "mlir/Transforms/GreedyPatternRewriteDriver.h" | |
| namespace fir { | |
| #define GEN_PASS_DEF_OPTIMIZEARRAYREPACKING | |
| #include "flang/Optimizer/Transforms/Passes.h.inc" | |
| } // namespace fir | |
| #define DEBUG_TYPE "optimize-array-repacking" | |
| namespace { | |
| class OptimizeArrayRepackingPass | |
| : public fir::impl::OptimizeArrayRepackingBase<OptimizeArrayRepackingPass> { | |
| public: | |
| void runOnOperation() override; | |
| }; | |
| /// Relinks all uses of redundant fir.pack_array to the source. | |
| class PackingOfContiguous : public mlir::OpRewritePattern<fir::PackArrayOp> { | |
| public: | |
| using OpRewritePattern::OpRewritePattern; | |
| mlir::LogicalResult matchAndRewrite(fir::PackArrayOp, | |
| mlir::PatternRewriter &) const override; | |
| }; | |
| /// Erases fir.unpack_array with have the matching temp and original | |
| /// operands. | |
| class NoopUnpacking : public mlir::OpRewritePattern<fir::UnpackArrayOp> { | |
| public: | |
| using OpRewritePattern::OpRewritePattern; | |
| mlir::LogicalResult matchAndRewrite(fir::UnpackArrayOp, | |
| mlir::PatternRewriter &) const override; | |
| }; | |
| } // namespace | |
| mlir::LogicalResult | |
| PackingOfContiguous::matchAndRewrite(fir::PackArrayOp op, | |
| mlir::PatternRewriter &rewriter) const { | |
| mlir::Value box = op.getArray(); | |
| if (hlfir::isSimplyContiguous(box, !op.getInnermost())) { | |
| rewriter.replaceOp(op, box); | |
| return mlir::success(); | |
| } | |
| return mlir::failure(); | |
| } | |
| mlir::LogicalResult | |
| NoopUnpacking::matchAndRewrite(fir::UnpackArrayOp op, | |
| mlir::PatternRewriter &rewriter) const { | |
| if (op.getTemp() == op.getOriginal()) { | |
| rewriter.eraseOp(op); | |
| return mlir::success(); | |
| } | |
| return mlir::failure(); | |
| } | |
| void OptimizeArrayRepackingPass::runOnOperation() { | |
| mlir::func::FuncOp funcOp = getOperation(); | |
| mlir::MLIRContext *context = &getContext(); | |
| mlir::RewritePatternSet patterns(context); | |
| mlir::GreedyRewriteConfig config; | |
| config | |
| .setRegionSimplificationLevel(mlir::GreedySimplifyRegionLevel::Disabled) | |
| // Traverse the operations top-down, so that fir.pack_array | |
| // operations are optimized before their using fir.pack_array | |
| // operations. This way the rewrite may converge faster. | |
| .setUseTopDownTraversal(); | |
| patterns.insert<PackingOfContiguous>(context); | |
| patterns.insert<NoopUnpacking>(context); | |
| if (mlir::failed( | |
| mlir::applyPatternsGreedily(funcOp, std::move(patterns), config))) { | |
| // Failure may happen if the rewriter does not converge soon enough. | |
| // That is not an error, so just report a diagnostic under debug. | |
| LLVM_DEBUG(mlir::emitError(funcOp.getLoc(), | |
| "failure in array repacking optimization")); | |
| } | |
| } |