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*684dfe8aSAlex Zinenko #include "mlir/Conversion/LLVMCommon/Pattern.h" 13875074c8SKiran Chandramohan #include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h" 14*684dfe8aSAlex Zinenko #include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVMPass.h" 15875074c8SKiran Chandramohan #include "mlir/Dialect/LLVMIR/LLVMDialect.h" 16875074c8SKiran Chandramohan #include "mlir/Dialect/OpenMP/OpenMPDialect.h" 17875074c8SKiran Chandramohan 18875074c8SKiran Chandramohan using namespace mlir; 19875074c8SKiran Chandramohan 20875074c8SKiran Chandramohan namespace { 21f7d033f4SAlex Zinenko /// A pattern that converts the region arguments in a single-region OpenMP 22f7d033f4SAlex Zinenko /// operation to the LLVM dialect. The body of the region is not modified and is 23f7d033f4SAlex Zinenko /// expected to either be processed by the conversion infrastructure or already 24f7d033f4SAlex Zinenko /// contain ops compatible with LLVM dialect types. 25f7d033f4SAlex Zinenko template <typename OpType> 26563879b6SRahul Joshi struct RegionOpConversion : public ConvertOpToLLVMPattern<OpType> { 27563879b6SRahul Joshi using ConvertOpToLLVMPattern<OpType>::ConvertOpToLLVMPattern; 28875074c8SKiran Chandramohan 29875074c8SKiran Chandramohan LogicalResult 30563879b6SRahul Joshi matchAndRewrite(OpType curOp, ArrayRef<Value> operands, 31875074c8SKiran Chandramohan ConversionPatternRewriter &rewriter) const override { 32f7d033f4SAlex Zinenko auto newOp = rewriter.create<OpType>(curOp.getLoc(), TypeRange(), operands, 3356774bddSMarius Brehler curOp->getAttrs()); 34875074c8SKiran Chandramohan rewriter.inlineRegionBefore(curOp.region(), newOp.region(), 35875074c8SKiran Chandramohan newOp.region().end()); 36563879b6SRahul Joshi if (failed(rewriter.convertRegionTypes(&newOp.region(), 37563879b6SRahul Joshi *this->getTypeConverter()))) 38875074c8SKiran Chandramohan return failure(); 39875074c8SKiran Chandramohan 40563879b6SRahul Joshi rewriter.eraseOp(curOp); 41875074c8SKiran Chandramohan return success(); 42875074c8SKiran Chandramohan } 43875074c8SKiran Chandramohan }; 44875074c8SKiran Chandramohan } // namespace 45875074c8SKiran Chandramohan 46dc4e913bSChris Lattner void mlir::populateOpenMPToLLVMConversionPatterns(LLVMTypeConverter &converter, 47dc4e913bSChris Lattner RewritePatternSet &patterns) { 48dc4e913bSChris Lattner patterns.add<RegionOpConversion<omp::ParallelOp>, 49563879b6SRahul Joshi RegionOpConversion<omp::WsLoopOp>>(converter); 50875074c8SKiran Chandramohan } 51875074c8SKiran Chandramohan 52875074c8SKiran Chandramohan namespace { 53875074c8SKiran Chandramohan struct ConvertOpenMPToLLVMPass 54875074c8SKiran Chandramohan : public ConvertOpenMPToLLVMBase<ConvertOpenMPToLLVMPass> { 55875074c8SKiran Chandramohan void runOnOperation() override; 56875074c8SKiran Chandramohan }; 57875074c8SKiran Chandramohan } // namespace 58875074c8SKiran Chandramohan 59875074c8SKiran Chandramohan void ConvertOpenMPToLLVMPass::runOnOperation() { 60875074c8SKiran Chandramohan auto module = getOperation(); 61875074c8SKiran Chandramohan 62875074c8SKiran Chandramohan // Convert to OpenMP operations with LLVM IR dialect 63dc4e913bSChris Lattner RewritePatternSet patterns(&getContext()); 64875074c8SKiran Chandramohan LLVMTypeConverter converter(&getContext()); 65875074c8SKiran Chandramohan populateStdToLLVMConversionPatterns(converter, patterns); 66563879b6SRahul Joshi populateOpenMPToLLVMConversionPatterns(converter, patterns); 67875074c8SKiran Chandramohan 68875074c8SKiran Chandramohan LLVMConversionTarget target(getContext()); 69f7d033f4SAlex Zinenko target.addDynamicallyLegalOp<omp::ParallelOp, omp::WsLoopOp>( 70f7d033f4SAlex Zinenko [&](Operation *op) { return converter.isLegal(&op->getRegion(0)); }); 71875074c8SKiran Chandramohan target.addLegalOp<omp::TerminatorOp, omp::TaskyieldOp, omp::FlushOp, 72875074c8SKiran Chandramohan omp::BarrierOp, omp::TaskwaitOp>(); 733fffffa8SRiver Riddle if (failed(applyPartialConversion(module, target, std::move(patterns)))) 74875074c8SKiran Chandramohan signalPassFailure(); 75875074c8SKiran Chandramohan } 76875074c8SKiran Chandramohan 77875074c8SKiran Chandramohan std::unique_ptr<OperationPass<ModuleOp>> mlir::createConvertOpenMPToLLVMPass() { 78875074c8SKiran Chandramohan return std::make_unique<ConvertOpenMPToLLVMPass>(); 79875074c8SKiran Chandramohan } 80