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" 12875074c8SKiran Chandramohan #include "mlir/Conversion/StandardToLLVM/ConvertStandardToLLVM.h" 13875074c8SKiran Chandramohan #include "mlir/Dialect/LLVMIR/LLVMDialect.h" 14875074c8SKiran Chandramohan #include "mlir/Dialect/OpenMP/OpenMPDialect.h" 15875074c8SKiran Chandramohan 16875074c8SKiran Chandramohan using namespace mlir; 17875074c8SKiran Chandramohan 18875074c8SKiran Chandramohan namespace { 19f7d033f4SAlex Zinenko /// A pattern that converts the region arguments in a single-region OpenMP 20f7d033f4SAlex Zinenko /// operation to the LLVM dialect. The body of the region is not modified and is 21f7d033f4SAlex Zinenko /// expected to either be processed by the conversion infrastructure or already 22f7d033f4SAlex Zinenko /// contain ops compatible with LLVM dialect types. 23f7d033f4SAlex Zinenko template <typename OpType> 24563879b6SRahul Joshi struct RegionOpConversion : public ConvertOpToLLVMPattern<OpType> { 25563879b6SRahul Joshi using ConvertOpToLLVMPattern<OpType>::ConvertOpToLLVMPattern; 26875074c8SKiran Chandramohan 27875074c8SKiran Chandramohan LogicalResult 28563879b6SRahul Joshi matchAndRewrite(OpType curOp, ArrayRef<Value> operands, 29875074c8SKiran Chandramohan ConversionPatternRewriter &rewriter) const override { 30f7d033f4SAlex Zinenko auto newOp = rewriter.create<OpType>(curOp.getLoc(), TypeRange(), operands, 31*56774bddSMarius Brehler curOp->getAttrs()); 32875074c8SKiran Chandramohan rewriter.inlineRegionBefore(curOp.region(), newOp.region(), 33875074c8SKiran Chandramohan newOp.region().end()); 34563879b6SRahul Joshi if (failed(rewriter.convertRegionTypes(&newOp.region(), 35563879b6SRahul Joshi *this->getTypeConverter()))) 36875074c8SKiran Chandramohan return failure(); 37875074c8SKiran Chandramohan 38563879b6SRahul Joshi rewriter.eraseOp(curOp); 39875074c8SKiran Chandramohan return success(); 40875074c8SKiran Chandramohan } 41875074c8SKiran Chandramohan }; 42875074c8SKiran Chandramohan } // namespace 43875074c8SKiran Chandramohan 44875074c8SKiran Chandramohan void mlir::populateOpenMPToLLVMConversionPatterns( 45563879b6SRahul Joshi LLVMTypeConverter &converter, OwningRewritePatternList &patterns) { 46f7d033f4SAlex Zinenko patterns.insert<RegionOpConversion<omp::ParallelOp>, 47563879b6SRahul Joshi RegionOpConversion<omp::WsLoopOp>>(converter); 48875074c8SKiran Chandramohan } 49875074c8SKiran Chandramohan 50875074c8SKiran Chandramohan namespace { 51875074c8SKiran Chandramohan struct ConvertOpenMPToLLVMPass 52875074c8SKiran Chandramohan : public ConvertOpenMPToLLVMBase<ConvertOpenMPToLLVMPass> { 53875074c8SKiran Chandramohan void runOnOperation() override; 54875074c8SKiran Chandramohan }; 55875074c8SKiran Chandramohan } // namespace 56875074c8SKiran Chandramohan 57875074c8SKiran Chandramohan void ConvertOpenMPToLLVMPass::runOnOperation() { 58875074c8SKiran Chandramohan auto module = getOperation(); 59875074c8SKiran Chandramohan 60875074c8SKiran Chandramohan // Convert to OpenMP operations with LLVM IR dialect 61875074c8SKiran Chandramohan OwningRewritePatternList patterns; 62875074c8SKiran Chandramohan LLVMTypeConverter converter(&getContext()); 63875074c8SKiran Chandramohan populateStdToLLVMConversionPatterns(converter, patterns); 64563879b6SRahul Joshi populateOpenMPToLLVMConversionPatterns(converter, patterns); 65875074c8SKiran Chandramohan 66875074c8SKiran Chandramohan LLVMConversionTarget target(getContext()); 67f7d033f4SAlex Zinenko target.addDynamicallyLegalOp<omp::ParallelOp, omp::WsLoopOp>( 68f7d033f4SAlex Zinenko [&](Operation *op) { return converter.isLegal(&op->getRegion(0)); }); 69875074c8SKiran Chandramohan target.addLegalOp<omp::TerminatorOp, omp::TaskyieldOp, omp::FlushOp, 70875074c8SKiran Chandramohan omp::BarrierOp, omp::TaskwaitOp>(); 713fffffa8SRiver Riddle if (failed(applyPartialConversion(module, target, std::move(patterns)))) 72875074c8SKiran Chandramohan signalPassFailure(); 73875074c8SKiran Chandramohan } 74875074c8SKiran Chandramohan 75875074c8SKiran Chandramohan std::unique_ptr<OperationPass<ModuleOp>> mlir::createConvertOpenMPToLLVMPass() { 76875074c8SKiran Chandramohan return std::make_unique<ConvertOpenMPToLLVMPass>(); 77875074c8SKiran Chandramohan } 78