mirror of
https://github.com/intel/llvm.git
synced 2026-01-16 05:32:28 +08:00
[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.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -200,16 +200,21 @@ struct ReductionOpConversion : public ConvertOpToLLVMPattern<omp::ReductionOp> {
|
||||
}
|
||||
};
|
||||
|
||||
struct ReductionDeclareOpConversion
|
||||
: public ConvertOpToLLVMPattern<omp::ReductionDeclareOp> {
|
||||
using ConvertOpToLLVMPattern<omp::ReductionDeclareOp>::ConvertOpToLLVMPattern;
|
||||
template <typename OpType>
|
||||
struct MultiRegionOpConversion : public ConvertOpToLLVMPattern<OpType> {
|
||||
using ConvertOpToLLVMPattern<OpType>::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<omp::ReductionDeclareOp>(
|
||||
auto newOp = rewriter.create<OpType>(
|
||||
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<omp::PrivateClauseOp>::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<mlir::omp::ReductionOp>([&](Operation *op) {
|
||||
return typeConverter.isLegal(op->getOperandTypes());
|
||||
});
|
||||
target.addDynamicallyLegalOp<mlir::omp::ReductionDeclareOp>(
|
||||
[&](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<omp::CriticalOp>,
|
||||
RegionOpConversion<omp::MasterOp>, ReductionOpConversion,
|
||||
RegionOpConversion<omp::OrderedRegionOp>,
|
||||
MultiRegionOpConversion<omp::ReductionDeclareOp>,
|
||||
MultiRegionOpConversion<omp::PrivateClauseOp>,
|
||||
RegionOpConversion<omp::CriticalOp>, RegionOpConversion<omp::MasterOp>,
|
||||
ReductionOpConversion, RegionOpConversion<omp::OrderedRegionOp>,
|
||||
RegionOpConversion<omp::ParallelOp>, RegionOpConversion<omp::WsLoopOp>,
|
||||
RegionOpConversion<omp::SectionsOp>, RegionOpConversion<omp::SectionOp>,
|
||||
RegionOpConversion<omp::SimdLoopOp>, RegionOpConversion<omp::SingleOp>,
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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<?xf32> alloc {
|
||||
// CHECK: ^bb0(%arg0: !llvm.struct<{{.*}}>):
|
||||
^bb0(%arg0: memref<?xf32>):
|
||||
// CHECK: omp.yield(%arg0 : !llvm.struct<{{.*}}>)
|
||||
omp.yield(%arg0 : memref<?xf32>)
|
||||
}
|
||||
|
||||
// -----
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user