From 95a2d04da3a3ace214f742085fc773a94e44bd22 Mon Sep 17 00:00:00 2001 From: Anchu Rajendran S Date: Fri, 12 Jul 2024 10:14:38 -0700 Subject: [PATCH] Adding Changes for invoking Masked Operation (#98423) PR adds changes to the flang frontend to create the `MaskedOp` when `masked` directive is used in the input program. Omp masked is introduced in 5.2 standard and allows a parallel region to be executed by threads specified by a programmer. This is achieved with the help of filter clause which helps to specify thread id expected to execute the region. Other related PRs: - [Fortran Parsing and Semantic Support](https://github.com/llvm/llvm-project/pull/91432) - Merged - [MLIR Support](https://github.com/llvm/llvm-project/pull/96022/files) - Merged - [Lowering Support](https://github.com/llvm/llvm-project/pull/98401) - Under Review --- flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 10 +++++++ flang/lib/Lower/OpenMP/ClauseProcessor.h | 2 ++ flang/lib/Lower/OpenMP/OpenMP.cpp | 29 ++++++++++++++++++- .../Lower/OpenMP/Todo/masked-directive.f90 | 13 --------- flang/test/Lower/OpenMP/masked.f90 | 25 ++++++++++++++++ 5 files changed, 65 insertions(+), 14 deletions(-) delete mode 100644 flang/test/Lower/OpenMP/Todo/masked-directive.f90 create mode 100644 flang/test/Lower/OpenMP/masked.f90 diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp index 433efb16c2d699..b26c1679086b95 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp @@ -332,6 +332,16 @@ bool ClauseProcessor::processDistSchedule( return false; } +bool ClauseProcessor::processFilter(lower::StatementContext &stmtCtx, + mlir::omp::FilterClauseOps &result) const { + if (auto *clause = findUniqueClause()) { + result.filteredThreadIdVar = + fir::getBase(converter.genExprValue(clause->v, stmtCtx)); + return true; + } + return false; +} + bool ClauseProcessor::processFinal(lower::StatementContext &stmtCtx, mlir::omp::FinalClauseOps &result) const { const parser::CharBlock *source = nullptr; diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h index ff39eb72ff24c8..4340c3278cebc9 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.h +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h @@ -63,6 +63,8 @@ class ClauseProcessor { bool processDeviceType(mlir::omp::DeviceTypeClauseOps &result) const; bool processDistSchedule(lower::StatementContext &stmtCtx, mlir::omp::DistScheduleClauseOps &result) const; + bool processFilter(lower::StatementContext &stmtCtx, + mlir::omp::FilterClauseOps &result) const; bool processFinal(lower::StatementContext &stmtCtx, mlir::omp::FinalClauseOps &result) const; bool processHasDeviceAddr( diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index a6e2b0bb0851e3..47ce2d8c8db874 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -1067,6 +1067,15 @@ genLoopNestClauses(lower::AbstractConverter &converter, clauseOps.loopInclusiveAttr = converter.getFirOpBuilder().getUnitAttr(); } +static void genMaskedClauses(lower::AbstractConverter &converter, + semantics::SemanticsContext &semaCtx, + lower::StatementContext &stmtCtx, + const List &clauses, mlir::Location loc, + mlir::omp::MaskedClauseOps &clauseOps) { + ClauseProcessor cp(converter, semaCtx, clauses); + cp.processFilter(stmtCtx, clauseOps); +} + static void genOrderedRegionClauses(lower::AbstractConverter &converter, semantics::SemanticsContext &semaCtx, @@ -1377,6 +1386,21 @@ genLoopNestOp(lower::AbstractConverter &converter, lower::SymMap &symTable, queue, item, clauseOps); } +static mlir::omp::MaskedOp +genMaskedOp(lower::AbstractConverter &converter, lower::SymMap &symTable, + semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, + mlir::Location loc, const ConstructQueue &queue, + ConstructQueue::iterator item) { + lower::StatementContext stmtCtx; + mlir::omp::MaskedClauseOps clauseOps; + genMaskedClauses(converter, semaCtx, stmtCtx, item->clauses, loc, clauseOps); + + return genOpWithBody( + OpWithBodyGenInfo(converter, symTable, semaCtx, loc, eval, + llvm::omp::Directive::OMPD_masked), + queue, item, clauseOps); +} + static mlir::omp::MasterOp genMasterOp(lower::AbstractConverter &converter, lower::SymMap &symTable, semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, @@ -2136,9 +2160,11 @@ static void genOMPDispatch(lower::AbstractConverter &converter, *loopDsp); break; case llvm::omp::Directive::OMPD_loop: - case llvm::omp::Directive::OMPD_masked: TODO(loc, "Unhandled directive " + llvm::omp::getOpenMPDirectiveName(dir)); break; + case llvm::omp::Directive::OMPD_masked: + genMaskedOp(converter, symTable, semaCtx, eval, loc, queue, item); + break; case llvm::omp::Directive::OMPD_master: genMasterOp(converter, symTable, semaCtx, eval, loc, queue, item); break; @@ -2478,6 +2504,7 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, !std::holds_alternative(clause.u) && !std::holds_alternative(clause.u) && !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && !std::holds_alternative(clause.u) && !std::holds_alternative(clause.u) && !std::holds_alternative(clause.u) && diff --git a/flang/test/Lower/OpenMP/Todo/masked-directive.f90 b/flang/test/Lower/OpenMP/Todo/masked-directive.f90 deleted file mode 100644 index 77767715af522d..00000000000000 --- a/flang/test/Lower/OpenMP/Todo/masked-directive.f90 +++ /dev/null @@ -1,13 +0,0 @@ -! This test checks lowering of OpenMP masked Directive. - -! RUN: %not_todo_cmd bbc -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s -! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -o - %s 2>&1 | FileCheck %s - -! CHECK: not yet implemented: Unhandled directive masked -subroutine test_masked() - integer :: c = 1 - !$omp masked - c = c + 1 - !$omp end masked -end subroutine - diff --git a/flang/test/Lower/OpenMP/masked.f90 b/flang/test/Lower/OpenMP/masked.f90 new file mode 100644 index 00000000000000..0d67c08d2d9f48 --- /dev/null +++ b/flang/test/Lower/OpenMP/masked.f90 @@ -0,0 +1,25 @@ +!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s + +!CHECK-LABEL: func @_QPomp_masked +subroutine omp_masked(threadId) +integer :: threadId + +!CHECK: omp.masked { +!$omp masked + + !CHECK: fir.call @_QPmasked() {{.*}}: () -> () + call masked() + +!CHECK: omp.terminator +!$omp end masked + +!CHECK: omp.masked filter({{.*}}) { +!$omp masked filter(threadId) + + !CHECK: fir.call @_QPmaskedwithfilter() {{.*}}: () -> () + call maskedWithFilter() + +!CHECK: omp.terminator +!$omp end masked +end subroutine omp_masked +