xref: /llvm-project/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp (revision 599c73990532333e62edf8ba19a5302b543f976f)
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 
11abc362a1SJakub Kuderski #include "mlir/Conversion/ArithToLLVM/ArithToLLVM.h"
12ace01605SRiver Riddle #include "mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h"
1358d97034SFabian Mora #include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h"
145a7b9194SRiver Riddle #include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h"
155a7b9194SRiver Riddle #include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVMPass.h"
1675e5f0aaSAlex Zinenko #include "mlir/Conversion/LLVMCommon/ConversionTarget.h"
17684dfe8aSAlex Zinenko #include "mlir/Conversion/LLVMCommon/Pattern.h"
1875e5f0aaSAlex Zinenko #include "mlir/Conversion/MemRefToLLVM/MemRefToLLVM.h"
19875074c8SKiran Chandramohan #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
20875074c8SKiran Chandramohan #include "mlir/Dialect/OpenMP/OpenMPDialect.h"
2167d0d7acSMichele Scuttari #include "mlir/Pass/Pass.h"
2267d0d7acSMichele Scuttari 
2367d0d7acSMichele Scuttari namespace mlir {
24cd4ca2d7SMarkus Böck #define GEN_PASS_DEF_CONVERTOPENMPTOLLVMPASS
2567d0d7acSMichele Scuttari #include "mlir/Conversion/Passes.h.inc"
2667d0d7acSMichele Scuttari } // namespace mlir
27875074c8SKiran Chandramohan 
28875074c8SKiran Chandramohan using namespace mlir;
29875074c8SKiran Chandramohan 
30875074c8SKiran Chandramohan namespace {
31f7d033f4SAlex Zinenko /// A pattern that converts the region arguments in a single-region OpenMP
32f7d033f4SAlex Zinenko /// operation to the LLVM dialect. The body of the region is not modified and is
33f7d033f4SAlex Zinenko /// expected to either be processed by the conversion infrastructure or already
34f7d033f4SAlex Zinenko /// contain ops compatible with LLVM dialect types.
35f7d033f4SAlex Zinenko template <typename OpType>
36563879b6SRahul Joshi struct RegionOpConversion : public ConvertOpToLLVMPattern<OpType> {
37563879b6SRahul Joshi   using ConvertOpToLLVMPattern<OpType>::ConvertOpToLLVMPattern;
38875074c8SKiran Chandramohan 
39875074c8SKiran Chandramohan   LogicalResult
40ef976337SRiver Riddle   matchAndRewrite(OpType curOp, typename OpType::Adaptor adaptor,
41875074c8SKiran Chandramohan                   ConversionPatternRewriter &rewriter) const override {
42ef976337SRiver Riddle     auto newOp = rewriter.create<OpType>(
43ef976337SRiver Riddle         curOp.getLoc(), TypeRange(), adaptor.getOperands(), curOp->getAttrs());
444fb4e12bSRiver Riddle     rewriter.inlineRegionBefore(curOp.getRegion(), newOp.getRegion(),
454fb4e12bSRiver Riddle                                 newOp.getRegion().end());
464fb4e12bSRiver Riddle     if (failed(rewriter.convertRegionTypes(&newOp.getRegion(),
47563879b6SRahul Joshi                                            *this->getTypeConverter())))
48875074c8SKiran Chandramohan       return failure();
49875074c8SKiran Chandramohan 
50563879b6SRahul Joshi     rewriter.eraseOp(curOp);
51875074c8SKiran Chandramohan     return success();
52875074c8SKiran Chandramohan   }
53875074c8SKiran Chandramohan };
5400c511b3SNimish Mishra 
5500c511b3SNimish Mishra template <typename T>
56dd32bf9aSKiran Chandramohan struct RegionLessOpWithVarOperandsConversion
57dd32bf9aSKiran Chandramohan     : public ConvertOpToLLVMPattern<T> {
5800c511b3SNimish Mishra   using ConvertOpToLLVMPattern<T>::ConvertOpToLLVMPattern;
5900c511b3SNimish Mishra   LogicalResult
6000c511b3SNimish Mishra   matchAndRewrite(T curOp, typename T::Adaptor adaptor,
6100c511b3SNimish Mishra                   ConversionPatternRewriter &rewriter) const override {
62ce254598SMatthias Springer     const TypeConverter *converter = ConvertToLLVMPattern::getTypeConverter();
63042ae895SPeixinQiao     SmallVector<Type> resTypes;
64042ae895SPeixinQiao     if (failed(converter->convertTypes(curOp->getResultTypes(), resTypes)))
65042ae895SPeixinQiao       return failure();
66042ae895SPeixinQiao     SmallVector<Value> convertedOperands;
67dd32bf9aSKiran Chandramohan     assert(curOp.getNumVariableOperands() ==
68dd32bf9aSKiran Chandramohan                curOp.getOperation()->getNumOperands() &&
69dd32bf9aSKiran Chandramohan            "unexpected non-variable operands");
70042ae895SPeixinQiao     for (unsigned idx = 0; idx < curOp.getNumVariableOperands(); ++idx) {
71042ae895SPeixinQiao       Value originalVariableOperand = curOp.getVariableOperand(idx);
72042ae895SPeixinQiao       if (!originalVariableOperand)
73042ae895SPeixinQiao         return failure();
745550c821STres Popp       if (isa<MemRefType>(originalVariableOperand.getType())) {
75042ae895SPeixinQiao         // TODO: Support memref type in variable operands
76a5d7e2a8SAart Bik         return rewriter.notifyMatchFailure(curOp,
77a5d7e2a8SAart Bik                                            "memref is not supported yet");
78042ae895SPeixinQiao       }
79118d9ebdSMehdi Amini       convertedOperands.emplace_back(adaptor.getOperands()[idx]);
80042ae895SPeixinQiao     }
81067ecad6SKiran Chandramohan 
82042ae895SPeixinQiao     rewriter.replaceOpWithNewOp<T>(curOp, resTypes, convertedOperands,
8300c511b3SNimish Mishra                                    curOp->getAttrs());
8400c511b3SNimish Mishra     return success();
8500c511b3SNimish Mishra   }
8600c511b3SNimish Mishra };
877bb1151bSKiran Chandramohan 
8822cdeb54SKiran Chandramohan template <typename T>
8922cdeb54SKiran Chandramohan struct RegionOpWithVarOperandsConversion : public ConvertOpToLLVMPattern<T> {
9022cdeb54SKiran Chandramohan   using ConvertOpToLLVMPattern<T>::ConvertOpToLLVMPattern;
9122cdeb54SKiran Chandramohan   LogicalResult
9222cdeb54SKiran Chandramohan   matchAndRewrite(T curOp, typename T::Adaptor adaptor,
9322cdeb54SKiran Chandramohan                   ConversionPatternRewriter &rewriter) const override {
94ce254598SMatthias Springer     const TypeConverter *converter = ConvertToLLVMPattern::getTypeConverter();
9522cdeb54SKiran Chandramohan     SmallVector<Type> resTypes;
9622cdeb54SKiran Chandramohan     if (failed(converter->convertTypes(curOp->getResultTypes(), resTypes)))
9722cdeb54SKiran Chandramohan       return failure();
9822cdeb54SKiran Chandramohan     SmallVector<Value> convertedOperands;
9922cdeb54SKiran Chandramohan     assert(curOp.getNumVariableOperands() ==
10022cdeb54SKiran Chandramohan                curOp.getOperation()->getNumOperands() &&
10122cdeb54SKiran Chandramohan            "unexpected non-variable operands");
10222cdeb54SKiran Chandramohan     for (unsigned idx = 0; idx < curOp.getNumVariableOperands(); ++idx) {
10322cdeb54SKiran Chandramohan       Value originalVariableOperand = curOp.getVariableOperand(idx);
10422cdeb54SKiran Chandramohan       if (!originalVariableOperand)
10522cdeb54SKiran Chandramohan         return failure();
1065550c821STres Popp       if (isa<MemRefType>(originalVariableOperand.getType())) {
10722cdeb54SKiran Chandramohan         // TODO: Support memref type in variable operands
10822cdeb54SKiran Chandramohan         return rewriter.notifyMatchFailure(curOp,
10922cdeb54SKiran Chandramohan                                            "memref is not supported yet");
11022cdeb54SKiran Chandramohan       }
11122cdeb54SKiran Chandramohan       convertedOperands.emplace_back(adaptor.getOperands()[idx]);
11222cdeb54SKiran Chandramohan     }
11322cdeb54SKiran Chandramohan     auto newOp = rewriter.create<T>(curOp.getLoc(), resTypes, convertedOperands,
11422cdeb54SKiran Chandramohan                                     curOp->getAttrs());
11522cdeb54SKiran Chandramohan     rewriter.inlineRegionBefore(curOp.getRegion(), newOp.getRegion(),
11622cdeb54SKiran Chandramohan                                 newOp.getRegion().end());
11722cdeb54SKiran Chandramohan     if (failed(rewriter.convertRegionTypes(&newOp.getRegion(),
11822cdeb54SKiran Chandramohan                                            *this->getTypeConverter())))
11922cdeb54SKiran Chandramohan       return failure();
12022cdeb54SKiran Chandramohan 
12122cdeb54SKiran Chandramohan     rewriter.eraseOp(curOp);
12222cdeb54SKiran Chandramohan     return success();
12322cdeb54SKiran Chandramohan   }
12422cdeb54SKiran Chandramohan };
12522cdeb54SKiran Chandramohan 
12656164c3eSDylan Fleming template <typename T>
12756164c3eSDylan Fleming struct RegionLessOpConversion : public ConvertOpToLLVMPattern<T> {
12856164c3eSDylan Fleming   using ConvertOpToLLVMPattern<T>::ConvertOpToLLVMPattern;
12956164c3eSDylan Fleming   LogicalResult
13056164c3eSDylan Fleming   matchAndRewrite(T curOp, typename T::Adaptor adaptor,
13156164c3eSDylan Fleming                   ConversionPatternRewriter &rewriter) const override {
132ce254598SMatthias Springer     const TypeConverter *converter = ConvertToLLVMPattern::getTypeConverter();
13356164c3eSDylan Fleming     SmallVector<Type> resTypes;
13456164c3eSDylan Fleming     if (failed(converter->convertTypes(curOp->getResultTypes(), resTypes)))
13556164c3eSDylan Fleming       return failure();
13656164c3eSDylan Fleming 
13756164c3eSDylan Fleming     rewriter.replaceOpWithNewOp<T>(curOp, resTypes, adaptor.getOperands(),
13856164c3eSDylan Fleming                                    curOp->getAttrs());
13956164c3eSDylan Fleming     return success();
14056164c3eSDylan Fleming   }
14156164c3eSDylan Fleming };
14256164c3eSDylan Fleming 
143067ecad6SKiran Chandramohan struct AtomicReadOpConversion
144067ecad6SKiran Chandramohan     : public ConvertOpToLLVMPattern<omp::AtomicReadOp> {
145067ecad6SKiran Chandramohan   using ConvertOpToLLVMPattern<omp::AtomicReadOp>::ConvertOpToLLVMPattern;
146067ecad6SKiran Chandramohan   LogicalResult
147067ecad6SKiran Chandramohan   matchAndRewrite(omp::AtomicReadOp curOp, OpAdaptor adaptor,
148067ecad6SKiran Chandramohan                   ConversionPatternRewriter &rewriter) const override {
149ce254598SMatthias Springer     const TypeConverter *converter = ConvertToLLVMPattern::getTypeConverter();
150067ecad6SKiran Chandramohan     Type curElementType = curOp.getElementType();
151067ecad6SKiran Chandramohan     auto newOp = rewriter.create<omp::AtomicReadOp>(
152067ecad6SKiran Chandramohan         curOp.getLoc(), TypeRange(), adaptor.getOperands(), curOp->getAttrs());
153067ecad6SKiran Chandramohan     TypeAttr typeAttr = TypeAttr::get(converter->convertType(curElementType));
154067ecad6SKiran Chandramohan     newOp.setElementTypeAttr(typeAttr);
155067ecad6SKiran Chandramohan     rewriter.eraseOp(curOp);
156067ecad6SKiran Chandramohan     return success();
157067ecad6SKiran Chandramohan   }
158067ecad6SKiran Chandramohan };
159067ecad6SKiran Chandramohan 
1600235cd73SKiran Chandramohan struct MapInfoOpConversion : public ConvertOpToLLVMPattern<omp::MapInfoOp> {
1610235cd73SKiran Chandramohan   using ConvertOpToLLVMPattern<omp::MapInfoOp>::ConvertOpToLLVMPattern;
1620235cd73SKiran Chandramohan   LogicalResult
1630235cd73SKiran Chandramohan   matchAndRewrite(omp::MapInfoOp curOp, OpAdaptor adaptor,
1640235cd73SKiran Chandramohan                   ConversionPatternRewriter &rewriter) const override {
1650235cd73SKiran Chandramohan     const TypeConverter *converter = ConvertToLLVMPattern::getTypeConverter();
1660235cd73SKiran Chandramohan 
1670235cd73SKiran Chandramohan     SmallVector<Type> resTypes;
1680235cd73SKiran Chandramohan     if (failed(converter->convertTypes(curOp->getResultTypes(), resTypes)))
1690235cd73SKiran Chandramohan       return failure();
1700235cd73SKiran Chandramohan 
1710235cd73SKiran Chandramohan     // Copy attributes of the curOp except for the typeAttr which should
1720235cd73SKiran Chandramohan     // be converted
1730235cd73SKiran Chandramohan     SmallVector<NamedAttribute> newAttrs;
1740235cd73SKiran Chandramohan     for (NamedAttribute attr : curOp->getAttrs()) {
1750235cd73SKiran Chandramohan       if (auto typeAttr = dyn_cast<TypeAttr>(attr.getValue())) {
1760235cd73SKiran Chandramohan         Type newAttr = converter->convertType(typeAttr.getValue());
1770235cd73SKiran Chandramohan         newAttrs.emplace_back(attr.getName(), TypeAttr::get(newAttr));
1780235cd73SKiran Chandramohan       } else {
1790235cd73SKiran Chandramohan         newAttrs.push_back(attr);
1800235cd73SKiran Chandramohan       }
1810235cd73SKiran Chandramohan     }
1820235cd73SKiran Chandramohan 
1830235cd73SKiran Chandramohan     rewriter.replaceOpWithNewOp<omp::MapInfoOp>(
1840235cd73SKiran Chandramohan         curOp, resTypes, adaptor.getOperands(), newAttrs);
1850235cd73SKiran Chandramohan     return success();
1860235cd73SKiran Chandramohan   }
1870235cd73SKiran Chandramohan };
1880235cd73SKiran Chandramohan 
189118a2a52SKareem Ergawy template <typename OpType>
190118a2a52SKareem Ergawy struct MultiRegionOpConversion : public ConvertOpToLLVMPattern<OpType> {
191118a2a52SKareem Ergawy   using ConvertOpToLLVMPattern<OpType>::ConvertOpToLLVMPattern;
192118a2a52SKareem Ergawy 
193118a2a52SKareem Ergawy   void forwardOpAttrs(OpType curOp, OpType newOp) const {}
194118a2a52SKareem Ergawy 
19556164c3eSDylan Fleming   LogicalResult
196118a2a52SKareem Ergawy   matchAndRewrite(OpType curOp, typename OpType::Adaptor adaptor,
19756164c3eSDylan Fleming                   ConversionPatternRewriter &rewriter) const override {
198118a2a52SKareem Ergawy     auto newOp = rewriter.create<OpType>(
19956164c3eSDylan Fleming         curOp.getLoc(), TypeRange(), curOp.getSymNameAttr(),
20056164c3eSDylan Fleming         TypeAttr::get(this->getTypeConverter()->convertType(
20156164c3eSDylan Fleming             curOp.getTypeAttr().getValue())));
202118a2a52SKareem Ergawy     forwardOpAttrs(curOp, newOp);
203118a2a52SKareem Ergawy 
20456164c3eSDylan Fleming     for (unsigned idx = 0; idx < curOp.getNumRegions(); idx++) {
20556164c3eSDylan Fleming       rewriter.inlineRegionBefore(curOp.getRegion(idx), newOp.getRegion(idx),
20656164c3eSDylan Fleming                                   newOp.getRegion(idx).end());
20756164c3eSDylan Fleming       if (failed(rewriter.convertRegionTypes(&newOp.getRegion(idx),
20856164c3eSDylan Fleming                                              *this->getTypeConverter())))
20956164c3eSDylan Fleming         return failure();
21056164c3eSDylan Fleming     }
21156164c3eSDylan Fleming 
21256164c3eSDylan Fleming     rewriter.eraseOp(curOp);
21356164c3eSDylan Fleming     return success();
21456164c3eSDylan Fleming   }
21556164c3eSDylan Fleming };
216118a2a52SKareem Ergawy 
217118a2a52SKareem Ergawy template <>
218118a2a52SKareem Ergawy void MultiRegionOpConversion<omp::PrivateClauseOp>::forwardOpAttrs(
219118a2a52SKareem Ergawy     omp::PrivateClauseOp curOp, omp::PrivateClauseOp newOp) const {
220118a2a52SKareem Ergawy   newOp.setDataSharingType(curOp.getDataSharingType());
221118a2a52SKareem Ergawy }
222875074c8SKiran Chandramohan } // namespace
223875074c8SKiran Chandramohan 
22400c511b3SNimish Mishra void mlir::configureOpenMPToLLVMConversionLegality(
225206fad0eSMatthias Springer     ConversionTarget &target, const LLVMTypeConverter &typeConverter) {
226af694df7SAkash Banerjee   target.addDynamicallyLegalOp<
227839275d0SSergio Afonso       omp::AtomicReadOp, omp::AtomicWriteOp, omp::CancellationPointOp,
228839275d0SSergio Afonso       omp::CancelOp, omp::CriticalDeclareOp, omp::FlushOp, omp::MapBoundsOp,
229839275d0SSergio Afonso       omp::MapInfoOp, omp::OrderedOp, omp::TargetEnterDataOp,
230839275d0SSergio Afonso       omp::TargetExitDataOp, omp::TargetUpdateOp, omp::ThreadprivateOp,
231839275d0SSergio Afonso       omp::YieldOp>([&](Operation *op) {
232dd32bf9aSKiran Chandramohan     return typeConverter.isLegal(op->getOperandTypes()) &&
233dd32bf9aSKiran Chandramohan            typeConverter.isLegal(op->getResultTypes());
23400c511b3SNimish Mishra   });
235118a2a52SKareem Ergawy   target.addDynamicallyLegalOp<
236839275d0SSergio Afonso       omp::AtomicUpdateOp, omp::CriticalOp, omp::DeclareReductionOp,
237fd3ff200SKareem Ergawy       omp::DistributeOp, omp::LoopNestOp, omp::LoopOp, omp::MasterOp,
238fd3ff200SKareem Ergawy       omp::OrderedRegionOp, omp::ParallelOp, omp::PrivateClauseOp,
239fd3ff200SKareem Ergawy       omp::SectionOp, omp::SectionsOp, omp::SimdOp, omp::SingleOp,
240fd3ff200SKareem Ergawy       omp::TargetDataOp, omp::TargetOp, omp::TaskgroupOp, omp::TaskloopOp,
241fd3ff200SKareem Ergawy       omp::TaskOp, omp::TeamsOp, omp::WsloopOp>([&](Operation *op) {
242118a2a52SKareem Ergawy     return std::all_of(op->getRegions().begin(), op->getRegions().end(),
243118a2a52SKareem Ergawy                        [&](Region &region) {
244118a2a52SKareem Ergawy                          return typeConverter.isLegal(&region);
245118a2a52SKareem Ergawy                        }) &&
24656164c3eSDylan Fleming            typeConverter.isLegal(op->getOperandTypes()) &&
24756164c3eSDylan Fleming            typeConverter.isLegal(op->getResultTypes());
24856164c3eSDylan Fleming   });
24900c511b3SNimish Mishra }
25000c511b3SNimish Mishra 
251dc4e913bSChris Lattner void mlir::populateOpenMPToLLVMConversionPatterns(LLVMTypeConverter &converter,
252dc4e913bSChris Lattner                                                   RewritePatternSet &patterns) {
253571df013SAndrew Gozillon   // This type is allowed when converting OpenMP to LLVM Dialect, it carries
254571df013SAndrew Gozillon   // bounds information for map clauses and the operation and type are
255571df013SAndrew Gozillon   // discarded on lowering to LLVM-IR from the OpenMP dialect.
256571df013SAndrew Gozillon   converter.addConversion(
257d84252e0SSergio Afonso       [&](omp::MapBoundsType type) -> Type { return type; });
258571df013SAndrew Gozillon 
259dd32bf9aSKiran Chandramohan   patterns.add<
26055e58423STom Eccles       AtomicReadOpConversion, MapInfoOpConversion,
261d84252e0SSergio Afonso       MultiRegionOpConversion<omp::DeclareReductionOp>,
262118a2a52SKareem Ergawy       MultiRegionOpConversion<omp::PrivateClauseOp>,
263839275d0SSergio Afonso       RegionLessOpConversion<omp::CancellationPointOp>,
264839275d0SSergio Afonso       RegionLessOpConversion<omp::CancelOp>,
265839275d0SSergio Afonso       RegionLessOpConversion<omp::CriticalDeclareOp>,
266839275d0SSergio Afonso       RegionLessOpConversion<omp::OrderedOp>,
267d84252e0SSergio Afonso       RegionLessOpConversion<omp::TargetEnterDataOp>,
268d84252e0SSergio Afonso       RegionLessOpConversion<omp::TargetExitDataOp>,
269d84252e0SSergio Afonso       RegionLessOpConversion<omp::TargetUpdateOp>,
270839275d0SSergio Afonso       RegionLessOpConversion<omp::YieldOp>,
271839275d0SSergio Afonso       RegionLessOpWithVarOperandsConversion<omp::AtomicWriteOp>,
272839275d0SSergio Afonso       RegionLessOpWithVarOperandsConversion<omp::FlushOp>,
273839275d0SSergio Afonso       RegionLessOpWithVarOperandsConversion<omp::MapBoundsOp>,
274839275d0SSergio Afonso       RegionLessOpWithVarOperandsConversion<omp::ThreadprivateOp>,
275839275d0SSergio Afonso       RegionOpConversion<omp::AtomicCaptureOp>,
276839275d0SSergio Afonso       RegionOpConversion<omp::CriticalOp>,
277839275d0SSergio Afonso       RegionOpConversion<omp::DistributeOp>,
278fd3ff200SKareem Ergawy       RegionOpConversion<omp::LoopNestOp>, RegionOpConversion<omp::LoopOp>,
279fd3ff200SKareem Ergawy       RegionOpConversion<omp::MaskedOp>, RegionOpConversion<omp::MasterOp>,
280839275d0SSergio Afonso       RegionOpConversion<omp::OrderedRegionOp>,
281839275d0SSergio Afonso       RegionOpConversion<omp::ParallelOp>, RegionOpConversion<omp::SectionOp>,
282839275d0SSergio Afonso       RegionOpConversion<omp::SectionsOp>, RegionOpConversion<omp::SimdOp>,
283839275d0SSergio Afonso       RegionOpConversion<omp::SingleOp>, RegionOpConversion<omp::TargetDataOp>,
284839275d0SSergio Afonso       RegionOpConversion<omp::TargetOp>, RegionOpConversion<omp::TaskgroupOp>,
285839275d0SSergio Afonso       RegionOpConversion<omp::TaskloopOp>, RegionOpConversion<omp::TaskOp>,
286839275d0SSergio Afonso       RegionOpConversion<omp::TeamsOp>, RegionOpConversion<omp::WsloopOp>,
287839275d0SSergio Afonso       RegionOpWithVarOperandsConversion<omp::AtomicUpdateOp>>(converter);
288875074c8SKiran Chandramohan }
289875074c8SKiran Chandramohan 
290875074c8SKiran Chandramohan namespace {
291875074c8SKiran Chandramohan struct ConvertOpenMPToLLVMPass
292cd4ca2d7SMarkus Böck     : public impl::ConvertOpenMPToLLVMPassBase<ConvertOpenMPToLLVMPass> {
293cd4ca2d7SMarkus Böck   using Base::Base;
294cd4ca2d7SMarkus Böck 
295875074c8SKiran Chandramohan   void runOnOperation() override;
296875074c8SKiran Chandramohan };
297875074c8SKiran Chandramohan } // namespace
298875074c8SKiran Chandramohan 
299875074c8SKiran Chandramohan void ConvertOpenMPToLLVMPass::runOnOperation() {
300875074c8SKiran Chandramohan   auto module = getOperation();
301875074c8SKiran Chandramohan 
302875074c8SKiran Chandramohan   // Convert to OpenMP operations with LLVM IR dialect
303dc4e913bSChris Lattner   RewritePatternSet patterns(&getContext());
304875074c8SKiran Chandramohan   LLVMTypeConverter converter(&getContext());
305abc362a1SJakub Kuderski   arith::populateArithToLLVMConversionPatterns(converter, patterns);
306ace01605SRiver Riddle   cf::populateControlFlowToLLVMConversionPatterns(converter, patterns);
307*599c7399SMatthias Springer   cf::populateAssertToLLVMConversionPattern(converter, patterns);
308cb4ccd38SQuentin Colombet   populateFinalizeMemRefToLLVMConversionPatterns(converter, patterns);
3095a7b9194SRiver Riddle   populateFuncToLLVMConversionPatterns(converter, patterns);
310563879b6SRahul Joshi   populateOpenMPToLLVMConversionPatterns(converter, patterns);
311875074c8SKiran Chandramohan 
312875074c8SKiran Chandramohan   LLVMConversionTarget target(getContext());
313839275d0SSergio Afonso   target.addLegalOp<omp::BarrierOp, omp::FlushOp, omp::TaskwaitOp,
314839275d0SSergio Afonso                     omp::TaskyieldOp, omp::TerminatorOp>();
31500c511b3SNimish Mishra   configureOpenMPToLLVMConversionLegality(target, converter);
3163fffffa8SRiver Riddle   if (failed(applyPartialConversion(module, target, std::move(patterns))))
317875074c8SKiran Chandramohan     signalPassFailure();
318875074c8SKiran Chandramohan }
31958d97034SFabian Mora 
32058d97034SFabian Mora //===----------------------------------------------------------------------===//
32158d97034SFabian Mora // ConvertToLLVMPatternInterface implementation
32258d97034SFabian Mora //===----------------------------------------------------------------------===//
32358d97034SFabian Mora namespace {
32458d97034SFabian Mora /// Implement the interface to convert OpenMP to LLVM.
32558d97034SFabian Mora struct OpenMPToLLVMDialectInterface : public ConvertToLLVMPatternInterface {
32658d97034SFabian Mora   using ConvertToLLVMPatternInterface::ConvertToLLVMPatternInterface;
32758d97034SFabian Mora   void loadDependentDialects(MLIRContext *context) const final {
32858d97034SFabian Mora     context->loadDialect<LLVM::LLVMDialect>();
32958d97034SFabian Mora   }
33058d97034SFabian Mora 
33158d97034SFabian Mora   /// Hook for derived dialect interface to provide conversion patterns
33258d97034SFabian Mora   /// and mark dialect legal for the conversion target.
33358d97034SFabian Mora   void populateConvertToLLVMConversionPatterns(
33458d97034SFabian Mora       ConversionTarget &target, LLVMTypeConverter &typeConverter,
33558d97034SFabian Mora       RewritePatternSet &patterns) const final {
33658d97034SFabian Mora     configureOpenMPToLLVMConversionLegality(target, typeConverter);
33758d97034SFabian Mora     populateOpenMPToLLVMConversionPatterns(typeConverter, patterns);
33858d97034SFabian Mora   }
33958d97034SFabian Mora };
34058d97034SFabian Mora } // namespace
34158d97034SFabian Mora 
34258d97034SFabian Mora void mlir::registerConvertOpenMPToLLVMInterface(DialectRegistry &registry) {
34358d97034SFabian Mora   registry.addExtension(+[](MLIRContext *ctx, omp::OpenMPDialect *dialect) {
34458d97034SFabian Mora     dialect->addInterfaces<OpenMPToLLVMDialectInterface>();
34558d97034SFabian Mora   });
34658d97034SFabian Mora }
347