1fb5b590bSValentin Clement //===- OpenACCToSCF.cpp - OpenACC condition to SCF if conversion ----------===// 2fb5b590bSValentin Clement // 3fb5b590bSValentin Clement // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4fb5b590bSValentin Clement // See https://llvm.org/LICENSE.txt for license information. 5fb5b590bSValentin Clement // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6fb5b590bSValentin Clement // 7fb5b590bSValentin Clement //===----------------------------------------------------------------------===// 8fb5b590bSValentin Clement 9fb5b590bSValentin Clement #include "../PassDetail.h" 10fb5b590bSValentin Clement #include "mlir/Conversion/OpenACCToSCF/ConvertOpenACCToSCF.h" 11a54f4eaeSMogball #include "mlir/Dialect/Arithmetic/IR/Arithmetic.h" 12fb5b590bSValentin Clement #include "mlir/Dialect/OpenACC/OpenACC.h" 13*8b68da2cSAlex Zinenko #include "mlir/Dialect/SCF/IR/SCF.h" 14fb5b590bSValentin Clement #include "mlir/Transforms/DialectConversion.h" 15fb5b590bSValentin Clement 16fb5b590bSValentin Clement using namespace mlir; 17fb5b590bSValentin Clement 18fb5b590bSValentin Clement //===----------------------------------------------------------------------===// 19fb5b590bSValentin Clement // Conversion patterns 20fb5b590bSValentin Clement //===----------------------------------------------------------------------===// 21fb5b590bSValentin Clement 22fb5b590bSValentin Clement namespace { 23fb5b590bSValentin Clement /// Pattern to transform the `ifCond` on operation without region into a scf.if 24fb5b590bSValentin Clement /// and move the operation into the `then` region. 25fb5b590bSValentin Clement template <typename OpTy> 26fb5b590bSValentin Clement class ExpandIfCondition : public OpRewritePattern<OpTy> { 27fb5b590bSValentin Clement using OpRewritePattern<OpTy>::OpRewritePattern; 28fb5b590bSValentin Clement matchAndRewrite(OpTy op,PatternRewriter & rewriter) const29fb5b590bSValentin Clement LogicalResult matchAndRewrite(OpTy op, 30fb5b590bSValentin Clement PatternRewriter &rewriter) const override { 31fb5b590bSValentin Clement // Early exit if there is no condition. 32fb5b590bSValentin Clement if (!op.ifCond()) 33fb5b590bSValentin Clement return success(); 34fb5b590bSValentin Clement 35fb5b590bSValentin Clement // Condition is not a constant. 36a54f4eaeSMogball if (!op.ifCond().template getDefiningOp<arith::ConstantOp>()) { 37fb5b590bSValentin Clement auto ifOp = rewriter.create<scf::IfOp>(op.getLoc(), TypeRange(), 38fb5b590bSValentin Clement op.ifCond(), false); 39fb5b590bSValentin Clement rewriter.updateRootInPlace(op, [&]() { op.ifCondMutable().erase(0); }); 40fb5b590bSValentin Clement auto thenBodyBuilder = ifOp.getThenBodyBuilder(); 41fb5b590bSValentin Clement thenBodyBuilder.setListener(rewriter.getListener()); 42fb5b590bSValentin Clement thenBodyBuilder.clone(*op.getOperation()); 43fb5b590bSValentin Clement rewriter.eraseOp(op); 44fb5b590bSValentin Clement } 45fb5b590bSValentin Clement 46fb5b590bSValentin Clement return success(); 47fb5b590bSValentin Clement } 48fb5b590bSValentin Clement }; 49fb5b590bSValentin Clement } // namespace 50fb5b590bSValentin Clement populateOpenACCToSCFConversionPatterns(RewritePatternSet & patterns)51fb5b590bSValentin Clementvoid mlir::populateOpenACCToSCFConversionPatterns(RewritePatternSet &patterns) { 52fb5b590bSValentin Clement patterns.add<ExpandIfCondition<acc::EnterDataOp>>(patterns.getContext()); 53fb5b590bSValentin Clement patterns.add<ExpandIfCondition<acc::ExitDataOp>>(patterns.getContext()); 54fb5b590bSValentin Clement patterns.add<ExpandIfCondition<acc::UpdateOp>>(patterns.getContext()); 55fb5b590bSValentin Clement } 56fb5b590bSValentin Clement 57fb5b590bSValentin Clement namespace { 58fb5b590bSValentin Clement struct ConvertOpenACCToSCFPass 59fb5b590bSValentin Clement : public ConvertOpenACCToSCFBase<ConvertOpenACCToSCFPass> { 60fb5b590bSValentin Clement void runOnOperation() override; 61fb5b590bSValentin Clement }; 62fb5b590bSValentin Clement } // namespace 63fb5b590bSValentin Clement runOnOperation()64fb5b590bSValentin Clementvoid ConvertOpenACCToSCFPass::runOnOperation() { 65fb5b590bSValentin Clement auto op = getOperation(); 66fb5b590bSValentin Clement auto *context = op.getContext(); 67fb5b590bSValentin Clement 68fb5b590bSValentin Clement RewritePatternSet patterns(context); 69fb5b590bSValentin Clement ConversionTarget target(*context); 70fb5b590bSValentin Clement populateOpenACCToSCFConversionPatterns(patterns); 71fb5b590bSValentin Clement 72fb5b590bSValentin Clement target.addLegalDialect<scf::SCFDialect>(); 73fb5b590bSValentin Clement target.addLegalDialect<acc::OpenACCDialect>(); 74fb5b590bSValentin Clement 75fb5b590bSValentin Clement target.addDynamicallyLegalOp<acc::EnterDataOp>( 76fb5b590bSValentin Clement [](acc::EnterDataOp op) { return !op.ifCond(); }); 77fb5b590bSValentin Clement 78fb5b590bSValentin Clement target.addDynamicallyLegalOp<acc::ExitDataOp>( 79fb5b590bSValentin Clement [](acc::ExitDataOp op) { return !op.ifCond(); }); 80fb5b590bSValentin Clement 81fb5b590bSValentin Clement target.addDynamicallyLegalOp<acc::UpdateOp>( 82fb5b590bSValentin Clement [](acc::UpdateOp op) { return !op.ifCond(); }); 83fb5b590bSValentin Clement 84fb5b590bSValentin Clement if (failed(applyPartialConversion(op, target, std::move(patterns)))) 85fb5b590bSValentin Clement signalPassFailure(); 86fb5b590bSValentin Clement } 87fb5b590bSValentin Clement createConvertOpenACCToSCFPass()88fb5b590bSValentin Clementstd::unique_ptr<OperationPass<ModuleOp>> mlir::createConvertOpenACCToSCFPass() { 89fb5b590bSValentin Clement return std::make_unique<ConvertOpenACCToSCFPass>(); 90fb5b590bSValentin Clement } 91