Skip to content

Commit 118a2a5

Browse files
authored
[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.
1 parent ceaf09c commit 118a2a5

File tree

4 files changed

+75
-26
lines changed

4 files changed

+75
-26
lines changed

mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,12 @@ def PrivateClauseOp : OpenMP_Op<"private", [IsolatedFromAbove]> {
221221
attr-dict
222222
}];
223223

224+
let builders = [
225+
OpBuilder<(ins CArg<"TypeRange">:$result,
226+
CArg<"StringAttr">:$sym_name,
227+
CArg<"TypeAttr">:$type)>
228+
];
229+
224230
let hasVerifier = 1;
225231
}
226232

mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -200,16 +200,21 @@ struct ReductionOpConversion : public ConvertOpToLLVMPattern<omp::ReductionOp> {
200200
}
201201
};
202202

203-
struct ReductionDeclareOpConversion
204-
: public ConvertOpToLLVMPattern<omp::ReductionDeclareOp> {
205-
using ConvertOpToLLVMPattern<omp::ReductionDeclareOp>::ConvertOpToLLVMPattern;
203+
template <typename OpType>
204+
struct MultiRegionOpConversion : public ConvertOpToLLVMPattern<OpType> {
205+
using ConvertOpToLLVMPattern<OpType>::ConvertOpToLLVMPattern;
206+
207+
void forwardOpAttrs(OpType curOp, OpType newOp) const {}
208+
206209
LogicalResult
207-
matchAndRewrite(omp::ReductionDeclareOp curOp, OpAdaptor adaptor,
210+
matchAndRewrite(OpType curOp, typename OpType::Adaptor adaptor,
208211
ConversionPatternRewriter &rewriter) const override {
209-
auto newOp = rewriter.create<omp::ReductionDeclareOp>(
212+
auto newOp = rewriter.create<OpType>(
210213
curOp.getLoc(), TypeRange(), curOp.getSymNameAttr(),
211214
TypeAttr::get(this->getTypeConverter()->convertType(
212215
curOp.getTypeAttr().getValue())));
216+
forwardOpAttrs(curOp, newOp);
217+
213218
for (unsigned idx = 0; idx < curOp.getNumRegions(); idx++) {
214219
rewriter.inlineRegionBefore(curOp.getRegion(idx), newOp.getRegion(idx),
215220
newOp.getRegion(idx).end());
@@ -222,20 +227,16 @@ struct ReductionDeclareOpConversion
222227
return success();
223228
}
224229
};
230+
231+
template <>
232+
void MultiRegionOpConversion<omp::PrivateClauseOp>::forwardOpAttrs(
233+
omp::PrivateClauseOp curOp, omp::PrivateClauseOp newOp) const {
234+
newOp.setDataSharingType(curOp.getDataSharingType());
235+
}
225236
} // namespace
226237

227238
void mlir::configureOpenMPToLLVMConversionLegality(
228239
ConversionTarget &target, LLVMTypeConverter &typeConverter) {
229-
target.addDynamicallyLegalOp<
230-
mlir::omp::AtomicUpdateOp, mlir::omp::CriticalOp, mlir::omp::TargetOp,
231-
mlir::omp::DataOp, mlir::omp::OrderedRegionOp, mlir::omp::ParallelOp,
232-
mlir::omp::WsLoopOp, mlir::omp::SimdLoopOp, mlir::omp::MasterOp,
233-
mlir::omp::SectionOp, mlir::omp::SectionsOp, mlir::omp::SingleOp,
234-
mlir::omp::TaskGroupOp, mlir::omp::TaskOp>([&](Operation *op) {
235-
return typeConverter.isLegal(&op->getRegion(0)) &&
236-
typeConverter.isLegal(op->getOperandTypes()) &&
237-
typeConverter.isLegal(op->getResultTypes());
238-
});
239240
target.addDynamicallyLegalOp<
240241
mlir::omp::AtomicReadOp, mlir::omp::AtomicWriteOp, mlir::omp::FlushOp,
241242
mlir::omp::ThreadprivateOp, mlir::omp::YieldOp, mlir::omp::EnterDataOp,
@@ -247,14 +248,20 @@ void mlir::configureOpenMPToLLVMConversionLegality(
247248
target.addDynamicallyLegalOp<mlir::omp::ReductionOp>([&](Operation *op) {
248249
return typeConverter.isLegal(op->getOperandTypes());
249250
});
250-
target.addDynamicallyLegalOp<mlir::omp::ReductionDeclareOp>(
251-
[&](Operation *op) {
252-
return typeConverter.isLegal(&op->getRegion(0)) &&
253-
typeConverter.isLegal(&op->getRegion(1)) &&
254-
typeConverter.isLegal(&op->getRegion(2)) &&
255-
typeConverter.isLegal(op->getOperandTypes()) &&
256-
typeConverter.isLegal(op->getResultTypes());
257-
});
251+
target.addDynamicallyLegalOp<
252+
mlir::omp::AtomicUpdateOp, mlir::omp::CriticalOp, mlir::omp::TargetOp,
253+
mlir::omp::DataOp, mlir::omp::OrderedRegionOp, mlir::omp::ParallelOp,
254+
mlir::omp::WsLoopOp, mlir::omp::SimdLoopOp, mlir::omp::MasterOp,
255+
mlir::omp::SectionOp, mlir::omp::SectionsOp, mlir::omp::SingleOp,
256+
mlir::omp::TaskGroupOp, mlir::omp::TaskOp, mlir::omp::ReductionDeclareOp,
257+
mlir::omp::PrivateClauseOp>([&](Operation *op) {
258+
return std::all_of(op->getRegions().begin(), op->getRegions().end(),
259+
[&](Region &region) {
260+
return typeConverter.isLegal(&region);
261+
}) &&
262+
typeConverter.isLegal(op->getOperandTypes()) &&
263+
typeConverter.isLegal(op->getResultTypes());
264+
});
258265
}
259266

260267
void mlir::populateOpenMPToLLVMConversionPatterns(LLVMTypeConverter &converter,
@@ -267,9 +274,10 @@ void mlir::populateOpenMPToLLVMConversionPatterns(LLVMTypeConverter &converter,
267274

268275
patterns.add<
269276
AtomicReadOpConversion, MapInfoOpConversion, ReductionOpConversion,
270-
ReductionDeclareOpConversion, RegionOpConversion<omp::CriticalOp>,
271-
RegionOpConversion<omp::MasterOp>, ReductionOpConversion,
272-
RegionOpConversion<omp::OrderedRegionOp>,
277+
MultiRegionOpConversion<omp::ReductionDeclareOp>,
278+
MultiRegionOpConversion<omp::PrivateClauseOp>,
279+
RegionOpConversion<omp::CriticalOp>, RegionOpConversion<omp::MasterOp>,
280+
ReductionOpConversion, RegionOpConversion<omp::OrderedRegionOp>,
273281
RegionOpConversion<omp::ParallelOp>, RegionOpConversion<omp::WsLoopOp>,
274282
RegionOpConversion<omp::SectionsOp>, RegionOpConversion<omp::SectionOp>,
275283
RegionOpConversion<omp::SimdLoopOp>, RegionOpConversion<omp::SingleOp>,

mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1858,6 +1858,15 @@ LogicalResult DataBoundsOp::verify() {
18581858
return success();
18591859
}
18601860

1861+
void PrivateClauseOp::build(OpBuilder &odsBuilder, OperationState &odsState,
1862+
TypeRange /*result_types*/, StringAttr symName,
1863+
TypeAttr type) {
1864+
PrivateClauseOp::build(
1865+
odsBuilder, odsState, symName, type,
1866+
DataSharingClauseTypeAttr::get(odsBuilder.getContext(),
1867+
DataSharingClauseType::Private));
1868+
}
1869+
18611870
LogicalResult PrivateClauseOp::verify() {
18621871
Type symType = getType();
18631872

mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,3 +485,29 @@ llvm.func @_QPtarget_map_with_bounds(%arg0: !llvm.ptr, %arg1: !llvm.ptr, %arg2:
485485
}
486486
llvm.return
487487
}
488+
489+
// -----
490+
491+
// CHECK: omp.private {type = private} @x.privatizer : !llvm.struct<{{.*}}> alloc {
492+
omp.private {type = private} @x.privatizer : memref<?xf32> alloc {
493+
// CHECK: ^bb0(%arg0: !llvm.struct<{{.*}}>):
494+
^bb0(%arg0: memref<?xf32>):
495+
// CHECK: omp.yield(%arg0 : !llvm.struct<{{.*}}>)
496+
omp.yield(%arg0 : memref<?xf32>)
497+
}
498+
499+
// -----
500+
501+
// CHECK: omp.private {type = firstprivate} @y.privatizer : i64 alloc {
502+
omp.private {type = firstprivate} @y.privatizer : index alloc {
503+
// CHECK: ^bb0(%arg0: i64):
504+
^bb0(%arg0: index):
505+
// CHECK: omp.yield(%arg0 : i64)
506+
omp.yield(%arg0 : index)
507+
// CHECK: } copy {
508+
} copy {
509+
// CHECK: ^bb0(%arg0: i64, %arg1: i64):
510+
^bb0(%arg0: index, %arg1: index):
511+
// CHECK: omp.yield(%arg0 : i64)
512+
omp.yield(%arg0 : index)
513+
}

0 commit comments

Comments
 (0)