From 118a2a52fd465b7576c54bd102ee2e417a3b9a71 Mon Sep 17 00:00:00 2001 From: Kareem Ergawy Date: Fri, 16 Feb 2024 05:57:41 +0100 Subject: [PATCH] [MLIR][OpenMP] Support `llvm` conversion for `omp.private` regions (#81414) Introduces conversion of `omp.private`'s regions to the LLVM dialect. This reuses the already existing conversion pattern for `ReducetionDeclareOp` and repurposes it to be used for multi-region ops as well. --- mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td | 6 ++ .../Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp | 60 +++++++++++-------- mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp | 9 +++ .../OpenMPToLLVM/convert-to-llvmir.mlir | 26 ++++++++ 4 files changed, 75 insertions(+), 26 deletions(-) diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td index 6a799228d74894..024f43f7e7e3b6 100644 --- a/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td +++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td @@ -221,6 +221,12 @@ def PrivateClauseOp : OpenMP_Op<"private", [IsolatedFromAbove]> { attr-dict }]; + let builders = [ + OpBuilder<(ins CArg<"TypeRange">:$result, + CArg<"StringAttr">:$sym_name, + CArg<"TypeAttr">:$type)> + ]; + let hasVerifier = 1; } diff --git a/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp b/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp index 730858ffc67a71..fa54d01cfe2384 100644 --- a/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp +++ b/mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp @@ -200,16 +200,21 @@ struct ReductionOpConversion : public ConvertOpToLLVMPattern { } }; -struct ReductionDeclareOpConversion - : public ConvertOpToLLVMPattern { - using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern; +template +struct MultiRegionOpConversion : public ConvertOpToLLVMPattern { + using ConvertOpToLLVMPattern::ConvertOpToLLVMPattern; + + void forwardOpAttrs(OpType curOp, OpType newOp) const {} + LogicalResult - matchAndRewrite(omp::ReductionDeclareOp curOp, OpAdaptor adaptor, + matchAndRewrite(OpType curOp, typename OpType::Adaptor adaptor, ConversionPatternRewriter &rewriter) const override { - auto newOp = rewriter.create( + auto newOp = rewriter.create( curOp.getLoc(), TypeRange(), curOp.getSymNameAttr(), TypeAttr::get(this->getTypeConverter()->convertType( curOp.getTypeAttr().getValue()))); + forwardOpAttrs(curOp, newOp); + for (unsigned idx = 0; idx < curOp.getNumRegions(); idx++) { rewriter.inlineRegionBefore(curOp.getRegion(idx), newOp.getRegion(idx), newOp.getRegion(idx).end()); @@ -222,20 +227,16 @@ struct ReductionDeclareOpConversion return success(); } }; + +template <> +void MultiRegionOpConversion::forwardOpAttrs( + omp::PrivateClauseOp curOp, omp::PrivateClauseOp newOp) const { + newOp.setDataSharingType(curOp.getDataSharingType()); +} } // namespace void mlir::configureOpenMPToLLVMConversionLegality( ConversionTarget &target, LLVMTypeConverter &typeConverter) { - target.addDynamicallyLegalOp< - mlir::omp::AtomicUpdateOp, mlir::omp::CriticalOp, mlir::omp::TargetOp, - mlir::omp::DataOp, mlir::omp::OrderedRegionOp, mlir::omp::ParallelOp, - mlir::omp::WsLoopOp, mlir::omp::SimdLoopOp, mlir::omp::MasterOp, - mlir::omp::SectionOp, mlir::omp::SectionsOp, mlir::omp::SingleOp, - mlir::omp::TaskGroupOp, mlir::omp::TaskOp>([&](Operation *op) { - return typeConverter.isLegal(&op->getRegion(0)) && - typeConverter.isLegal(op->getOperandTypes()) && - typeConverter.isLegal(op->getResultTypes()); - }); target.addDynamicallyLegalOp< mlir::omp::AtomicReadOp, mlir::omp::AtomicWriteOp, mlir::omp::FlushOp, mlir::omp::ThreadprivateOp, mlir::omp::YieldOp, mlir::omp::EnterDataOp, @@ -247,14 +248,20 @@ void mlir::configureOpenMPToLLVMConversionLegality( target.addDynamicallyLegalOp([&](Operation *op) { return typeConverter.isLegal(op->getOperandTypes()); }); - target.addDynamicallyLegalOp( - [&](Operation *op) { - return typeConverter.isLegal(&op->getRegion(0)) && - typeConverter.isLegal(&op->getRegion(1)) && - typeConverter.isLegal(&op->getRegion(2)) && - typeConverter.isLegal(op->getOperandTypes()) && - typeConverter.isLegal(op->getResultTypes()); - }); + target.addDynamicallyLegalOp< + mlir::omp::AtomicUpdateOp, mlir::omp::CriticalOp, mlir::omp::TargetOp, + mlir::omp::DataOp, mlir::omp::OrderedRegionOp, mlir::omp::ParallelOp, + mlir::omp::WsLoopOp, mlir::omp::SimdLoopOp, mlir::omp::MasterOp, + mlir::omp::SectionOp, mlir::omp::SectionsOp, mlir::omp::SingleOp, + mlir::omp::TaskGroupOp, mlir::omp::TaskOp, mlir::omp::ReductionDeclareOp, + mlir::omp::PrivateClauseOp>([&](Operation *op) { + return std::all_of(op->getRegions().begin(), op->getRegions().end(), + [&](Region ®ion) { + return typeConverter.isLegal(®ion); + }) && + typeConverter.isLegal(op->getOperandTypes()) && + typeConverter.isLegal(op->getResultTypes()); + }); } void mlir::populateOpenMPToLLVMConversionPatterns(LLVMTypeConverter &converter, @@ -267,9 +274,10 @@ void mlir::populateOpenMPToLLVMConversionPatterns(LLVMTypeConverter &converter, patterns.add< AtomicReadOpConversion, MapInfoOpConversion, ReductionOpConversion, - ReductionDeclareOpConversion, RegionOpConversion, - RegionOpConversion, ReductionOpConversion, - RegionOpConversion, + MultiRegionOpConversion, + MultiRegionOpConversion, + RegionOpConversion, RegionOpConversion, + ReductionOpConversion, RegionOpConversion, RegionOpConversion, RegionOpConversion, RegionOpConversion, RegionOpConversion, RegionOpConversion, RegionOpConversion, diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp index d1bff4ee70152f..82e32da91aaeeb 100644 --- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp +++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp @@ -1858,6 +1858,15 @@ LogicalResult DataBoundsOp::verify() { return success(); } +void PrivateClauseOp::build(OpBuilder &odsBuilder, OperationState &odsState, + TypeRange /*result_types*/, StringAttr symName, + TypeAttr type) { + PrivateClauseOp::build( + odsBuilder, odsState, symName, type, + DataSharingClauseTypeAttr::get(odsBuilder.getContext(), + DataSharingClauseType::Private)); +} + LogicalResult PrivateClauseOp::verify() { Type symType = getType(); diff --git a/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir b/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir index ae3bb6ccea7a8b..6cbc0c8f4be9a2 100644 --- a/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir +++ b/mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir @@ -485,3 +485,29 @@ llvm.func @_QPtarget_map_with_bounds(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2: } llvm.return } + +// ----- + +// CHECK: omp.private {type = private} @x.privatizer : !llvm.struct<{{.*}}> alloc { +omp.private {type = private} @x.privatizer : memref alloc { +// CHECK: ^bb0(%arg0: !llvm.struct<{{.*}}>): +^bb0(%arg0: memref): + // CHECK: omp.yield(%arg0 : !llvm.struct<{{.*}}>) + omp.yield(%arg0 : memref) +} + +// ----- + +// CHECK: omp.private {type = firstprivate} @y.privatizer : i64 alloc { +omp.private {type = firstprivate} @y.privatizer : index alloc { +// CHECK: ^bb0(%arg0: i64): +^bb0(%arg0: index): + // CHECK: omp.yield(%arg0 : i64) + omp.yield(%arg0 : index) +// CHECK: } copy { +} copy { +// CHECK: ^bb0(%arg0: i64, %arg1: i64): +^bb0(%arg0: index, %arg1: index): + // CHECK: omp.yield(%arg0 : i64) + omp.yield(%arg0 : index) +}