diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -201,7 +201,10 @@ } bool needBarrier = false; - firOpBuilder.setInsertionPointToStart(firOpBuilder.getAllocaBlock()); + if (mlir::isa(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 @@ auto &firOpBuilder = converter.getFirOpBuilder(); auto currentLocation = converter.getCurrentLocation(); + const Fortran::parser::OpenMPConstruct *parentOmpConstruct = + eval.parentConstruct->getIf(); + assert(parentOmpConstruct && + "No enclosing parent OpenMPConstruct on SECTION construct"); + const Fortran::parser::OpenMPSectionsConstruct *sectionsConstruct = + std::get_if( + &parentOmpConstruct->u); + assert(sectionsConstruct && "SECTION construct must have parent" + "SECTIONS construct"); + const Fortran::parser::OmpClauseList §ionsClauseList = + std::get( + std::get( + 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(currentLocation); - createBodyOfOp(sectionOp, converter, currentLocation, eval); + createBodyOfOp(sectionOp, converter, currentLocation, eval, + §ionsClauseList); } -// 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 --- 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 -!CHECK: %[[DOUBLE_COUNT:.*]] = fir.address_of(@_QFEdouble_count) : !fir.ref !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) { !CHECK: omp.section { -!CHECK: {{.*}} = arith.constant 5 : i32 -!CHECK: fir.store {{.*}} to {{.*}} : !fir.ref -!CHECK: {{.*}} = fir.load %[[COUNT]] : !fir.ref -!CHECK: {{.*}} = fir.load %[[DOUBLE_COUNT]] : !fir.ref -!CHECK: {{.*}} = arith.muli {{.*}}, {{.*}} : i32 -!CHECK: {{.*}} = fir.convert {{.*}} : (i32) -> f32 -!CHECK: fir.store {{.*}} to %[[ETA]] : !fir.ref +!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 +!CHECK: %[[temp_count:.*]] = fir.load %[[COUNT]] : !fir.ref +!CHECK: %[[temp_double_count:.*]] = fir.load %[[PRIVATE_DOUBLE_COUNT]] : !fir.ref +!CHECK: %[[result:.*]] = arith.muli %[[temp_count]], %[[temp_double_count]] : i32 +!CHECK: {{.*}} = fir.convert %[[result]] : (i32) -> f32 +!CHECK: fir.store {{.*}} to %[[PRIVATE_ETA]] : !fir.ref !CHECK: omp.terminator !CHECK: } !CHECK: omp.section { -!CHECK: {{.*}} = fir.load %[[DOUBLE_COUNT]] : !fir.ref -!CHECK: {{.*}} = arith.constant 1 : i32 -!CHECK: {{.*}} = arith.addi {{.*}} : i32 -!CHECK: fir.store {{.*}} to %[[DOUBLE_COUNT]] : !fir.ref +!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 +!CHECK: %[[const:.*]] = arith.constant 1 : i32 +!CHECK: %[[result:.*]] = arith.addi %[[temp]], %[[const]] : i32 +!CHECK: fir.store %[[result]] to %[[PRIVATE_DOUBLE_COUNT]] : !fir.ref !CHECK: omp.terminator !CHECK: } !CHECK: omp.section { -!CHECK: {{.*}} = fir.load %[[ETA]] : !fir.ref -!CHECK: {{.*}} = arith.constant 7.000000e+00 : f32 -!CHECK: {{.*}} = arith.subf {{.*}} : f32 -!CHECK: fir.store {{.*}} to %[[ETA]] : !fir.ref +!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 +!CHECK: %[[const:.*]] = arith.constant 7.000000e+00 : f32 +!CHECK: %[[result:.*]] = arith.subf %[[temp]], %[[const]] : f32 +!CHECK: fir.store %[[result]] to %[[PRIVATE_ETA]] : !fir.ref !CHECK: {{.*}} = fir.load %[[COUNT]] : !fir.ref -!CHECK: {{.*}} = fir.convert {{.*}} : (i32) -> f32 -!CHECK: {{.*}} = fir.load %[[ETA]] : !fir.ref -!CHECK: {{.*}} = arith.mulf {{.*}}, {{.*}} : f32 -!CHECK: {{.*}} = fir.convert {{.*}} : (f32) -> i32 -!CHECK: fir.store {{.*}} to %[[COUNT]] : !fir.ref +!CHECK: %[[temp_count:.*]] = fir.convert {{.*}} : (i32) -> f32 +!CHECK: %[[temp_eta:.*]] = fir.load %[[PRIVATE_ETA]] : !fir.ref +!CHECK: {{.*}} = arith.mulf %[[temp_count]], %[[temp_eta]] : f32 +!CHECK: %[[result:.*]] = fir.convert {{.*}} : (f32) -> i32 +!CHECK: fir.store %[[result]] to %[[COUNT]] : !fir.ref !CHECK: {{.*}} = fir.load %[[COUNT]] : !fir.ref -!CHECK: {{.*}} = fir.convert {{.*}} : (i32) -> f32 -!CHECK: {{.*}} = fir.load %[[ETA]] : !fir.ref -!CHECK: {{.*}} = arith.subf {{.*}}, {{.*}} : f32 -!CHECK: {{.*}} = fir.convert {{.*}} : (f32) -> i32 -!CHECK: fir.store {{.*}} to %[[DOUBLE_COUNT]] : !fir.ref +!CHECK: %[[temp_count:.*]] = fir.convert {{.*}} : (i32) -> f32 +!CHECK: %[[temp_eta:.*]] = fir.load %[[PRIVATE_ETA]] : !fir.ref +!CHECK: {{.*}} = arith.subf %[[temp_count]], %[[temp_eta]] : f32 +!CHECK: %[[result:.*]] = fir.convert {{.*}} : (f32) -> i32 +!CHECK: fir.store %[[result]] to %[[PRIVATE_DOUBLE_COUNT]] : !fir.ref !CHECK: omp.terminator !CHECK: } !CHECK: omp.terminator @@ -74,6 +79,9 @@ !CHECK: func @_QPfirstprivate(%[[ARG:.*]]: !fir.ref {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 +!CHECK: fir.store %[[temp]] to %[[PRIVATE_ALPHA]] : !fir.ref !CHECK: omp.terminator !CHECK: } !CHECK: omp.terminator