[flang-commits] [flang] 1f734b0 - [flang][OpenMP] Handle private/firstprivate clauses on sections construct

Nimish Mishra via flang-commits flang-commits at lists.llvm.org
Sun Sep 4 07:50:44 PDT 2022


Author: Nimish Mishra
Date: 2022-09-05T01:49:30+05:30
New Revision: 1f734b0d1731bf15fe2501ec04f65658ad4a87a6

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

LOG: [flang][OpenMP] Handle private/firstprivate clauses on sections construct

This patch adds private/firstprivate support for sections construct. For
a source like the following:

```
!$omp sections private(x) firstprivate(y)
    !$omp section
        <block of code>
    !$omp section
        <block of code>
!$omp end sections
```
...privatization proceeds to privatize `x` and `y` accordingly
inside each of the generated `omp.section` operations.

Reviewed By: peixin

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

Added: 
    

Modified: 
    flang/lib/Lower/OpenMP.cpp
    flang/test/Lower/OpenMP/sections.f90

Removed: 
    


################################################################################
diff  --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp
index 19ff2d738a4ad..fe56621cf88d7 100644
--- a/flang/lib/Lower/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP.cpp
@@ -201,7 +201,10 @@ static bool privatizeVars(Op &op, Fortran::lower::AbstractConverter &converter,
   }
 
   bool needBarrier = false;
