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 ®ion) { 244118a2a52SKareem Ergawy return typeConverter.isLegal(®ion); 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 ®istry) { 34358d97034SFabian Mora registry.addExtension(+[](MLIRContext *ctx, omp::OpenMPDialect *dialect) { 34458d97034SFabian Mora dialect->addInterfaces<OpenMPToLLVMDialectInterface>(); 34558d97034SFabian Mora }); 34658d97034SFabian Mora } 347