1875074c8SKiran Chandramohan //===- OpenMPToLLVM.cpp - conversion from OpenMP to LLVM dialect ----------===// 2875074c8SKiran Chandramohan // 3875074c8SKiran Chandramohan // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4875074c8SKiran Chandramohan // See https://llvm.org/LICENSE.txt for license information. 5875074c8SKiran Chandramohan // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6875074c8SKiran Chandramohan // 7875074c8SKiran Chandramohan //===----------------------------------------------------------------------===// 8875074c8SKiran Chandramohan 9875074c8SKiran Chandramohan #include "mlir/Conversion/OpenMPToLLVM/ConvertOpenMPToLLVM.h" 10875074c8SKiran Chandramohan 11875074c8SKiran Chandramohan #include "../PassDetail.h" 12*a54f4eaeSMogball #include "mlir/Conversion/ArithmeticToLLVM/ArithmeticToLLVM.h" 1375e5f0aaSAlex Zinenko #include "mlir/Conversion/LLVMCommon/ConversionTarget.h" 14684dfe8aSAlex Zinenko #include "mlir/Conversion/LLVMCommon/Pattern.h" 1575e5f0aaSAlex Zinenko #include "mlir/Conversion/MemRefToLLVM/MemRefToLLVM.h" 16875074c8SKiran Chandramohan #include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h" 17684dfe8aSAlex Zinenko #include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVMPass.h" 18875074c8SKiran Chandramohan #include "mlir/Dialect/LLVMIR/LLVMDialect.h" 19875074c8SKiran Chandramohan #include "mlir/Dialect/OpenMP/OpenMPDialect.h" 20875074c8SKiran Chandramohan 21875074c8SKiran Chandramohan using namespace mlir; 22875074c8SKiran Chandramohan 23875074c8SKiran Chandramohan namespace { 24f7d033f4SAlex Zinenko /// A pattern that converts the region arguments in a single-region OpenMP 25f7d033f4SAlex Zinenko /// operation to the LLVM dialect. The body of the region is not modified and is 26f7d033f4SAlex Zinenko /// expected to either be processed by the conversion infrastructure or already 27f7d033f4SAlex Zinenko /// contain ops compatible with LLVM dialect types. 28f7d033f4SAlex Zinenko template <typename OpType> 29563879b6SRahul Joshi struct RegionOpConversion : public ConvertOpToLLVMPattern<OpType> { 30563879b6SRahul Joshi using ConvertOpToLLVMPattern<OpType>::ConvertOpToLLVMPattern; 31875074c8SKiran Chandramohan 32875074c8SKiran Chandramohan LogicalResult 33ef976337SRiver Riddle matchAndRewrite(OpType curOp, typename OpType::Adaptor adaptor, 34875074c8SKiran Chandramohan ConversionPatternRewriter &rewriter) const override { 35ef976337SRiver Riddle auto newOp = rewriter.create<OpType>( 36ef976337SRiver Riddle curOp.getLoc(), TypeRange(), adaptor.getOperands(), curOp->getAttrs()); 37875074c8SKiran Chandramohan rewriter.inlineRegionBefore(curOp.region(), newOp.region(), 38875074c8SKiran Chandramohan newOp.region().end()); 39563879b6SRahul Joshi if (failed(rewriter.convertRegionTypes(&newOp.region(), 40563879b6SRahul Joshi *this->getTypeConverter()))) 41875074c8SKiran Chandramohan return failure(); 42875074c8SKiran Chandramohan 43563879b6SRahul Joshi rewriter.eraseOp(curOp); 44875074c8SKiran Chandramohan return success(); 45875074c8SKiran Chandramohan } 46875074c8SKiran Chandramohan }; 47875074c8SKiran Chandramohan } // namespace 48875074c8SKiran Chandramohan 49dc4e913bSChris Lattner void mlir::populateOpenMPToLLVMConversionPatterns(LLVMTypeConverter &converter, 50dc4e913bSChris Lattner RewritePatternSet &patterns) { 51187d9f8cSKiran Chandramohan patterns.add<RegionOpConversion<omp::MasterOp>, 52187d9f8cSKiran Chandramohan RegionOpConversion<omp::ParallelOp>, 53563879b6SRahul Joshi RegionOpConversion<omp::WsLoopOp>>(converter); 54875074c8SKiran Chandramohan } 55875074c8SKiran Chandramohan 56875074c8SKiran Chandramohan namespace { 57875074c8SKiran Chandramohan struct ConvertOpenMPToLLVMPass 58875074c8SKiran Chandramohan : public ConvertOpenMPToLLVMBase<ConvertOpenMPToLLVMPass> { 59875074c8SKiran Chandramohan void runOnOperation() override; 60875074c8SKiran Chandramohan }; 61875074c8SKiran Chandramohan } // namespace 62875074c8SKiran Chandramohan 63875074c8SKiran Chandramohan void ConvertOpenMPToLLVMPass::runOnOperation() { 64875074c8SKiran Chandramohan auto module = getOperation(); 65875074c8SKiran Chandramohan 66875074c8SKiran Chandramohan // Convert to OpenMP operations with LLVM IR dialect 67dc4e913bSChris Lattner RewritePatternSet patterns(&getContext()); 68875074c8SKiran Chandramohan LLVMTypeConverter converter(&getContext()); 69*a54f4eaeSMogball mlir::arith::populateArithmeticToLLVMConversionPatterns(converter, patterns); 7075e5f0aaSAlex Zinenko populateMemRefToLLVMConversionPatterns(converter, patterns); 71875074c8SKiran Chandramohan populateStdToLLVMConversionPatterns(converter, patterns); 72563879b6SRahul Joshi populateOpenMPToLLVMConversionPatterns(converter, patterns); 73875074c8SKiran Chandramohan 74875074c8SKiran Chandramohan LLVMConversionTarget target(getContext()); 75187d9f8cSKiran Chandramohan target.addDynamicallyLegalOp<omp::MasterOp, omp::ParallelOp, omp::WsLoopOp>( 76f7d033f4SAlex Zinenko [&](Operation *op) { return converter.isLegal(&op->getRegion(0)); }); 77875074c8SKiran Chandramohan target.addLegalOp<omp::TerminatorOp, omp::TaskyieldOp, omp::FlushOp, 78875074c8SKiran Chandramohan omp::BarrierOp, omp::TaskwaitOp>(); 793fffffa8SRiver Riddle if (failed(applyPartialConversion(module, target, std::move(patterns)))) 80875074c8SKiran Chandramohan signalPassFailure(); 81875074c8SKiran Chandramohan } 82875074c8SKiran Chandramohan 83875074c8SKiran Chandramohan std::unique_ptr<OperationPass<ModuleOp>> mlir::createConvertOpenMPToLLVMPass() { 84875074c8SKiran Chandramohan return std::make_unique<ConvertOpenMPToLLVMPass>(); 85875074c8SKiran Chandramohan } 86