-  firOpBuilder.setInsertionPointToStart(firOpBuilder.getAllocaBlock());
+  if (mlir::isa<mlir::omp::SectionOp>(op))
+    firOpBuilder.setInsertionPointToStart(&op.getRegion().back());
+  else
+    firOpBuilder.setInsertionPointToStart(firOpBuilder.getAllocaBlock());
   for (auto sym : privatizedSymbols) {
     privatizeSymbol(converter, sym, lastPrivBlock);
     if (sym->test(Fortran::semantics::Symbol::Flag::OmpFirstPrivate) &&
@@ -1326,12 +1329,28 @@ genOMP(Fortran::lower::AbstractConverter &converter,
 
   auto &firOpBuilder = converter.getFirOpBuilder();
   auto currentLocation = converter.getCurrentLocation();
+  const Fortran::parser::OpenMPConstruct *parentOmpConstruct =
+      eval.parentConstruct->getIf<Fortran::parser::OpenMPConstruct>();
+  assert(parentOmpConstruct &&
+         "No enclosing parent OpenMPConstruct on SECTION construct");
+  const Fortran::parser::OpenMPSectionsConstruct *sectionsConstruct =
+      std::get_if<Fortran::parser::OpenMPSectionsConstruct>(
+          &parentOmpConstruct->u);
+  assert(sectionsConstruct && "SECTION construct must have parent"
+                              "SECTIONS construct");
+  const Fortran::parser::OmpClauseList &sectionsClauseList =
+      std::get<Fortran::parser::OmpClauseList>(
+          std::get<Fortran::parser::OmpBeginSectionsDirective>(
+              sectionsConstruct->t)
+              .t);
+  // Currently only private/firstprivate clause is handled, and
+  // all privatization is done within `omp.section` operations.
   mlir::omp::SectionOp sectionOp =
       firOpBuilder.create<mlir::omp::SectionOp>(currentLocation);
-  createBodyOfOp<omp::SectionOp>(sectionOp, converter, currentLocation, eval);
+  createBodyOfOp<omp::SectionOp>(sectionOp, converter, currentLocation, eval,
+                                 &sectionsClauseList);
 }
 
-// TODO: Add support for reduction
 static void
 genOMP(Fortran::lower::AbstractConverter &converter,
        Fortran::lower::pft::Evaluation &eval,

diff  --git a/flang/test/Lower/OpenMP/sections.f90 b/flang/test/Lower/OpenMP/sections.f90
index a882308479aed..3a856487beb1a 100644
--- a/flang/test/Lower/OpenMP/sections.f90
+++ b/flang/test/Lower/OpenMP/sections.f90
@@ -4,44 +4,49 @@
 
 !CHECK: func @_QQmain() {
 !CHECK:   %[[COUNT:.*]] = fir.address_of(@_QFEcount) : !fir.ref<i32>
-!CHECK:   %[[DOUBLE_COUNT:.*]] = fir.address_of(@_QFEdouble_count) : !fir.ref<i32>
 !CHECK:   %[[ETA:.*]] = fir.alloca f32 {bindc_name = "eta", uniq_name = "_QFEeta"}
 !CHECK:   %[[CONST_1:.*]] = arith.constant 1 : i32
 !CHECK:   omp.sections allocate(%[[CONST_1]] : i32 -> %0 : !fir.ref<i32>)  {
 !CHECK:     omp.section {
-!CHECK:       {{.*}} = arith.constant 5 : i32
-!CHECK:       fir.store {{.*}} to {{.*}} : !fir.ref<i32>
-!CHECK:       {{.*}} = fir.load %[[COUNT]] : !fir.ref<i32>
-!CHECK:       {{.*}} = fir.load %[[DOUBLE_COUNT]] : !fir.ref<i32>
-!CHECK:       {{.*}} = arith.muli {{.*}}, {{.*}} : i32
-!CHECK:       {{.*}} = fir.convert {{.*}} : (i32) -> f32
-!CHECK:       fir.store {{.*}} to %[[ETA]] : !fir.ref<f32>
+!CHECK:       %[[PRIVATE_ETA:.*]] = fir.alloca f32 {bindc_name = "eta", pinned, uniq_name = "_QFEeta"}
+!CHECK:       %[[PRIVATE_DOUBLE_COUNT:.*]] = fir.alloca i32 {bindc_name = "double_count", pinned, uniq_name = "_QFEdouble_count"} 
+!CHECK:       %[[const:.*]] = arith.constant 5 : i32
+!CHECK:       fir.store %[[const]] to %[[COUNT]] : !fir.ref<i32>
+!CHECK:       %[[temp_count:.*]] = fir.load %[[COUNT]] : !fir.ref<i32>
+!CHECK:       %[[temp_double_count:.*]] = fir.load %[[PRIVATE_DOUBLE_COUNT]] : !fir.ref<i32>
+!CHECK:       %[[result:.*]] = arith.muli %[[temp_count]], %[[temp_double_count]] : i32
+!CHECK:       {{.*}} = fir.convert %[[result]] : (i32) -> f32
+!CHECK:       fir.store {{.*}} to %[[PRIVATE_ETA]] : !fir.ref<f32>
 !CHECK:       omp.terminator
 !CHECK:     }
 !CHECK:     omp.section {
-!CHECK:       {{.*}} = fir.load %[[DOUBLE_COUNT]] : !fir.ref<i32>
-!CHECK:       {{.*}} = arith.constant 1 : i32
-!CHECK:       {{.*}} = arith.addi {{.*}} : i32
-!CHECK:       fir.store {{.*}} to %[[DOUBLE_COUNT]] : !fir.ref<i32>
+!CHECK:       %[[PRIVATE_ETA:.*]] = fir.alloca f32 {bindc_name = "eta", pinned, uniq_name = "_QFEeta"}
+!CHECK:       %[[PRIVATE_DOUBLE_COUNT:.*]] = fir.alloca i32 {bindc_name = "double_count", pinned, uniq_name = "_QFEdouble_count"} 
+!CHECK:       %[[temp:.*]] = fir.load %[[PRIVATE_DOUBLE_COUNT]] : !fir.ref<i32>
+!CHECK:       %[[const:.*]] = arith.constant 1 : i32
+!CHECK:       %[[result:.*]] = arith.addi %[[temp]], %[[const]] : i32
+!CHECK:       fir.store %[[result]] to %[[PRIVATE_DOUBLE_COUNT]] : !fir.ref<i32>
 !CHECK:       omp.terminator
 !CHECK:     }
 !CHECK:     omp.section {
-!CHECK:       {{.*}} = fir.load %[[ETA]] : !fir.ref<f32>
-!CHECK:       {{.*}} = arith.constant 7.000000e+00 : f32
-!CHECK:       {{.*}} = arith.subf {{.*}} : f32
-!CHECK:       fir.store {{.*}} to %[[ETA]] : !fir.ref<f32>
+!CHECK:       %[[PRIVATE_ETA:.*]] = fir.alloca f32 {bindc_name = "eta", pinned, uniq_name = "_QFEeta"}
+!CHECK:       %[[PRIVATE_DOUBLE_COUNT:.*]] = fir.alloca i32 {bindc_name = "double_count", pinned, uniq_name = "_QFEdouble_count"} 
+!CHECK:       %[[temp:.*]] = fir.load %[[PRIVATE_ETA]] : !fir.ref<f32>
+!CHECK:       %[[const:.*]] = arith.constant 7.000000e+00 : f32
+!CHECK:       %[[result:.*]] = arith.subf %[[temp]], %[[const]] : f32
+!CHECK:       fir.store %[[result]] to %[[PRIVATE_ETA]] : !fir.ref<f32>
 !CHECK:       {{.*}} = fir.load %[[COUNT]] : !fir.ref<i32>
-!CHECK:       {{.*}} = fir.convert {{.*}} : (i32) -> f32
-!CHECK:       {{.*}} = fir.load %[[ETA]] : !fir.ref<f32>
-!CHECK:       {{.*}} = arith.mulf {{.*}}, {{.*}} : f32
-!CHECK:       {{.*}} = fir.convert {{.*}} : (f32) -> i32
-!CHECK:       fir.store {{.*}} to %[[COUNT]] : !fir.ref<i32>
+!CHECK:       %[[temp_count:.*]] = fir.convert {{.*}} : (i32) -> f32
+!CHECK:       %[[temp_eta:.*]] = fir.load %[[PRIVATE_ETA]] : !fir.ref<f32>
+!CHECK:       {{.*}} = arith.mulf %[[temp_count]], %[[temp_eta]] : f32
+!CHECK:       %[[result:.*]] = fir.convert {{.*}} : (f32) -> i32
+!CHECK:       fir.store %[[result]] to %[[COUNT]] : !fir.ref<i32>
 !CHECK:       {{.*}} = fir.load %[[COUNT]] : !fir.ref<i32>
-!CHECK:       {{.*}} = fir.convert {{.*}} : (i32) -> f32
-!CHECK:       {{.*}} = fir.load %[[ETA]] : !fir.ref<f32>
-!CHECK:       {{.*}} = arith.subf {{.*}}, {{.*}} : f32
-!CHECK:       {{.*}} = fir.convert {{.*}} : (f32) -> i32
-!CHECK:       fir.store {{.*}} to %[[DOUBLE_COUNT]] : !fir.ref<i32>
+!CHECK:       %[[temp_count:.*]] = fir.convert {{.*}} : (i32) -> f32
+!CHECK:       %[[temp_eta:.*]] = fir.load %[[PRIVATE_ETA]] : !fir.ref<f32>
+!CHECK:       {{.*}} = arith.subf %[[temp_count]], %[[temp_eta]] : f32
+!CHECK:       %[[result:.*]] = fir.convert {{.*}} : (f32) -> i32
+!CHECK:       fir.store %[[result]] to %[[PRIVATE_DOUBLE_COUNT]] : !fir.ref<i32>
 !CHECK:       omp.terminator
 !CHECK:     }
 !CHECK:     omp.terminator
@@ -74,6 +79,9 @@ end program sample
 !CHECK: func @_QPfirstprivate(%[[ARG:.*]]: !fir.ref<f32> {fir.bindc_name = "alpha"}) {
 !CHECK:   omp.sections {
 !CHECK:     omp.section  {
+!CHECK:         %[[PRIVATE_ALPHA:.*]] = fir.alloca f32 {bindc_name = "alpha", pinned, uniq_name = "_QFfirstprivateEalpha"}
+!CHECK:         %[[temp:.*]] = fir.load %[[ARG]] : !fir.ref<f32>
+!CHECK:         fir.store %[[temp]] to %[[PRIVATE_ALPHA]] : !fir.ref<f32>
 !CHECK:       omp.terminator
 !CHECK:     }
 !CHECK:     omp.terminator


        


More information about the flang-commits mailing list