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