[flang-commits] [flang] c6ac937 - [Flang] Add OpenMP Conversion patterns

Kiran Chandramohan via flang-commits flang-commits at lists.llvm.org
Mon Mar 21 07:23:15 PDT 2022


Author: Kiran Chandramohan
Date: 2022-03-21T14:23:02Z
New Revision: c6ac937091249582fce14f02920a4bc94049e713

URL: https://github.com/llvm/llvm-project/commit/c6ac937091249582fce14f02920a4bc94049e713
DIFF: https://github.com/llvm/llvm-project/commit/c6ac937091249582fce14f02920a4bc94049e713.diff

LOG: [Flang] Add OpenMP Conversion patterns

This patch adds the OpenMP conversion patterns to the FIR to LLVM
dialect lowering pass in Codegen. Appropriate legalization
conditions are also added. This ensures that a mix of FIR and OpenMP
dialects can be lowered to LLVM and OpenMP  dialects. Also adds two
tests.

This is part of the upstreaming effort from the fir-dev branch in [1].
[1] https://github.com/flang-compiler/f18-llvm-project

Reviewed By: clementval, peixin

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

Co-authored-by: Sourabh Singh Tomar <SourabhSingh.Tomar at amd.com>
Co-authored-by: Eric Schweitz <eschweitz at nvidia.com>

Added: 
    flang/test/Fir/convert-to-llvm-openmp-and-fir.fir

Modified: 
    flang/lib/Optimizer/CodeGen/CodeGen.cpp

Removed: 
    


################################################################################
diff  --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 55da2d93d3c10..5f65eda63ff8c 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -23,6 +23,7 @@
 #include "mlir/Conversion/ControlFlowToLLVM/ControlFlowToLLVM.h"
 #include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h"
 #include "mlir/Conversion/LLVMCommon/Pattern.h"
+#include "mlir/Conversion/OpenMPToLLVM/ConvertOpenMPToLLVM.h"
 #include "mlir/IR/BuiltinTypes.h"
 #include "mlir/IR/Matchers.h"
 #include "mlir/Pass/Pass.h"
