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 @@ -549,15 +549,27 @@ llvm::SmallVectorImpl &useDeviceSymbols) const; + // Call this method for these clauses that should be supported but are not + // implemented yet. It triggers a compilation error if the given clauses are + // found. + template + void processTODO(mlir::Location currentLocation, + llvm::omp::Directive directive) const; + private: using ClauseIterator = std::list::const_iterator; - /// Utility to find a clause within a range in the clause list. - template + /// Utility to find one of the given clauses within a range in the clause + /// list. + template static ClauseIterator findClause(ClauseIterator begin, ClauseIterator end) { - for (ClauseIterator it = begin; it != end; ++it) - if (std::get_if(&it->u)) - return it; + for (ClauseIterator it = begin; it != end; ++it) { + bool found[sizeof...(Ts)] = { + static_cast(std::get_if(&it->u))...}; + for (bool v : found) + if (v) + return it; + } return end; } @@ -1764,6 +1776,18 @@ }); } +template +void ClauseProcessor::processTODO(mlir::Location currentLocation, + llvm::omp::Directive directive) const { + ClauseIterator it = findClause(clauses.v.begin(), clauses.v.end()); + if (it != clauses.v.end()) { + TODO(currentLocation, + "Unhandled clause in " + + llvm::omp::getOpenMPDirectiveName(directive).upper() + + " directive"); + } +} + //===----------------------------------------------------------------------===// // Code generation helper functions //===----------------------------------------------------------------------===// @@ -2204,8 +2228,11 @@ llvm::SmallVector allocateOperands, allocatorOperands; mlir::UnitAttr nowaitAttr; - ClauseProcessor(converter, beginClauseList) - .processAllocate(allocatorOperands, allocateOperands); + ClauseProcessor cp(converter, beginClauseList); + cp.processAllocate(allocatorOperands, allocateOperands); + cp.processTODO( + currentLocation, llvm::omp::Directive::OMPD_single); + ClauseProcessor(converter, endClauseList).processNowait(nowaitAttr); return genOpWithBody( @@ -2235,6 +2262,10 @@ cp.processMergeable(mergeableAttr); cp.processPriority(stmtCtx, priorityClauseOperand); cp.processDepend(dependTypeOperands, dependOperands); + cp.processTODO( + currentLocation, llvm::omp::Directive::OMPD_task); return genOpWithBody( converter, eval, currentLocation, /*outerCombined=*/false, &clauseList, @@ -2254,9 +2285,10 @@ mlir::Location currentLocation, const Fortran::parser::OmpClauseList &clauseList) { llvm::SmallVector allocateOperands, allocatorOperands; - // TODO: Add task_reduction support - ClauseProcessor(converter, clauseList) - .processAllocate(allocatorOperands, allocateOperands); + ClauseProcessor cp(converter, clauseList); + cp.processAllocate(allocatorOperands, allocateOperands); + cp.processTODO( + currentLocation, llvm::omp::Directive::OMPD_taskgroup); return genOpWithBody( converter, eval, currentLocation, /*outerCombined=*/false, &clauseList, /*task_reduction_vars=*/mlir::ValueRange(), @@ -2314,12 +2346,15 @@ llvm::SmallVector mapTypes; Fortran::parser::OmpIfClause::DirectiveNameModifier directiveName; + llvm::omp::Directive directive; if constexpr (std::is_same_v) { directiveName = Fortran::parser::OmpIfClause::DirectiveNameModifier::TargetEnterData; + directive = llvm::omp::Directive::OMPD_target_enter_data; } else if constexpr (std::is_same_v) { directiveName = Fortran::parser::OmpIfClause::DirectiveNameModifier::TargetExitData; + directive = llvm::omp::Directive::OMPD_target_exit_data; } else { return nullptr; } @@ -2329,6 +2364,8 @@ cp.processDevice(stmtCtx, deviceOperand); cp.processNowait(nowaitAttr); cp.processMap(mapOperands, mapTypes); + cp.processTODO(currentLocation, + directive); llvm::SmallVector mapTypesAttr(mapTypes.begin(), mapTypes.end()); @@ -2361,6 +2398,17 @@ cp.processThreadLimit(stmtCtx, threadLimitOperand); cp.processNowait(nowaitAttr); cp.processMap(mapOperands, mapTypes); + cp.processTODO( + currentLocation, llvm::omp::Directive::OMPD_target); llvm::SmallVector mapTypesAttr(mapTypes.begin(), mapTypes.end()); @@ -2393,8 +2441,8 @@ cp.processDefault(); cp.processNumTeams(stmtCtx, numTeamsClauseOperand); cp.processThreadLimit(stmtCtx, threadLimitClauseOperand); - if (cp.processReduction(currentLocation, reductionVars, reductionDeclSymbols)) - TODO(currentLocation, "Reduction of TEAMS directive"); + cp.processTODO( + currentLocation, llvm::omp::Directive::OMPD_teams); return genOpWithBody( converter, eval, currentLocation, outerCombined, &clauseList, @@ -2411,10 +2459,11 @@ // genOMP() Code generation helper functions //===----------------------------------------------------------------------===// -static void genOMP(Fortran::lower::AbstractConverter &converter, - Fortran::lower::pft::Evaluation &eval, - const Fortran::parser::OpenMPSimpleStandaloneConstruct - &simpleStandaloneConstruct) { +static void +genOmpSimpleStandalone(Fortran::lower::AbstractConverter &converter, + Fortran::lower::pft::Evaluation &eval, + const Fortran::parser::OpenMPSimpleStandaloneConstruct + &simpleStandaloneConstruct) { const auto &directive = std::get( simpleStandaloneConstruct.t); @@ -2430,6 +2479,10 @@ firOpBuilder.create(currentLocation); break; case llvm::omp::Directive::OMPD_taskwait: + ClauseProcessor(converter, opClauseList) + .processTODO( + currentLocation, llvm::omp::Directive::OMPD_taskwait); firOpBuilder.create(currentLocation); break; case llvm::omp::Directive::OMPD_taskyield: @@ -2453,6 +2506,24 @@ } } +static void +genOmpFlush(Fortran::lower::AbstractConverter &converter, + Fortran::lower::pft::Evaluation &eval, + const Fortran::parser::OpenMPFlushConstruct &flushConstruct) { + llvm::SmallVector operandRange; + if (const auto &ompObjectList = + std::get>( + flushConstruct.t)) + genObjectList(*ompObjectList, converter, operandRange); + const auto &memOrderClause = + std::get>>( + flushConstruct.t); + if (memOrderClause && memOrderClause->size() > 0) + TODO(converter.getCurrentLocation(), "Handle OmpMemoryOrderClause"); + converter.getFirOpBuilder().create( + converter.getCurrentLocation(), operandRange); +} + static void genOMP(Fortran::lower::AbstractConverter &converter, Fortran::lower::pft::Evaluation &eval, @@ -2461,22 +2532,10 @@ Fortran::common::visitors{ [&](const Fortran::parser::OpenMPSimpleStandaloneConstruct &simpleStandaloneConstruct) { - genOMP(converter, eval, simpleStandaloneConstruct); + genOmpSimpleStandalone(converter, eval, simpleStandaloneConstruct); }, [&](const Fortran::parser::OpenMPFlushConstruct &flushConstruct) { - llvm::SmallVector operandRange; - if (const auto &ompObjectList = - std::get>( - flushConstruct.t)) - genObjectList(*ompObjectList, converter, operandRange); - const auto &memOrderClause = std::get>>( - flushConstruct.t); - if (memOrderClause && memOrderClause->size() > 0) - TODO(converter.getCurrentLocation(), - "Handle OmpMemoryOrderClause"); - converter.getFirOpBuilder().create( - converter.getCurrentLocation(), operandRange); + genOmpFlush(converter, eval, flushConstruct); }, [&](const Fortran::parser::OpenMPCancelConstruct &cancelConstruct) { TODO(converter.getCurrentLocation(), "OpenMPCancelConstruct"); @@ -2494,14 +2553,13 @@ const Fortran::parser::OpenMPLoopConstruct &loopConstruct) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); llvm::SmallVector lowerBound, upperBound, step, linearVars, - linearStepVars, reductionVars, alignedVars, nontemporalVars; - mlir::Value scheduleChunkClauseOperand, ifClauseOperand; + linearStepVars, reductionVars; + mlir::Value scheduleChunkClauseOperand; mlir::IntegerAttr orderedClauseOperand; mlir::omp::ClauseOrderKindAttr orderClauseOperand; mlir::omp::ClauseScheduleKindAttr scheduleValClauseOperand; mlir::omp::ScheduleModifierAttr scheduleModClauseOperand; mlir::UnitAttr nowaitClauseOperand, scheduleSimdClauseOperand; - mlir::IntegerAttr simdlenClauseOperand, safelenClauseOperand; llvm::SmallVector reductionDeclSymbols; Fortran::lower::StatementContext stmtCtx; std::size_t loopVarTypeSize; @@ -2561,12 +2619,10 @@ cp.processCollapse(currentLocation, eval, lowerBound, upperBound, step, iv, loopVarTypeSize); cp.processScheduleChunk(stmtCtx, scheduleChunkClauseOperand); - cp.processIf(stmtCtx, - Fortran::parser::OmpIfClause::DirectiveNameModifier::Simd, - ifClauseOperand); cp.processReduction(currentLocation, reductionVars, reductionDeclSymbols); - cp.processSimdlen(simdlenClauseOperand); - cp.processSafelen(safelenClauseOperand); + cp.processTODO(currentLocation, + ompDirective); // The types of lower bound, upper bound, and step are converted into the // type of the loop variable if necessary. @@ -2581,8 +2637,20 @@ } // 2.9.3.1 SIMD construct - // TODO: Support all the clauses if (llvm::omp::allSimdSet.test(ompDirective)) { + llvm::SmallVector alignedVars, nontemporalVars; + mlir::Value ifClauseOperand; + mlir::IntegerAttr simdlenClauseOperand, safelenClauseOperand; + cp.processIf(stmtCtx, + Fortran::parser::OmpIfClause::DirectiveNameModifier::Simd, + ifClauseOperand); + cp.processSimdlen(simdlenClauseOperand); + cp.processSafelen(safelenClauseOperand); + cp.processTODO(currentLocation, + ompDirective); + mlir::TypeRange resultType; auto simdLoopOp = firOpBuilder.create( currentLocation, resultType, lowerBound, upperBound, step, alignedVars, @@ -2595,9 +2663,6 @@ return; } - // FIXME: Add support for following clauses: - // 1. linear - // 2. order auto wsLoopOp = firOpBuilder.create( currentLocation, lowerBound, upperBound, step, linearVars, linearStepVars, reductionVars, @@ -3331,6 +3396,9 @@ cp.processTo(symbolAndClause); cp.processLink(symbolAndClause); cp.processDeviceType(deviceType); + cp.processTODO( + converter.getCurrentLocation(), + llvm::omp::Directive::OMPD_declare_target); } for (const DeclareTargetCapturePair &symClause : symbolAndClause) { diff --git a/flang/test/Lower/OpenMP/Todo/reduction-teams.f90 b/flang/test/Lower/OpenMP/Todo/reduction-teams.f90 --- a/flang/test/Lower/OpenMP/Todo/reduction-teams.f90 +++ b/flang/test/Lower/OpenMP/Todo/reduction-teams.f90 @@ -1,7 +1,7 @@ ! 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: Reduction of TEAMS directive +! CHECK: not yet implemented: Unhandled clause in TEAMS directive subroutine reduction_teams() integer :: i i = 0