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 Data with region

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

Differential Revision: https://reviews.llvm.org/D144380
  • Loading branch information
TIFitis committed Feb 23, 2023
1 parent dbf149c commit af694df
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 29 deletions.
81 changes: 80 additions & 1 deletion flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ func.func @_QPsb2(%arg0: !fir.ref<i32> {fir.bindc_name = "x"}, %arg1: !fir.ref<i
// CHECK: llvm.return
// CHECK: }


// -----

func.func @_QPsb(%arr: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "arr"}) {
Expand Down Expand Up @@ -218,6 +217,8 @@ func.func @_QPsimd1(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.ref
// CHECK: llvm.return
// CHECK: }

// -----

func.func @_QPomp_target_data() {
%0 = fir.alloca !fir.array<1024xi32> {bindc_name = "a", uniq_name = "_QFomp_target_dataEa"}
%1 = fir.alloca !fir.array<1024xi32> {bindc_name = "b", uniq_name = "_QFomp_target_dataEb"}
Expand All @@ -242,6 +243,84 @@ func.func @_QPomp_target_data() {
// CHECK: llvm.return
// CHECK: }

// -----

func.func @_QPopenmp_target_data_region() {
%0 = fir.alloca !fir.array<1024xi32> {bindc_name = "a", uniq_name = "_QFopenmp_target_data_regionEa"}
%1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFopenmp_target_data_regionEi"}
omp.target_data map((tofrom -> %0 : !fir.ref<!fir.array<1024xi32>>)) {
%c1_i32 = arith.constant 1 : i32
%2 = fir.convert %c1_i32 : (i32) -> index
%c1024_i32 = arith.constant 1024 : i32
%3 = fir.convert %c1024_i32 : (i32) -> index
%c1 = arith.constant 1 : index
%4 = fir.convert %2 : (index) -> i32
%5:2 = fir.do_loop %arg0 = %2 to %3 step %c1 iter_args(%arg1 = %4) -> (index, i32) {
fir.store %arg1 to %1 : !fir.ref<i32>
%6 = fir.load %1 : !fir.ref<i32>
%7 = fir.load %1 : !fir.ref<i32>
%8 = fir.convert %7 : (i32) -> i64
%c1_i64 = arith.constant 1 : i64
%9 = arith.subi %8, %c1_i64 : i64
%10 = fir.coordinate_of %0, %9 : (!fir.ref<!fir.array<1024xi32>>, i64) -> !fir.ref<i32>
fir.store %6 to %10 : !fir.ref<i32>
%11 = arith.addi %arg0, %c1 : index
%12 = fir.convert %c1 : (index) -> i32
%13 = fir.load %1 : !fir.ref<i32>
%14 = arith.addi %13, %12 : i32
fir.result %11, %14 : index, i32
}
fir.store %5#1 to %1 : !fir.ref<i32>
omp.terminator
}
return
}

// CHECK-LABEL: llvm.func @_QPopenmp_target_data_region() {
// CHECK: %[[VAL_0:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[VAL_1:.*]] = llvm.alloca %[[VAL_0]] x !llvm.array<1024 x i32> {bindc_name = "a", in_type = !fir.array<1024xi32>, operand_segment_sizes = array<i32: 0, 0>, uniq_name = "_QFopenmp_target_data_regionEa"} : (i64) -> !llvm.ptr<array<1024 x i32>>
// CHECK: %[[VAL_2:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[VAL_3:.*]] = llvm.alloca %[[VAL_2]] x i32 {bindc_name = "i", in_type = i32, operand_segment_sizes = array<i32: 0, 0>, uniq_name = "_QFopenmp_target_data_regionEi"} : (i64) -> !llvm.ptr<i32>
// CHECK: omp.target_data map((tofrom -> %[[VAL_1]] : !llvm.ptr<array<1024 x i32>>)) {
// CHECK: %[[VAL_4:.*]] = llvm.mlir.constant(1 : i32) : i32
// CHECK: %[[VAL_5:.*]] = llvm.sext %[[VAL_4]] : i32 to i64
// CHECK: %[[VAL_6:.*]] = llvm.mlir.constant(1024 : i32) : i32
// CHECK: %[[VAL_7:.*]] = llvm.sext %[[VAL_6]] : i32 to i64
// CHECK: %[[VAL_8:.*]] = llvm.mlir.constant(1 : index) : i64
// CHECK: %[[VAL_9:.*]] = llvm.trunc %[[VAL_5]] : i64 to i32
// CHECK: %[[VAL_10:.*]] = llvm.sub %[[VAL_7]], %[[VAL_5]] : i64
// CHECK: %[[VAL_11:.*]] = llvm.add %[[VAL_10]], %[[VAL_8]] : i64
// CHECK: llvm.br ^bb1(%[[VAL_5]], %[[VAL_9]], %[[VAL_11]] : i64, i32, i64)
// CHECK: ^bb1(%[[VAL_12:.*]]: i64, %[[VAL_13:.*]]: i32, %[[VAL_14:.*]]: i64):
// CHECK: %[[VAL_15:.*]] = llvm.mlir.constant(0 : index) : i64
// CHECK: %[[VAL_16:.*]] = llvm.icmp "sgt" %[[VAL_14]], %[[VAL_15]] : i64
// CHECK: llvm.cond_br %[[VAL_16]], ^bb2, ^bb3
// CHECK: ^bb2:
// CHECK: llvm.store %[[VAL_13]], %[[VAL_3]] : !llvm.ptr<i32>
// CHECK: %[[VAL_17:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr<i32>
// CHECK: %[[VAL_18:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr<i32>
// CHECK: %[[VAL_19:.*]] = llvm.sext %[[VAL_18]] : i32 to i64
// CHECK: %[[VAL_20:.*]] = llvm.mlir.constant(1 : i64) : i64
// CHECK: %[[VAL_21:.*]] = llvm.sub %[[VAL_19]], %[[VAL_20]] : i64
// CHECK: %[[VAL_22:.*]] = llvm.getelementptr %[[VAL_1]][0, %[[VAL_21]]] : (!llvm.ptr<array<1024 x i32>>, i64) -> !llvm.ptr<i32>
// CHECK: llvm.store %[[VAL_17]], %[[VAL_22]] : !llvm.ptr<i32>
// CHECK: %[[VAL_23:.*]] = llvm.add %[[VAL_12]], %[[VAL_8]] : i64
// CHECK: %[[VAL_24:.*]] = llvm.trunc %[[VAL_8]] : i64 to i32
// CHECK: %[[VAL_25:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr<i32>
// CHECK: %[[VAL_26:.*]] = llvm.add %[[VAL_25]], %[[VAL_24]] : i32
// CHECK: %[[VAL_27:.*]] = llvm.add %[[VAL_12]], %[[VAL_8]] : i64
// CHECK: %[[VAL_28:.*]] = llvm.mlir.constant(1 : index) : i64
// CHECK: %[[VAL_29:.*]] = llvm.sub %[[VAL_14]], %[[VAL_28]] : i64
// CHECK: llvm.br ^bb1(%[[VAL_27]], %[[VAL_26]], %[[VAL_29]] : i64, i32, i64)
// CHECK: ^bb3:
// CHECK: llvm.store %[[VAL_13]], %[[VAL_3]] : !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
55 changes: 27 additions & 28 deletions mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,24 +151,23 @@ struct LegalizeDataOpForLLVMTranslation : public ConvertOpToLLVMPattern<Op> {

void mlir::configureOpenMPToLLVMConversionLegality(
ConversionTarget &target, LLVMTypeConverter &typeConverter) {
target.addDynamicallyLegalOp<mlir::omp::AtomicUpdateOp, mlir::omp::CriticalOp,
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::DataOp,
mlir::omp::EnterDataOp, mlir::omp::ExitDataOp>(
[&](Operation *op) {
return typeConverter.isLegal(op->getOperandTypes()) &&
typeConverter.isLegal(op->getResultTypes());
});
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());
});
target
.addDynamicallyLegalOp<mlir::omp::AtomicReadOp, mlir::omp::AtomicWriteOp,
mlir::omp::FlushOp, mlir::omp::ThreadprivateOp,
mlir::omp::EnterDataOp, mlir::omp::ExitDataOp>(
[&](Operation *op) {
return typeConverter.isLegal(op->getOperandTypes()) &&
typeConverter.isLegal(op->getResultTypes());
});
target.addDynamicallyLegalOp<mlir::omp::ReductionOp>([&](Operation *op) {
return typeConverter.isLegal(op->getOperandTypes());
});
Expand All @@ -177,20 +176,20 @@ void mlir::configureOpenMPToLLVMConversionLegality(
void mlir::populateOpenMPToLLVMConversionPatterns(LLVMTypeConverter &converter,
RewritePatternSet &patterns) {
patterns.add<
ReductionOpConversion, RegionOpConversion<omp::CriticalOp>,
RegionOpConversion<omp::MasterOp>, ReductionOpConversion,
RegionOpConversion<omp::MasterOp>, RegionOpConversion<omp::ParallelOp>,
RegionOpConversion<omp::WsLoopOp>, RegionOpConversion<omp::SectionsOp>,
RegionOpConversion<omp::SectionOp>, RegionOpConversion<omp::SimdLoopOp>,
RegionOpConversion<omp::SingleOp>, RegionOpConversion<omp::TaskOp>,
LegalizeDataOpForLLVMTranslation<omp::DataOp>,
LegalizeDataOpForLLVMTranslation<omp::EnterDataOp>,
LegalizeDataOpForLLVMTranslation<omp::ExitDataOp>, ReductionOpConversion,
RegionOpConversion<omp::CriticalOp>, RegionOpConversion<omp::MasterOp>,
ReductionOpConversion, RegionOpConversion<omp::MasterOp>,
RegionOpConversion<omp::ParallelOp>, RegionOpConversion<omp::WsLoopOp>,
RegionOpConversion<omp::SectionsOp>, RegionOpConversion<omp::SectionOp>,
RegionOpConversion<omp::SimdLoopOp>, RegionOpConversion<omp::SingleOp>,
RegionOpConversion<omp::TaskOp>, RegionOpConversion<omp::DataOp>,
RegionLessOpWithVarOperandsConversion<omp::AtomicReadOp>,
RegionLessOpWithVarOperandsConversion<omp::AtomicWriteOp>,
RegionOpWithVarOperandsConversion<omp::AtomicUpdateOp>,
RegionLessOpWithVarOperandsConversion<omp::FlushOp>,
RegionLessOpWithVarOperandsConversion<omp::ThreadprivateOp>,
LegalizeDataOpForLLVMTranslation<omp::DataOp>,
LegalizeDataOpForLLVMTranslation<omp::EnterDataOp>,
LegalizeDataOpForLLVMTranslation<omp::ExitDataOp>>(converter);
RegionLessOpWithVarOperandsConversion<omp::ThreadprivateOp>>(converter);
}

namespace {
Expand Down
20 changes: 20 additions & 0 deletions mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,26 @@ llvm.func @_QPomp_target_data(%a : !llvm.ptr<i32>, %b : !llvm.ptr<i32>, %c : !ll

// -----

// CHECK-LABEL: @_QPomp_target_data_region
// CHECK: (%[[ARG0:.*]]: !llvm.ptr<array<1024 x i32>>, %[[ARG1:.*]]: !llvm.ptr<i32>) {
// CHECK: omp.target_data map((tofrom -> %[[ARG0]] : !llvm.ptr<array<1024 x i32>>)) {
// CHECK: %[[VAL_1:.*]] = llvm.mlir.constant(10 : i32) : i32
// CHECK: llvm.store %[[VAL_1]], %[[ARG1]] : !llvm.ptr<i32>
// CHECK: omp.terminator
// CHECK: }
// CHECK: llvm.return

llvm.func @_QPomp_target_data_region(%a : !llvm.ptr<array<1024 x i32>>, %i : !llvm.ptr<i32>) {
omp.target_data 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 af694df

Please sign in to comment.