@@ -3328,12 +3329,21 @@ class FIRToLLVMLowering : public fir::FIRToLLVMLoweringBase<FIRToLLVMLowering> {
         XEmboxOpConversion, XReboxOpConversion, ZeroOpConversion>(typeConverter,
                                                                   options);
     mlir::populateFuncToLLVMConversionPatterns(typeConverter, pattern);
+    mlir::populateOpenMPToLLVMConversionPatterns(typeConverter, pattern);
     mlir::arith::populateArithmeticToLLVMConversionPatterns(typeConverter,
                                                             pattern);
     mlir::cf::populateControlFlowToLLVMConversionPatterns(typeConverter,
                                                           pattern);
     mlir::ConversionTarget target{*context};
     target.addLegalDialect<mlir::LLVM::LLVMDialect>();
+    // The OpenMP dialect is legal for Operations without regions, for those
+    // which contains regions it is legal if the region contains only the
+    // LLVM dialect.
+    target.addDynamicallyLegalOp<mlir::omp::ParallelOp, mlir::omp::WsLoopOp,
+                                 mlir::omp::MasterOp>([&](Operation *op) {
+      return typeConverter.isLegal(&op->getRegion(0));
+    });
+    target.addLegalDialect<mlir::omp::OpenMPDialect>();
 
     // required NOPs for applying a full conversion
     target.addLegalOp<mlir::ModuleOp>();

diff  --git a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
new file mode 100644
index 0000000000000..f675b668513f3
--- /dev/null
+++ b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
@@ -0,0 +1,71 @@
+// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=aarch64-unknown-linux-gnu" %s | FileCheck %s
+
+func @_QPsb1(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "arr"}) {
+  %c1_i64 = arith.constant 1 : i64
+  %c1_i32 = arith.constant 1 : i32
+  %0 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsbEi"}
+  omp.parallel  {
+    %1 = fir.alloca i32 {adapt.valuebyref, pinned}
+    %2 = fir.load %arg0 : !fir.ref<i32>
+    omp.wsloop (%arg2) : i32 = (%c1_i32) to (%2) inclusive step (%c1_i32) nowait  {
+      fir.store %arg2 to %1 : !fir.ref<i32>
+      %3 = fir.load %1 : !fir.ref<i32>
+      %4 = fir.convert %3 : (i32) -> i64
+      %5 = arith.subi %4, %c1_i64 : i64
+      %6 = fir.coordinate_of %arg1, %5 : (!fir.ref<!fir.array<?xi32>>, i64) -> !fir.ref<i32>
+      fir.store %3 to %6 : !fir.ref<i32>
+      omp.yield
+    }
+    omp.terminator
+  }
+  return
+}
+
+// CHECK-LABEL:  _QPsb1
+// CHECK-SAME: %[[N_REF:.*]]: !llvm.ptr<i32> {fir.bindc_name = "n"}, %[[ARR_REF:.*]]: !llvm.ptr<i32> {fir.bindc_name = "arr"}) {
+// CHECK:    %[[ONE_1:.*]] = llvm.mlir.constant(1 : i64) : i64
+// CHECK:    %[[ONE_2:.*]] = llvm.mlir.constant(1 : i32) : i32
+// CHECK: omp.parallel   {
+// CHECK:      %[[ONE_3:.*]] = llvm.mlir.constant(1 : i64) : i64
+// CHECK:      %[[I_VAR:.*]] = llvm.alloca %[[ONE_3]] x i32 {adapt.valuebyref, in_type = i32, operand_segment_sizes = dense<0> : vector<2xi32>, pinned} : (i64) -> !llvm.ptr<i32>
+// CHECK:      %[[N:.*]] = llvm.load %[[N_REF]] : !llvm.ptr<i32>
+// CHECK: omp.wsloop (%[[I:.*]]) : i32 = (%[[ONE_2]]) to (%[[N]]) inclusive step (%[[ONE_2]]) nowait  {
+// CHECK:   llvm.store %[[I]], %[[I_VAR]] : !llvm.ptr<i32>
+// CHECK:   %[[I1:.*]] = llvm.load %[[I_VAR]] : !llvm.ptr<i32>
+// CHECK:   %[[I1_EXT:.*]] = llvm.sext %[[I1]] : i32 to i64
+// CHECK:   %[[I_CSTYLE:.*]] = llvm.sub %[[I1_EXT]], %[[ONE_1]]  : i64
+// CHECK:   %[[ARR_I_REF:.*]] = llvm.getelementptr %[[ARR_REF]][%[[I_CSTYLE]]] : (!llvm.ptr<i32>, i64) -> !llvm.ptr<i32>
+// CHECK:   llvm.store %[[I1]], %[[ARR_I_REF]] : !llvm.ptr<i32>
+// CHECK: omp.yield
+// CHECK: }
+// CHECK: omp.terminator
+// CHECK: }
+// CHECK: llvm.return
+// CHECK: }
+
+// -----
+
+func @_QPsb2(%arg0: !fir.ref<i32> {fir.bindc_name = "x"}, %arg1: !fir.ref<i32> {fir.bindc_name = "n"}) {
+  omp.parallel  {
+    omp.master  {
+      %0 = fir.load %arg1 : !fir.ref<i32>
+      fir.store %0 to %arg0 : !fir.ref<i32>
+      omp.terminator
+    }
+    omp.terminator
+  }
+  return
+}
+
+// CHECK-LABEL: _QPsb2
+// CHECK-SAME: %[[X_REF:.*]]: !llvm.ptr<i32> {fir.bindc_name = "x"}, %[[N_REF:.*]]: !llvm.ptr<i32> {fir.bindc_name = "n"}) {
+// CHECK: omp.parallel   {
+// CHECK:   omp.master {
+// CHECK:     %[[N:.*]] = llvm.load %[[N_REF]] : !llvm.ptr<i32>
+// CHECK:     llvm.store %[[N]], %[[X_REF]] : !llvm.ptr<i32>
+// CHECK:     omp.terminator
+// CHECK:   }
+// CHECK:   omp.terminator
+// CHECK: }
+// CHECK: llvm.return
+// CHECK: }


        


More information about the flang-commits mailing list