//===- 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 namespace { class OptimizeArrayRepackingPass : public fir::impl::OptimizeArrayRepackingBase { public: void runOnOperation() override; }; /// Relinks all uses of redundant fir.pack_array to the source. class PackingOfContiguous : public mlir::OpRewritePattern { 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 { 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.replaceAllUsesWith(op, box); rewriter.eraseOp(op); 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); patterns.insert(context); patterns.insert(context); if (mlir::failed( mlir::applyPatternsGreedily(funcOp, std::move(patterns), config))) { mlir::emitError(funcOp.getLoc(), "failure in array repacking optimization"); signalPassFailure(); } }