[flang-commits] [flang] 88d5289 - [flang][OpenMP] Added lowering support for sections construct
Nimish Mishra via flang-commits
flang-commits at lists.llvm.org
Thu Mar 24 00:58:45 PDT 2022
Author: Nimish Mishra
Date: 2022-03-24T13:29:38+05:30
New Revision: 88d5289fc69d24e8490a064c87228d68c53e5d9c
URL: https://github.com/llvm/llvm-project/commit/88d5289fc69d24e8490a064c87228d68c53e5d9c
DIFF: https://github.com/llvm/llvm-project/commit/88d5289fc69d24e8490a064c87228d68c53e5d9c.diff
LOG: [flang][OpenMP] Added lowering support for sections construct
This patch adds lowering support (from PFT to FIR) for sections construct
Reviewed By: kiranchandramohan
Differential Revision: https://reviews.llvm.org/D122302
Added:
flang/test/Lower/OpenMP/sections.f90
Modified:
flang/lib/Lower/OpenMP.cpp
Removed:
################################################################################
diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp
index 8aeca2769bde1..bdecfeee968bd 100644
--- a/flang/lib/Lower/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP.cpp
@@ -96,6 +96,38 @@ static void genOMP(Fortran::lower::AbstractConverter &converter,
}
}
+static void
+genAllocateClause(Fortran::lower::AbstractConverter &converter,
+ const Fortran::parser::OmpAllocateClause &ompAllocateClause,
+ SmallVector<Value> &allocatorOperands,
+ SmallVector<Value> &allocateOperands) {
+ auto &firOpBuilder = converter.getFirOpBuilder();
+ auto currentLocation = converter.getCurrentLocation();
+ Fortran::lower::StatementContext stmtCtx;
+
+ mlir::Value allocatorOperand;
+ const Fortran::parser::OmpObjectList &ompObjectList =
+ std::get<Fortran::parser::OmpObjectList>(ompAllocateClause.t);
+ const auto &allocatorValue =
+ std::get<std::optional<Fortran::parser::OmpAllocateClause::Allocator>>(
+ ompAllocateClause.t);
+ // Check if allocate clause has allocator specified. If so, add it
+ // to list of allocators, otherwise, add default allocator to
+ // list of allocators.
+ if (allocatorValue) {
+ allocatorOperand = fir::getBase(converter.genExprValue(
+ *Fortran::semantics::GetExpr(allocatorValue->v), stmtCtx));
+ allocatorOperands.insert(allocatorOperands.end(), ompObjectList.v.size(),
+ allocatorOperand);
+ } else {
+ allocatorOperand = firOpBuilder.createIntegerConstant(
+ currentLocation, firOpBuilder.getI32Type(), 1);
+ allocatorOperands.insert(allocatorOperands.end(), ompObjectList.v.size(),
+ allocatorOperand);
+ }
+ genObjectList(ompObjectList, converter, allocateOperands);
+}
+
static void
genOMP(Fortran::lower::AbstractConverter &converter,
Fortran::lower::pft::Evaluation &eval,
@@ -262,6 +294,57 @@ genOMP(Fortran::lower::AbstractConverter &converter,
createBodyOfOp<omp::CriticalOp>(criticalOp, firOpBuilder, currentLocation);
}
+static void
+genOMP(Fortran::lower::AbstractConverter &converter,
+ Fortran::lower::pft::Evaluation &eval,
+ const Fortran::parser::OpenMPSectionConstruct §ionConstruct) {
+
+ auto &firOpBuilder = converter.getFirOpBuilder();
+ auto currentLocation = converter.getCurrentLocation();
+ mlir::omp::SectionOp sectionOp =
+ firOpBuilder.create<mlir::omp::SectionOp>(currentLocation);
+ createBodyOfOp<omp::SectionOp>(sectionOp, firOpBuilder, currentLocation);
+}
+
+// TODO: Add support for reduction
+static void
+genOMP(Fortran::lower::AbstractConverter &converter,
+ Fortran::lower::pft::Evaluation &eval,
+ const Fortran::parser::OpenMPSectionsConstruct §ionsConstruct) {
+ auto &firOpBuilder = converter.getFirOpBuilder();
+ auto currentLocation = converter.getCurrentLocation();
+ SmallVector<Value> reductionVars, allocateOperands, allocatorOperands;
+ mlir::UnitAttr noWaitClauseOperand;
+ const auto §ionsClauseList = std::get<Fortran::parser::OmpClauseList>(
+ std::get<Fortran::parser::OmpBeginSectionsDirective>(sectionsConstruct.t)
+ .t);
+ for (const Fortran::parser::OmpClause &clause : sectionsClauseList.v) {
+ if (std::get_if<Fortran::parser::OmpClause::Reduction>(&clause.u)) {
+ TODO(currentLocation, "OMPC_Reduction");
+ } else if (const auto &allocateClause =
+ std::get_if<Fortran::parser::OmpClause::Allocate>(
+ &clause.u)) {
+ genAllocateClause(converter, allocateClause->v, allocatorOperands,
+ allocateOperands);
+ }
+ }
+ const auto &endSectionsClauseList =
+ std::get<Fortran::parser::OmpEndSectionsDirective>(sectionsConstruct.t);
+ const auto &clauseList =
+ std::get<Fortran::parser::OmpClauseList>(endSectionsClauseList.t);
+ for (const auto &clause : clauseList.v) {
+ if (std::get_if<Fortran::parser::OmpClause::Nowait>(&clause.u)) {
+ noWaitClauseOperand = firOpBuilder.getUnitAttr();
+ }
+ }
+
+ mlir::omp::SectionsOp sectionsOp = firOpBuilder.create<mlir::omp::SectionsOp>(
+ currentLocation, reductionVars, /*reductions = */ nullptr,
+ allocateOperands, allocatorOperands, noWaitClauseOperand);
+
+ createBodyOfOp<omp::SectionsOp>(sectionsOp, firOpBuilder, currentLocation);
+}
+
void Fortran::lower::genOpenMPConstruct(
Fortran::lower::AbstractConverter &converter,
Fortran::lower::pft::Evaluation &eval,
@@ -275,10 +358,10 @@ void Fortran::lower::genOpenMPConstruct(
},
[&](const Fortran::parser::OpenMPSectionsConstruct
§ionsConstruct) {
- TODO(converter.getCurrentLocation(), "OpenMPSectionsConstruct");
+ genOMP(converter, eval, sectionsConstruct);
},
[&](const Fortran::parser::OpenMPSectionConstruct §ionConstruct) {
- TODO(converter.getCurrentLocation(), "OpenMPSectionConstruct");
+ genOMP(converter, eval, sectionConstruct);
},
[&](const Fortran::parser::OpenMPLoopConstruct &loopConstruct) {
TODO(converter.getCurrentLocation(), "OpenMPLoopConstruct");
diff --git a/flang/test/Lower/OpenMP/sections.f90 b/flang/test/Lower/OpenMP/sections.f90
new file mode 100644
index 0000000000000..f18babcd31a05
--- /dev/null
+++ b/flang/test/Lower/OpenMP/sections.f90
@@ -0,0 +1,180 @@
+! This test checks the lowering of OpenMP sections construct with several clauses present
+
+! RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | FileCheck %s --check-prefix="FIRDialect"
+! RUN: %flang_fc1 -emit-fir -fopenmp %s -o - | fir-opt --fir-to-llvm-ir | FileCheck %s --check-prefix="LLVMDialect"
+! TODO before (%flang_fc1 -emit-fir -fopenmp %s -o - | fir-opt --fir-to-llvm-ir | tco | FileCheck %s --check-prefix="LLVMIR"):
+! ensure allocate clause lowering
+
+!FIRDialect: func @_QQmain() {
+!FIRDialect: %[[COUNT:.*]] = fir.address_of(@_QFEcount) : !fir.ref<i32>
+!FIRDialect: %[[DOUBLE_COUNT:.*]] = fir.address_of(@_QFEdouble_count) : !fir.ref<i32>
+!FIRDialect: %[[ETA:.*]] = fir.alloca f32 {bindc_name = "eta", uniq_name = "_QFEeta"}
+!FIRDialect: %[[CONST_1:.*]] = arith.constant 1 : i32
+!FIRDialect: omp.sections allocate(%[[CONST_1]] : i32 -> %0 : !fir.ref<i32>) {
+!FIRDialect: omp.section {
+!FIRDialect: {{.*}} = arith.constant 5 : i32
+!FIRDialect: fir.store {{.*}} to {{.*}} : !fir.ref<i32>
+!FIRDialect: {{.*}} = fir.load %[[COUNT]] : !fir.ref<i32>
+!FIRDialect: {{.*}} = fir.load %[[DOUBLE_COUNT]] : !fir.ref<i32>
+!FIRDialect: {{.*}} = arith.muli {{.*}}, {{.*}} : i32
+!FIRDialect: {{.*}} = fir.convert {{.*}} : (i32) -> f32
+!FIRDialect: fir.store {{.*}} to %[[ETA]] : !fir.ref<f32>
+!FIRDialect: omp.terminator
+!FIRDialect: }
+!FIRDialect: omp.section {
+!FIRDialect: {{.*}} = fir.load %[[DOUBLE_COUNT]] : !fir.ref<i32>
+!FIRDialect: {{.*}} = arith.constant 1 : i32
+!FIRDialect: {{.*}} = arith.addi {{.*}} : i32
+!FIRDialect: fir.store {{.*}} to %[[DOUBLE_COUNT]] : !fir.ref<i32>
+!FIRDialect: omp.terminator
+!FIRDialect: }
+!FIRDialect: omp.section {
+!FIRDialect: {{.*}} = fir.load %[[ETA]] : !fir.ref<f32>
+!FIRDialect: {{.*}} = arith.constant 7.000000e+00 : f32
+!FIRDialect: {{.*}} = arith.subf {{.*}} : f32
+!FIRDialect: fir.store {{.*}} to %[[ETA]] : !fir.ref<f32>
+!FIRDialect: {{.*}} = fir.load %[[COUNT]] : !fir.ref<i32>
+!FIRDialect: {{.*}} = fir.convert {{.*}} : (i32) -> f32
+!FIRDialect: {{.*}} = fir.load %[[ETA]] : !fir.ref<f32>
+!FIRDialect: {{.*}} = arith.mulf {{.*}}, {{.*}} : f32
+!FIRDialect: {{.*}} = fir.convert {{.*}} : (f32) -> i32
+!FIRDialect: fir.store {{.*}} to %[[COUNT]] : !fir.ref<i32>
+!FIRDialect: {{.*}} = fir.load %[[COUNT]] : !fir.ref<i32>
+!FIRDialect: {{.*}} = fir.convert {{.*}} : (i32) -> f32
+!FIRDialect: {{.*}} = fir.load %[[ETA]] : !fir.ref<f32>
+!FIRDialect: {{.*}} = arith.subf {{.*}}, {{.*}} : f32
+!FIRDialect: {{.*}} = fir.convert {{.*}} : (f32) -> i32
+!FIRDialect: fir.store {{.*}} to %[[DOUBLE_COUNT]] : !fir.ref<i32>
+!FIRDialect: omp.terminator
+!FIRDialect: }
+!FIRDialect: omp.terminator
+!FIRDialect: }
+!FIRDialect: omp.sections nowait {
+!FIRDialect: omp.terminator
+!FIRDialect: }
+!FIRDialect: return
+!FIRDialect: }
+
+!LLVMDialect: llvm.func @_QQmain() {
+!LLVMDialect: %[[COUNT:.*]] = llvm.mlir.addressof @_QFEcount : !llvm.ptr<i32>
+!LLVMDialect: {{.*}} = builtin.unrealized_conversion_cast %[[COUNT]] : !llvm.ptr<i32> to !fir.ref<i32>
+!LLVMDialect: %[[DOUBLE_COUNT:.*]] = llvm.mlir.addressof @_QFEdouble_count : !llvm.ptr<i32>
+!LLVMDialect: %[[ALLOCATOR:.*]] = llvm.mlir.constant(1 : i64) : i64
+!LLVMDialect: %[[ETA:.*]] = llvm.alloca %[[ALLOCATOR]] x f32 {bindc_name = "eta", in_type = f32, operand_segment_sizes = dense<0> : vector<2xi32>, uniq_name = "_QFEeta"} : (i64) -> !llvm.ptr<f32>
+!LLVMDialect: %[[CONSTANT:.*]] = llvm.mlir.constant(1 : i32) : i32
+!LLVMDialect: omp.sections allocate(%[[CONSTANT]] : i32 -> %1 : !fir.ref<i32>) {
+!LLVMDialect: omp.section {
+!LLVMDialect: {{.*}} = llvm.mlir.constant(5 : i32) : i32
+!LLVMDialect: llvm.store {{.*}}, %[[COUNT]] : !llvm.ptr<i32>
+!LLVMDialect: {{.*}} = llvm.load %[[COUNT]] : !llvm.ptr<i32>
+!LLVMDialect: {{.*}} = llvm.load %[[DOUBLE_COUNT]] : !llvm.ptr<i32>
+!LLVMDialect: {{.*}} = llvm.mul {{.*}}, {{.*}} : i32
+!LLVMDialect: {{.*}} = llvm.sitofp {{.*}} : i32 to f32
+!LLVMDialect: llvm.store {{.*}}, %[[ETA]] : !llvm.ptr<f32>
+!LLVMDialect: omp.terminator
+!LLVMDialect: }
+!LLVMDialect: omp.section {
+!LLVMDialect: {{.*}} = llvm.load %[[DOUBLE_COUNT]] : !llvm.ptr<i32>
+!LLVMDialect: {{.*}} = llvm.mlir.constant(1 : i32) : i32
+!LLVMDialect: {{.*}} = llvm.add {{.*}}, {{.*}} : i32
+!LLVMDialect: llvm.store {{.*}}, %[[DOUBLE_COUNT]] : !llvm.ptr<i32>
+!LLVMDialect: omp.terminator
+!LLVMDialect: }
+!LLVMDialect: omp.section {
+!LLVMDialect: {{.*}} = llvm.load %[[ETA]] : !llvm.ptr<f32>
+!LLVMDialect: {{.*}} = llvm.mlir.constant(7.000000e+00 : f32) : f32
+!LLVMDialect: {{.*}} = llvm.fsub {{.*}}, {{.*}} : f32
+!LLVMDialect: llvm.store {{.*}}, %[[ETA]] : !llvm.ptr<f32>
+!LLVMDialect: {{.*}} = llvm.load %[[COUNT]] : !llvm.ptr<i32>
+!LLVMDialect: {{.*}} = llvm.sitofp {{.*}} : i32 to f32
+!LLVMDialect: {{.*}} = llvm.load %[[ETA]] : !llvm.ptr<f32>
+!LLVMDialect: {{.*}} = llvm.fmul {{.*}}, {{.*}} : f32
+!LLVMDialect: {{.*}} = llvm.fptosi {{.*}} : f32 to i32
+!LLVMDialect: llvm.store {{.*}}, %[[COUNT]] : !llvm.ptr<i32>
+!LLVMDialect: {{.*}} = llvm.load %[[COUNT]] : !llvm.ptr<i32>
+!LLVMDialect: {{.*}} = llvm.sitofp {{.*}} : i32 to f32
+!LLVMDialect: {{.*}} = llvm.load %[[ETA]] : !llvm.ptr<f32>
+!LLVMDialect: {{.*}} = llvm.fsub {{.*}}, {{.*}} : f32
+!LLVMDialect: {{.*}} = llvm.fptosi {{.*}} : f32 to i32
+!LLVMDialect: llvm.store {{.*}}, %[[DOUBLE_COUNT]] : !llvm.ptr<i32>
+!LLVMDialect: omp.terminator
+!LLVMDialect: }
+!LLVMDialect: omp.terminator
+!LLVMDialect: }
+!LLVMDialect: omp.sections nowait {
+!LLVMDialect: omp.section {
+!LLVMDialect: omp.terminator
+!LLVMDialect: }
+!LLVMDialect: omp.terminator
+!LLVMDialect: }
+!LLVMDialect: llvm.return
+!LLVMDialect: }
+
+program sample
+ use omp_lib
+ integer :: count = 0, double_count = 1
+ !$omp sections private (eta, double_count) allocate(omp_high_bw_mem_alloc: count)
+ !$omp section
+ count = 1 + 4
+ eta = count * double_count
+ !$omp section
+ double_count = double_count + 1
+ !$omp section
+ eta = eta - 7
+ count = count * eta
+ double_count = count - eta
+ !$omp end sections
+
+ !$omp sections
+ !$omp end sections nowait
+end program sample
+
+!FIRDialect: func @_QPfirstprivate(%[[ARG:.*]]: !fir.ref<f32> {fir.bindc_name = "alpha"}) {
+!FIRDialect: omp.sections {
+!FIRDialect: omp.section {
+!FIRDialect: omp.terminator
+!FIRDialect: }
+!FIRDialect: omp.terminator
+!FIRDialect: }
+!FIRDialect: omp.sections {
+!FIRDialect: omp.section {
+!FIRDialect: %[[PRIVATE_VAR:.*]] = fir.load %[[ARG]] : !fir.ref<f32>
+!FIRDialect: %[[CONSTANT:.*]] = arith.constant 5.000000e+00 : f32
+!FIRDialect: %[[PRIVATE_VAR_2:.*]] = arith.mulf %[[PRIVATE_VAR]], %[[CONSTANT]] : f32
+!FIRDialect: fir.store %[[PRIVATE_VAR_2]] to %[[ARG]] : !fir.ref<f32>
+!FIRDialect: omp.terminator
+!FIRDialect: }
+!FIRDialect: omp.terminator
+!FIRDialect: }
+!FIRDialect: return
+!FIRDialect: }
+
+!LLVMDialect: llvm.func @_QPfirstprivate(%[[ARG:.*]]: !llvm.ptr<f32> {fir.bindc_name = "alpha"}) {
+!LLVMDialect: omp.sections {
+!LLVMDialect: omp.section {
+!LLVMDialect: omp.terminator
+!LLVMDialect: }
+!LLVMDialect: omp.terminator
+!LLVMDialect: }
+!LLVMDialect: omp.sections {
+!LLVMDialect: omp.section {
+!LLVMDialect: {{.*}} = llvm.load %[[ARG]] : !llvm.ptr<f32>
+!LLVMDialect: {{.*}} = llvm.mlir.constant(5.000000e+00 : f32) : f32
+!LLVMDialect: {{.*}} = llvm.fmul {{.*}}, {{.*}} : f32
+!LLVMDialect: llvm.store {{.*}}, %[[ARG]] : !llvm.ptr<f32>
+!LLVMDialect: omp.terminator
+!LLVMDialect: }
+!LLVMDialect: omp.terminator
+!LLVMDialect: }
+!LLVMDialect: llvm.return
+!LLVMDialect: }
+
+subroutine firstprivate(alpha)
+ real :: alpha
+ !$omp sections firstprivate(alpha)
+ !$omp end sections
+
+ !$omp sections
+ alpha = alpha * 5
+ !$omp end sections
+end subroutine
More information about the flang-commits
mailing list