[MLIR][OpenMP] Add conversion support from FIR to LLVM Dialect for OMP Target Data...
authorAkash Banerjee <Akash.Banerjee@amd.com>
Thu, 23 Feb 2023 16:58:04 +0000 (16:58 +0000)
committerAkash Banerjee <Akash.Banerjee@amd.com>
Thu, 23 Feb 2023 17:01:20 +0000 (17:01 +0000)
This enables conversion of OpenMP Target Data op with region from FIR Dialect to LLVM IR Dialect.

Differential Revision: https://reviews.llvm.org/D144380

flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
mlir/lib/Conversion/OpenMPToLLVM/OpenMPToLLVM.cpp
mlir/test/Conversion/OpenMPToLLVM/convert-to-llvmir.mlir

index 159be7a..3a848d1 100644 (file)
@@ -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"}) {
@@ -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"}
@@ -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"}
index d2eecf2..4e38aaf 100644 (file)
@@ -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());
   });
@@ -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 {
index 220dd86..9db9e49 100644 (file)
@@ -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