Index: flang/lib/Lower/OpenMP.cpp =================================================================== --- flang/lib/Lower/OpenMP.cpp +++ flang/lib/Lower/OpenMP.cpp @@ -912,6 +912,31 @@ return omp::ClauseProcBindKindAttr::get(firOpBuilder.getContext(), pbKind); } +static omp::ClauseTaskDependAttr +genDependKindAttr(fir::FirOpBuilder &firOpBuilder, + const Fortran::parser::OmpClause::Depend *dependClause) { + omp::ClauseTaskDepend pbKind; + switch ( + std::get( + std::get(dependClause->v.u) + .t) + .v) { + case Fortran::parser::OmpDependenceType::Type::In: + pbKind = omp::ClauseTaskDepend::taskdependin; + break; + case Fortran::parser::OmpDependenceType::Type::Out: + pbKind = omp::ClauseTaskDepend::taskdependout; + break; + case Fortran::parser::OmpDependenceType::Type::Inout: + pbKind = omp::ClauseTaskDepend::taskdependinout; + break; + default: + llvm_unreachable("unknown parser task dependence type"); + break; + } + return omp::ClauseTaskDependAttr::get(firOpBuilder.getContext(), pbKind); +} + /* When parallel is used in a combined construct, then use this function to * create the parallel operation. It handles the parallel specific clauses * and leaves the rest for handling at the inner operations. @@ -978,7 +1003,8 @@ mlir::Value ifClauseOperand, numThreadsClauseOperand, finalClauseOperand, priorityClauseOperand; mlir::omp::ClauseProcBindKindAttr procBindKindAttr; - SmallVector allocateOperands, allocatorOperands; + SmallVector allocateOperands, allocatorOperands, dependOperands; + SmallVector dependTypeOperands; mlir::UnitAttr nowaitAttr, untiedAttr, mergeableAttr; const auto &opClauseList = @@ -1050,6 +1076,42 @@ "Reduction in OpenMP " + llvm::omp::getOpenMPDirectiveName(blockDirective.v) + " construct"); + } else if (const auto &dependClause = + std::get_if(&clause.u)) { + const std::list &depVal = + std::get>( + std::get( + dependClause->v.u) + .t); + omp::ClauseTaskDependAttr dependTypeOperand = + genDependKindAttr(firOpBuilder, dependClause); + dependTypeOperands.insert(dependTypeOperands.end(), depVal.size(), + dependTypeOperand); + for (const Fortran::parser::Designator &ompObject : depVal) { + Fortran::semantics::Symbol *sym = nullptr; + std::visit( + Fortran::common::visitors{ + [&](const Fortran::parser::DataRef &designator) { + if (const Fortran::parser::Name *name = + std::get_if(&designator.u)) { + sym = name->symbol; + } else if (const Fortran::common::Indirection< + Fortran::parser::ArrayElement> *a = + std::get_if>( + &designator.u)) { + TODO(converter.getCurrentLocation(), + "array sections not supported for task depend"); + } + }, + [&](const Fortran::parser::Substring &designator) { + TODO(converter.getCurrentLocation(), + "substring not supported for task depend"); + }}, + (ompObject).u); + const mlir::Value variable = converter.getSymbolAddress(*sym); + dependOperands.push_back(((variable))); + } } else { TODO(converter.getCurrentLocation(), "OpenMP Block construct clause"); } @@ -1087,8 +1149,12 @@ auto taskOp = firOpBuilder.create( currentLocation, ifClauseOperand, finalClauseOperand, untiedAttr, mergeableAttr, /*in_reduction_vars=*/ValueRange(), - /*in_reductions=*/nullptr, priorityClauseOperand, /*depends=*/nullptr, - /*depend_vars=*/ValueRange(), allocateOperands, allocatorOperands); + /*in_reductions=*/nullptr, priorityClauseOperand, + dependTypeOperands.empty() + ? nullptr + : mlir::ArrayAttr::get(firOpBuilder.getContext(), + dependTypeOperands), + dependOperands, allocateOperands, allocatorOperands); createBodyOfOp(taskOp, converter, currentLocation, eval, &opClauseList); } else if (blockDirective.v == llvm::omp::OMPD_taskgroup) { // TODO: Add task_reduction support Index: flang/test/Lower/OpenMP/task.f90 =================================================================== --- flang/test/Lower/OpenMP/task.f90 +++ flang/test/Lower/OpenMP/task.f90 @@ -99,6 +99,21 @@ !$omp end task end subroutine task_allocate +!=============================================================================== +! `depend` clause +!=============================================================================== + +!CHECK-LABEL: func @_QPtask_depend +subroutine task_depend() + integer :: x + !CHECK: omp.task depend(taskdependin -> %{{.+}} : !fir.ref) { + !$omp task depend(in : x) + !CHECK: arith.addi + x = x + 12 + !CHECK: omp.terminator + !$omp end task +end subroutine task_depend + !=============================================================================== ! `private` clause !===============================================================================