Skip to content

Commit

Permalink
[MLIR][OpenMP] Add conversion support from FIR to LLVM Dialect for OM…
Browse files Browse the repository at this point in the history
…P Target

This enables conversion of OpenMP Target op with region from FIR Dialect to LLVM IR Dialect.

Differential Revision: https://reviews.llvm.org/D147439
  • Loading branch information
TIFitis committed Apr 11, 2023
1 parent 07b52b5 commit dc26a3d
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 32 deletions.
37 changes: 35 additions & 2 deletions flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
Expand Up @@ -321,6 +321,39 @@ func.func @_QPopenmp_target_data_region() {

// -----

func.func @_QPomp_target() {
%0 = fir.alloca !fir.array<512xi32> {bindc_name = "a", uniq_name = "_QFomp_targetEa"}
%c64_i32 = arith.constant 64 : i32
omp.target thread_limit(%c64_i32 : i32) map((tofrom -> %0 : !fir.ref<!fir.array<512xi32>>)) {
%c10_i32 = arith.constant 10 : i32
%c1_i64 = arith.constant 1 : i64
%c1_i64_0 = arith.constant 1 : i64
%1 = arith.subi %c1_i64, %c1_i64_0 : i64
%2 = fir.coordinate_of %0, %1 : (!fir.ref<!fir.array<512xi32>>, i64) -> !fir.ref<i32>
fir.store %c10_i32 to %2 : !fir.ref<i32>
omp.terminator
}
return
}

// CHECK-LABEL: llvm.func @_QPomp_target() {
// CHECK: %[[VAL_0:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[VAL_1:.*]] = llvm.alloca %[[VAL_0]] x !llvm.array<512 x i32> {bindc_name = "a", in_type = !fir.array<512xi32>, operand_segment_sizes = array<i32: 0, 0>, uniq_name = "_QFomp_targetEa"} : (i64) -> !llvm.ptr<array<512 x i32>>
// CHECK: %[[VAL_2:.*]] = llvm.mlir.constant(64 : i32) : i32
// CHECK: omp.target thread_limit(%[[VAL_2]] : i32) map((tofrom -> %[[VAL_1]] : !llvm.ptr<array<512 x i32>>)) {
// CHECK: %[[VAL_3:.*]] = llvm.mlir.constant(10 : i32) : i32
// CHECK: %[[VAL_4:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[VAL_5:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[VAL_6:.*]] = llvm.mlir.constant(0 : i64) : i64
// CHECK: %[[VAL_7:.*]] = llvm.getelementptr %[[VAL_1]][0, %[[VAL_6]]] : (!llvm.ptr<array<512 x i32>>, i64) -> !llvm.ptr<i32>
// CHECK: llvm.store %[[VAL_3]], %[[VAL_7]] : !llvm.ptr<i32>
// CHECK: omp.terminator
// CHECK: }
// CHECK: llvm.return
// CHECK: }

// -----

func.func @_QPsimdloop_with_nested_loop() {
%0 = fir.alloca i32 {adapt.valuebyref}
%1 = fir.alloca !fir.array<10xi32> {bindc_name = "a", uniq_name = "_QFsimdloop_with_nested_loopEa"}
Expand Down Expand Up @@ -501,7 +534,7 @@ func.func @_QPsb() {
// CHECK: %[[RES:.*]] = llvm.icmp "eq" %[[ARGVAL_1]], %[[ARGVAL_2]] : i1
// CHECK: %[[RES_EXT:.*]] = llvm.zext %[[RES]] : i1 to i32
// CHECK: omp.yield(%[[RES_EXT]] : i32)
// CHECK: }
// CHECK: }
// CHECK-LABEL: @_QPsimple_reduction
// CHECK-SAME: %[[ARRAY_REF:.*]]: !llvm.ptr<array<100 x i32>>
// CHECK: %[[RED_ACCUMULATOR:.*]] = llvm.alloca %2 x i32 {bindc_name = "x", in_type = !fir.logical<4>, operand_segment_sizes = array<i32: 0, 0>, uniq_name = "_QFsimple_reductionEx"} : (i64) -> !llvm.ptr<i32>
Expand All @@ -526,7 +559,7 @@ omp.reduction.declare @eqv_reduction : !fir.logical<4> init {
%2 = arith.cmpi eq, %0, %1 : i1
%3 = fir.convert %2 : (i1) -> !fir.logical<4>
omp.yield(%3 : !fir.logical<4>)
}
}
func.func @_QPsimple_reduction(%arg0: !fir.ref<!fir.array<100x!fir.logical<4>>> {fir.bindc_name = "y"}) {
%0 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsimple_reductionEi"}
%1 = fir.alloca !fir.logical<4> {bindc_name = "x", uniq_name = "_QFsimple_reductionEx"}
Expand Down
49 changes: 19 additions & 30 deletions mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp
Expand Up @@ -153,18 +153,6 @@ struct ReductionOpConversion : public ConvertOpToLLVMPattern<omp::ReductionOp> {
}
};

template <typename Op>
struct LegalizeDataOpForLLVMTranslation : public ConvertOpToLLVMPattern<Op> {
using ConvertOpToLLVMPattern<Op>::ConvertOpToLLVMPattern;
LogicalResult
matchAndRewrite(Op curOp, typename Op::Adaptor adaptor,
ConversionPatternRewriter &rewriter) const override {
rewriter.replaceOpWithNewOp<Op>(curOp, TypeRange(), adaptor.getOperands(),
curOp.getOperation()->getAttrs());
return success();
}
};

struct ReductionDeclareOpConversion
: public ConvertOpToLLVMPattern<omp::ReductionDeclareOp> {
using ConvertOpToLLVMPattern<omp::ReductionDeclareOp>::ConvertOpToLLVMPattern;
Expand Down Expand Up @@ -192,14 +180,15 @@ struct ReductionDeclareOpConversion
void mlir::configureOpenMPToLLVMConversionLegality(
ConversionTarget &target, LLVMTypeConverter &typeConverter) {
target.addDynamicallyLegalOp<
mlir::omp::AtomicUpdateOp, mlir::omp::CriticalOp, mlir::omp::DataOp,
mlir::omp::ParallelOp, mlir::omp::WsLoopOp, mlir::omp::SimdLoopOp,
mlir::omp::MasterOp, mlir::omp::SectionOp, mlir::omp::SectionsOp,
mlir::omp::SingleOp, mlir::omp::TaskOp>([&](Operation *op) {
return typeConverter.isLegal(&op->getRegion(0)) &&
typeConverter.isLegal(op->getOperandTypes()) &&
typeConverter.isLegal(op->getResultTypes());
});
mlir::omp::AtomicUpdateOp, mlir::omp::CriticalOp, mlir::omp::TargetOp,
mlir::omp::DataOp, mlir::omp::ParallelOp, mlir::omp::WsLoopOp,
mlir::omp::SimdLoopOp, mlir::omp::MasterOp, mlir::omp::SectionOp,
mlir::omp::SectionsOp, mlir::omp::SingleOp, 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,
Expand All @@ -224,21 +213,21 @@ void mlir::configureOpenMPToLLVMConversionLegality(
void mlir::populateOpenMPToLLVMConversionPatterns(LLVMTypeConverter &converter,
RewritePatternSet &patterns) {
patterns.add<
LegalizeDataOpForLLVMTranslation<omp::DataOp>,
LegalizeDataOpForLLVMTranslation<omp::EnterDataOp>,
LegalizeDataOpForLLVMTranslation<omp::ExitDataOp>, ReductionOpConversion,
ReductionDeclareOpConversion, RegionOpConversion<omp::CriticalOp>,
RegionOpConversion<omp::MasterOp>, ReductionOpConversion,
RegionOpConversion<omp::ParallelOp>, RegionOpConversion<omp::WsLoopOp>,
RegionOpConversion<omp::SectionsOp>, RegionOpConversion<omp::SectionOp>,
RegionOpConversion<omp::SimdLoopOp>, RegionOpConversion<omp::SingleOp>,
RegionOpConversion<omp::TaskOp>, RegionOpConversion<omp::DataOp>,
ReductionOpConversion, ReductionDeclareOpConversion,
RegionOpConversion<omp::CriticalOp>, RegionOpConversion<omp::MasterOp>,
ReductionOpConversion, RegionOpConversion<omp::ParallelOp>,
RegionOpConversion<omp::WsLoopOp>, RegionOpConversion<omp::SectionsOp>,
RegionOpConversion<omp::SectionOp>, RegionOpConversion<omp::SimdLoopOp>,
RegionOpConversion<omp::SingleOp>, RegionOpConversion<omp::TaskOp>,
RegionOpConversion<omp::DataOp>, RegionOpConversion<omp::TargetOp>,
RegionLessOpWithVarOperandsConversion<omp::AtomicReadOp>,
RegionLessOpWithVarOperandsConversion<omp::AtomicWriteOp>,
RegionOpWithVarOperandsConversion<omp::AtomicUpdateOp>,
RegionLessOpWithVarOperandsConversion<omp::FlushOp>,
RegionLessOpWithVarOperandsConversion<omp::ThreadprivateOp>,
RegionLessOpConversion<omp::YieldOp>>(converter);
RegionLessOpConversion<omp::YieldOp>,
RegionLessOpConversion<omp::EnterDataOp>,
RegionLessOpConversion<omp::ExitDataOp>>(converter);
}

namespace {
Expand Down
24 changes: 24 additions & 0 deletions mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir
Expand Up @@ -225,6 +225,30 @@ llvm.func @_QPomp_target_data_region(%a : !llvm.ptr<array<1024 x i32>>, %i : !ll

// -----

// CHECK-LABEL: llvm.func @_QPomp_target(
// CHECK: %[[ARG_0:.*]]: !llvm.ptr<array<1024 x i32>>,
// CHECK: %[[ARG_1:.*]]: !llvm.ptr<i32>) {
// CHECK: %[[VAL_0:.*]] = llvm.mlir.constant(64 : i32) : i32
// CHECK: omp.target thread_limit(%[[VAL_0]] : i32) map((tofrom -> %[[ARG_0]] : !llvm.ptr<array<1024 x i32>>)) {
// CHECK: %[[VAL_1:.*]] = llvm.mlir.constant(10 : i32) : i32
// CHECK: llvm.store %[[VAL_1]], %[[ARG_1]] : !llvm.ptr<i32>
// CHECK: omp.terminator
// CHECK: }
// CHECK: llvm.return
// CHECK: }

llvm.func @_QPomp_target(%a : !llvm.ptr<array<1024 x i32>>, %i : !llvm.ptr<i32>) {
%0 = llvm.mlir.constant(64 : i32) : i32
omp.target thread_limit(%0 : i32) map((tofrom -> %a : !llvm.ptr<array<1024 x i32>>)) {
%1 = llvm.mlir.constant(10 : i32) : i32
llvm.store %1, %i : !llvm.ptr<i32>
omp.terminator
}
llvm.return
}

// -----

// CHECK-LABEL: @_QPsb
// CHECK: omp.sections
// CHECK: omp.section
Expand Down

0 comments on commit dc26a3d

Please sign in to comment.