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" 1275e5f0aaSAlex Zinenko #include "mlir/Conversion/LLVMCommon/ConversionTarget.h" 13684dfe8aSAlex Zinenko #include "mlir/Conversion/LLVMCommon/Pattern.h" 1475e5f0aaSAlex Zinenko #include "mlir/Conversion/MemRefToLLVM/MemRefToLLVM.h" 15875074c8SKiran Chandramohan #include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h" 16684dfe8aSAlex Zinenko #include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVMPass.h" 17875074c8SKiran Chandramohan #include "mlir/Dialect/LLVMIR/LLVMDialect.h" 18875074c8SKiran Chandramohan #include "mlir/Dialect/OpenMP/OpenMPDialect.h" 19875074c8SKiran Chandramohan 20875074c8SKiran Chandramohan using namespace mlir; 21875074c8SKiran Chandramohan 22875074c8SKiran Chandramohan namespace { 23f7d033f4SAlex Zinenko /// A pattern that converts the region arguments in a single-region OpenMP 24f7d033f4SAlex Zinenko /// operation to the LLVM dialect. The body of the region is not modified and is 25f7d033f4SAlex Zinenko /// expected to either be processed by the conversion infrastructure or already 26f7d033f4SAlex Zinenko /// contain ops compatible with LLVM dialect types. 27f7d033f4SAlex Zinenko template <typename OpType> 28563879b6SRahul Joshi struct RegionOpConversion : public ConvertOpToLLVMPattern<OpType> { 29563879b6SRahul Joshi using ConvertOpToLLVMPattern<OpType>::ConvertOpToLLVMPattern; 30875074c8SKiran Chandramohan 31875074c8SKiran Chandramohan LogicalResult 32563879b6SRahul Joshi matchAndRewrite(OpType curOp, ArrayRef<Value> operands, 33875074c8SKiran Chandramohan ConversionPatternRewriter &rewriter) const override { 34f7d033f4SAlex Zinenko auto newOp = rewriter.create<OpType>(curOp.getLoc(), TypeRange(), operands, 3556774bddSMarius Brehler curOp->getAttrs()); 36875074c8SKiran Chandramohan rewriter.inlineRegionBefore(curOp.region(), newOp.region(), 37875074c8SKiran Chandramohan newOp.region().end()); 38563879b6SRahul Joshi if (failed(rewriter.convertRegionTypes(&newOp.region(), 39563879b6SRahul Joshi *this->getTypeConverter()))) 40875074c8SKiran Chandramohan return failure(); 41875074c8SKiran Chandramohan 42563879b6SRahul Joshi rewriter.eraseOp(curOp); 43875074c8SKiran Chandramohan return success(); 44875074c8SKiran Chandramohan } 45875074c8SKiran Chandramohan }; 46875074c8SKiran Chandramohan } // namespace 47875074c8SKiran Chandramohan 48dc4e913bSChris Lattner void mlir::populateOpenMPToLLVMConversionPatterns(LLVMTypeConverter &converter, 49dc4e913bSChris Lattner RewritePatternSet &patterns) { 50*187d9f8cSKiran Chandramohan patterns.add<RegionOpConversion<omp::MasterOp>, 51*187d9f8cSKiran Chandramohan RegionOpConversion<omp::ParallelOp>, 52563879b6SRahul Joshi RegionOpConversion<omp::WsLoopOp>>(converter); 53875074c8SKiran Chandramohan } 54875074c8SKiran Chandramohan 55875074c8SKiran Chandramohan namespace { 56875074c8SKiran Chandramohan struct ConvertOpenMPToLLVMPass 57875074c8SKiran Chandramohan : public ConvertOpenMPToLLVMBase<ConvertOpenMPToLLVMPass> { 58875074c8SKiran Chandramohan void runOnOperation() override; 59875074c8SKiran Chandramohan }; 60875074c8SKiran Chandramohan } // namespace 61875074c8SKiran Chandramohan 62875074c8SKiran Chandramohan void ConvertOpenMPToLLVMPass::runOnOperation() { 63875074c8SKiran Chandramohan auto module = getOperation(); 64875074c8SKiran Chandramohan 65875074c8SKiran Chandramohan // Convert to OpenMP operations with LLVM IR dialect 66dc4e913bSChris Lattner RewritePatternSet patterns(&getContext()); 67875074c8SKiran Chandramohan LLVMTypeConverter converter(&getContext()); 6875e5f0aaSAlex Zinenko populateMemRefToLLVMConversionPatterns(converter, patterns); 69875074c8SKiran Chandramohan populateStdToLLVMConversionPatterns(converter, patterns); 70563879b6SRahul Joshi populateOpenMPToLLVMConversionPatterns(converter, patterns); 71875074c8SKiran Chandramohan 72875074c8SKiran Chandramohan LLVMConversionTarget target(getContext()); 73*187d9f8cSKiran Chandramohan target.addDynamicallyLegalOp<omp::MasterOp, omp::ParallelOp, omp::WsLoopOp>( 74f7d033f4SAlex Zinenko [&](Operation *op) { return converter.isLegal(&op->getRegion(0)); }); 75875074c8SKiran Chandramohan target.addLegalOp<omp::TerminatorOp, omp::TaskyieldOp, omp::FlushOp, 76875074c8SKiran Chandramohan omp::BarrierOp, omp::TaskwaitOp>(); 773fffffa8SRiver Riddle if (failed(applyPartialConversion(module, target, std::move(patterns)))) 78875074c8SKiran Chandramohan signalPassFailure(); 79875074c8SKiran Chandramohan } 80875074c8SKiran Chandramohan 81875074c8SKiran Chandramohan std::unique_ptr<OperationPass<ModuleOp>> mlir::createConvertOpenMPToLLVMPass() { 82875074c8SKiran Chandramohan return std::make_unique<ConvertOpenMPToLLVMPass>(); 83875074c8SKiran Chandramohan } 84