llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-flang-semantics @llvm/pr-subscribers-flang-parser Author: Krzysztof Parzyszek (kparzysz) <details> <summary>Changes</summary> --- Patch is 39.71 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/160573.diff 16 Files Affected: - (modified) flang/include/flang/Parser/openmp-utils.h (-2) - (modified) flang/include/flang/Parser/parse-tree.h (+8-2) - (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+6-8) - (modified) flang/lib/Parser/openmp-parsers.cpp (+3-15) - (modified) flang/lib/Parser/unparse.cpp (+2-2) - (modified) flang/lib/Semantics/check-omp-structure.cpp (+124-121) - (modified) flang/lib/Semantics/check-omp-structure.h (-3) - (modified) flang/lib/Semantics/resolve-directives.cpp (+11-16) - (modified) flang/lib/Semantics/resolve-names.cpp (+34-43) - (modified) flang/test/Parser/OpenMP/declare-target-indirect-tree.f90 (+16-12) - (modified) flang/test/Parser/OpenMP/declare-target-to-clause.f90 (+8-6) - (modified) flang/test/Parser/OpenMP/declare_target-device_type.f90 (+93-15) - (modified) flang/test/Parser/OpenMP/enter-automap-modifier.f90 (+7-4) - (modified) flang/test/Parser/OpenMP/openmp6-directive-spellings.f90 (+5-4) - (modified) flang/test/Semantics/OpenMP/blank-common-block.f90 (+1) - (modified) flang/test/Semantics/OpenMP/declare-target-function-name-with-symbols.f90 (+1-1) ``````````diff diff --git a/flang/include/flang/Parser/openmp-utils.h b/flang/include/flang/Parser/openmp-utils.h index 4b8fe6a5b49f0..bf54f970a7d3a 100644 --- a/flang/include/flang/Parser/openmp-utils.h +++ b/flang/include/flang/Parser/openmp-utils.h @@ -41,7 +41,6 @@ struct ConstructId { MAKE_CONSTR_ID(OpenMPDeclarativeAllocate, D::OMPD_allocate); MAKE_CONSTR_ID(OpenMPDeclarativeAssumes, D::OMPD_assumes); MAKE_CONSTR_ID(OpenMPDeclareReductionConstruct, D::OMPD_declare_reduction); -MAKE_CONSTR_ID(OpenMPDeclareTargetConstruct, D::OMPD_declare_target); MAKE_CONSTR_ID(OpenMPExecutableAllocate, D::OMPD_allocate); MAKE_CONSTR_ID(OpenMPRequiresConstruct, D::OMPD_requires); @@ -97,7 +96,6 @@ struct DirectiveNameScope { } else if constexpr (std::is_same_v<T, OpenMPDeclarativeAllocate> || std::is_same_v<T, OpenMPDeclarativeAssumes> || std::is_same_v<T, OpenMPDeclareReductionConstruct> || - std::is_same_v<T, OpenMPDeclareTargetConstruct> || std::is_same_v<T, OpenMPExecutableAllocate> || std::is_same_v<T, OpenMPRequiresConstruct>) { return MakeName(std::get<Verbatim>(x.t).source, ConstructId<T>::id); diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index be30a95763208..e7593d9875097 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -4961,10 +4961,16 @@ struct OmpDeclareTargetSpecifier { std::variant<OmpDeclareTargetWithList, OmpDeclareTargetWithClause> u; }; +// Ref: [4.5:110-113], [5.0:180-185], [5.1:210-216], [5.2:206-207], +// [6.0:346-348] +// +// declare-target-directive -> // since 4.5 +// DECLARE_TARGET[(extended-list)] | +// DECLARE_TARGET clause-list struct OpenMPDeclareTargetConstruct { - TUPLE_CLASS_BOILERPLATE(OpenMPDeclareTargetConstruct); + WRAPPER_CLASS_BOILERPLATE( + OpenMPDeclareTargetConstruct, OmpDirectiveSpecification); CharBlock source; - std::tuple<Verbatim, OmpDeclareTargetSpecifier> t; }; // OMP v5.2: 5.8.8 diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index d2e865b3e1d0c..1cb3335abbd06 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -761,19 +761,17 @@ static void promoteNonCPtrUseDevicePtrArgsToUseDeviceAddr( static void getDeclareTargetInfo( lower::AbstractConverter &converter, semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, - const parser::OpenMPDeclareTargetConstruct &declareTargetConstruct, + const parser::OpenMPDeclareTargetConstruct &construct, mlir::omp::DeclareTargetOperands &clauseOps, llvm::SmallVectorImpl<DeclareTargetCaptureInfo> &symbolAndClause) { - const auto &spec = - std::get<parser::OmpDeclareTargetSpecifier>(declareTargetConstruct.t); - if (const auto *objectList{parser::Unwrap<parser::OmpObjectList>(spec.u)}) { - ObjectList objects{makeObjects(*objectList, semaCtx)}; + + if (!construct.v.Arguments().v.empty()) { + ObjectList objects{makeObjects(construct.v.Arguments(), semaCtx)}; // Case: declare target(func, var1, var2) gatherFuncAndVarSyms(objects, mlir::omp::DeclareTargetCaptureClause::to, symbolAndClause, /*automap=*/false); - } else if (const auto *clauseList{ - parser::Unwrap<parser::OmpClauseList>(spec.u)}) { - List<Clause> clauses = makeClauses(*clauseList, semaCtx); + } else { + List<Clause> clauses = makeClauses(construct.v.Clauses(), semaCtx); if (clauses.empty()) { Fortran::lower::pft::FunctionLikeUnit *owningProc = eval.getOwningProcedure(); diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 0085576292ff5..bd080386c0aea 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -1773,23 +1773,11 @@ TYPE_PARSER(sourced(construct<OpenMPDeclareReductionConstruct>( IsDirective(llvm::omp::Directive::OMPD_declare_reduction)) >= Parser<OmpDirectiveSpecification>{}))) -// declare-target with list -TYPE_PARSER(sourced(construct<OmpDeclareTargetWithList>( - parenthesized(Parser<OmpObjectList>{})))) - -// declare-target with clause -TYPE_PARSER( - sourced(construct<OmpDeclareTargetWithClause>(Parser<OmpClauseList>{}))) - -// declare-target-specifier -TYPE_PARSER( - construct<OmpDeclareTargetSpecifier>(Parser<OmpDeclareTargetWithList>{}) || - construct<OmpDeclareTargetSpecifier>(Parser<OmpDeclareTargetWithClause>{})) - // 2.10.6 Declare Target Construct TYPE_PARSER(sourced(construct<OpenMPDeclareTargetConstruct>( - verbatim("DECLARE TARGET"_tok) || verbatim("DECLARE_TARGET"_tok), - Parser<OmpDeclareTargetSpecifier>{}))) + predicated(Parser<OmpDirectiveName>{}, + IsDirective(llvm::omp::Directive::OMPD_declare_target)) >= + Parser<OmpDirectiveSpecification>{}))) static OmpMapperSpecifier ConstructOmpMapperSpecifier( std::optional<Name> &&mapperName, TypeSpec &&typeSpec, Name &&varName) { diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index c9774dd137d2b..be166bcb743ba 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2582,8 +2582,8 @@ class UnparseVisitor { } void Unparse(const OpenMPDeclareTargetConstruct &x) { BeginOpenMP(); - Word("!$OMP DECLARE TARGET "); - Walk(std::get<parser::OmpDeclareTargetSpecifier>(x.t)); + Word("!$OMP "); + Walk(x.v); Put("\n"); EndOpenMP(); } diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index cf89d305e3cb2..05ff541657b1a 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -624,11 +624,6 @@ template <typename Checker> struct DirectiveSpellingVisitor { checker_(std::get<parser::Verbatim>(x.t).source, Directive::OMPD_assumes); return false; } - bool Pre(const parser::OpenMPDeclareTargetConstruct &x) { - checker_( - std::get<parser::Verbatim>(x.t).source, Directive::OMPD_declare_target); - return false; - } bool Pre(const parser::OpenMPGroupprivate &x) { checker_(x.v.DirName().source, Directive::OMPD_groupprivate); return false; @@ -1615,38 +1610,6 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Allocate &x) { } } -void OmpStructureChecker::Enter(const parser::OmpDeclareTargetWithClause &x) { - SetClauseSets(llvm::omp::Directive::OMPD_declare_target); -} - -void OmpStructureChecker::Leave(const parser::OmpDeclareTargetWithClause &x) { - if (x.v.v.size() > 0) { - const parser::OmpClause *enterClause = - FindClause(llvm::omp::Clause::OMPC_enter); - const parser::OmpClause *toClause = FindClause(llvm::omp::Clause::OMPC_to); - const parser::OmpClause *linkClause = - FindClause(llvm::omp::Clause::OMPC_link); - const parser::OmpClause *indirectClause = - FindClause(llvm::omp::Clause::OMPC_indirect); - if (!enterClause && !toClause && !linkClause) { - context_.Say(x.source, - "If the DECLARE TARGET directive has a clause, it must contain at least one ENTER clause or LINK clause"_err_en_US); - } - if (indirectClause && !enterClause) { - context_.Say(x.source, - "The INDIRECT clause cannot be used without the ENTER clause with the DECLARE TARGET directive."_err_en_US); - } - unsigned version{context_.langOptions().OpenMPVersion}; - if (toClause && version >= 52) { - context_.Warn(common::UsageWarning::OpenMPUsage, toClause->source, - "The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead."_warn_en_US); - } - if (indirectClause) { - CheckAllowedClause(llvm::omp::Clause::OMPC_indirect); - } - } -} - void OmpStructureChecker::Enter(const parser::OpenMPDeclareMapperConstruct &x) { const parser::OmpDirectiveName &dirName{x.v.DirName()}; PushContextAndClauseSets(dirName.source, dirName.v); @@ -1698,42 +1661,6 @@ void OmpStructureChecker::Leave( dirContext_.pop_back(); } -void OmpStructureChecker::Enter(const parser::OpenMPDeclareTargetConstruct &x) { - const auto &dir{std::get<parser::Verbatim>(x.t)}; - PushContext(dir.source, llvm::omp::Directive::OMPD_declare_target); -} - -void OmpStructureChecker::Enter(const parser::OmpDeclareTargetWithList &x) { - SymbolSourceMap symbols; - GetSymbolsInObjectList(x.v, symbols); - for (auto &[symbol, source] : symbols) { - const GenericDetails *genericDetails = symbol->detailsIf<GenericDetails>(); - if (genericDetails) { - context_.Say(source, - "The procedure '%s' in DECLARE TARGET construct cannot be a generic name."_err_en_US, - symbol->name()); - genericDetails->specific(); - } - if (IsProcedurePointer(*symbol)) { - context_.Say(source, - "The procedure '%s' in DECLARE TARGET construct cannot be a procedure pointer."_err_en_US, - symbol->name()); - } - const SubprogramDetails *entryDetails = - symbol->detailsIf<SubprogramDetails>(); - if (entryDetails && entryDetails->entryScope()) { - context_.Say(source, - "The procedure '%s' in DECLARE TARGET construct cannot be an entry name."_err_en_US, - symbol->name()); - } - if (IsStmtFunction(*symbol)) { - context_.Say(source, - "The procedure '%s' in DECLARE TARGET construct cannot be a statement function."_err_en_US, - symbol->name()); - } - } -} - void OmpStructureChecker::CheckSymbolName( const parser::CharBlock &source, const parser::OmpObject &object) { common::visit( @@ -1766,62 +1693,138 @@ void OmpStructureChecker::CheckSymbolNames( } } +void OmpStructureChecker::Enter(const parser::OpenMPDeclareTargetConstruct &x) { + const parser::OmpDirectiveName &dirName{x.v.DirName()}; + PushContext(dirName.source, dirName.v); + + // Check if arguments are extended-list-items. + for (const parser::OmpArgument &arg : x.v.Arguments().v) { + const Symbol *symbol{GetArgumentSymbol(arg)}; + if (!symbol) { + context_.Say(arg.source, + "An argument to the DECLARE TARGET directive should be an extended-list-item"_err_en_US); + continue; + } + const GenericDetails *genericDetails = symbol->detailsIf<GenericDetails>(); + if (genericDetails) { + context_.Say(arg.source, + "The procedure '%s' in DECLARE TARGET construct cannot be a generic name."_err_en_US, + symbol->name()); + genericDetails->specific(); + } + if (IsProcedurePointer(*symbol)) { + context_.Say(arg.source, + "The procedure '%s' in DECLARE TARGET construct cannot be a procedure pointer."_err_en_US, + symbol->name()); + } + const SubprogramDetails *entryDetails = + symbol->detailsIf<SubprogramDetails>(); + if (entryDetails && entryDetails->entryScope()) { + context_.Say(arg.source, + "The procedure '%s' in DECLARE TARGET construct cannot be an entry name."_err_en_US, + symbol->name()); + } + if (IsStmtFunction(*symbol)) { + context_.Say(arg.source, + "The procedure '%s' in DECLARE TARGET construct cannot be a statement function."_err_en_US, + symbol->name()); + } + } + + // Check if there are arguments or clauses, but not both. + if (!x.v.Clauses().v.empty()) { + if (!x.v.Arguments().v.empty()) { + context_.Say(x.source, + "DECLARE TARGET directive can have argument or clauses, but not both"_err_en_US); + } + SetClauseSets(llvm::omp::Directive::OMPD_declare_target); + } +} + void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &x) { - const auto &dir{std::get<parser::Verbatim>(x.t)}; - const auto &spec{std::get<parser::OmpDeclareTargetSpecifier>(x.t)}; + const parser::OmpDirectiveName &dirName{x.v.DirName()}; + // Handle both forms of DECLARE TARGET. // - Extended list: It behaves as if there was an ENTER/TO clause with the // list of objects as argument. It accepts no explicit clauses. // - With clauses. - if (const auto *objectList{parser::Unwrap<parser::OmpObjectList>(spec.u)}) { - deviceConstructFound_ = true; - CheckSymbolNames(dir.source, *objectList); - CheckVarIsNotPartOfAnotherVar(dir.source, *objectList); - CheckThreadprivateOrDeclareTargetVar(*objectList); - } else if (const auto *clauseList{ - parser::Unwrap<parser::OmpClauseList>(spec.u)}) { - bool toClauseFound{false}, deviceTypeClauseFound{false}, - enterClauseFound{false}; - for (const auto &clause : clauseList->v) { - common::visit( - common::visitors{ - [&](const parser::OmpClause::To &toClause) { - toClauseFound = true; - auto &objList{std::get<parser::OmpObjectList>(toClause.v.t)}; - CheckSymbolNames(dir.source, objList); - CheckVarIsNotPartOfAnotherVar(dir.source, objList); - CheckThreadprivateOrDeclareTargetVar(objList); - }, - [&](const parser::OmpClause::Link &linkClause) { - CheckSymbolNames(dir.source, linkClause.v); - CheckVarIsNotPartOfAnotherVar(dir.source, linkClause.v); - CheckThreadprivateOrDeclareTargetVar(linkClause.v); - }, - [&](const parser::OmpClause::Enter &enterClause) { - enterClauseFound = true; - auto &objList{std::get<parser::OmpObjectList>(enterClause.v.t)}; - CheckSymbolNames(dir.source, objList); - CheckVarIsNotPartOfAnotherVar(dir.source, objList); - CheckThreadprivateOrDeclareTargetVar(objList); - }, - [&](const parser::OmpClause::DeviceType &deviceTypeClause) { - deviceTypeClauseFound = true; - if (deviceTypeClause.v.v != - parser::OmpDeviceTypeClause::DeviceTypeDescription::Host) { - // Function / subroutine explicitly marked as runnable by the - // target device. - deviceConstructFound_ = true; - } - }, - [&](const auto &) {}, - }, - clause.u); + for (const parser::OmpArgument &arg : x.v.Arguments().v) { + if (auto *object{GetArgumentObject(arg)}) { + deviceConstructFound_ = true; + CheckSymbolName(dirName.source, *object); + CheckVarIsNotPartOfAnotherVar(dirName.source, *object); + CheckThreadprivateOrDeclareTargetVar(*object); + } + } - if ((toClauseFound || enterClauseFound) && !deviceTypeClauseFound) { - deviceConstructFound_ = true; - } + if (!x.v.Clauses().v.empty()) { + const parser::OmpClause *enterClause = + FindClause(llvm::omp::Clause::OMPC_enter); + const parser::OmpClause *toClause = FindClause(llvm::omp::Clause::OMPC_to); + const parser::OmpClause *linkClause = + FindClause(llvm::omp::Clause::OMPC_link); + const parser::OmpClause *indirectClause = + FindClause(llvm::omp::Clause::OMPC_indirect); + if (!enterClause && !toClause && !linkClause) { + context_.Say(x.source, + "If the DECLARE TARGET directive has a clause, it must contain at least one ENTER clause or LINK clause"_err_en_US); + } + if (indirectClause && !enterClause) { + context_.Say(x.source, + "The INDIRECT clause cannot be used without the ENTER clause with the DECLARE TARGET directive."_err_en_US); + } + unsigned version{context_.langOptions().OpenMPVersion}; + if (toClause && version >= 52) { + context_.Warn(common::UsageWarning::OpenMPUsage, toClause->source, + "The usage of TO clause on DECLARE TARGET directive has been deprecated. Use ENTER clause instead."_warn_en_US); + } + if (indirectClause) { + CheckAllowedClause(llvm::omp::Clause::OMPC_indirect); } } + + bool toClauseFound{false}, deviceTypeClauseFound{false}, + enterClauseFound{false}; + for (const parser::OmpClause &clause : x.v.Clauses().v) { + common::visit( + common::visitors{ + [&](const parser::OmpClause::To &toClause) { + toClauseFound = true; + auto &objList{std::get<parser::OmpObjectList>(toClause.v.t)}; + CheckSymbolNames(dirName.source, objList); + CheckVarIsNotPartOfAnotherVar(dirName.source, objList); + CheckThreadprivateOrDeclareTargetVar(objList); + }, + [&](const parser::OmpClause::Link &linkClause) { + CheckSymbolNames(dirName.source, linkClause.v); + CheckVarIsNotPartOfAnotherVar(dirName.source, linkClause.v); + CheckThreadprivateOrDeclareTargetVar(linkClause.v); + }, + [&](const parser::OmpClause::Enter &enterClause) { + enterClauseFound = true; + auto &objList{std::get<parser::OmpObjectList>(enterClause.v.t)}; + CheckSymbolNames(dirName.source, objList); + CheckVarIsNotPartOfAnotherVar(dirName.source, objList); + CheckThreadprivateOrDeclareTargetVar(objList); + }, + [&](const parser::OmpClause::DeviceType &deviceTypeClause) { + deviceTypeClauseFound = true; + if (deviceTypeClause.v.v != + parser::OmpDeviceTypeClause::DeviceTypeDescription::Host) { + // Function / subroutine explicitly marked as runnable by the + // target device. + deviceConstructFound_ = true; + } + }, + [&](const auto &) {}, + }, + clause.u); + + if ((toClauseFound || enterClauseFound) && !deviceTypeClauseFound) { + deviceConstructFound_ = true; + } + } + dirContext_.pop_back(); } diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h index 176f6568814c5..193784555a887 100644 --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -113,9 +113,6 @@ class OmpStructureChecker void Leave(const parser::OpenMPDeclareTargetConstruct &); void Enter(const parser::OpenMPDepobjConstruct &); void Leave(const parser::OpenMPDepobjConstruct &); - void Enter(const parser::OmpDeclareTargetWithList &); - void Enter(const parser::OmpDeclareTargetWithClause &); - void Leave(const parser::OmpDeclareTargetWithClause &); void Enter(const parser::OpenMPDispatchConstruct &); void Leave(const parser::OpenMPDispatchConstruct &); void Enter(const parser::OmpErrorDirective &); diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index 218e3e7266ca9..7ef211c8b428c 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -2324,22 +2324,17 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPCriticalConstruct &x) { bool OmpAttributeVisitor::Pre(const parser::OpenMPDeclareTargetConstruct &x) { PushContext(x.source, llvm::omp::Directive::OMPD_declare_target); - const auto &spec{std::get<parser::OmpDeclareTargetSpecifier>(x.t)}; - if (const auto *objectList{parser::Unwrap<parser::OmpObjectList>(spec.u)}) { - ResolveOmpObjectList(*objectList, Symbol::Flag::OmpDeclareTarget); - } else if (const auto *clauseList{ - parser::Unwrap<parser::OmpClauseList>(spec.u)}) { - for (const auto &clause : clauseList->v) { - if (const auto *toClause{std::get_if<parser::OmpClause::To>(&clause.u)}) { - auto &objList{std::get<parser::OmpObjectList>(toClause->v.t)}; - ResolveOmpObjectList(objList, Symbol::Flag::OmpDeclareTarget); - } else if (const auto *linkClause{ - std::get_if<parser::OmpClause::Link>(&clause.u)}) { - ResolveOmpObjectList(linkClause->v, Symbol::Flag::OmpDeclareTarget); - } else if (const auto *enterClause{ - std::get_if<parser::OmpClause::Enter>(&clause.u)}) { - ResolveOmpObjectList(std::get<parser::OmpObjectList>(enterClause->v.t), - Symbol::Flag::OmpDeclareTarget); + + for (const parser::OmpArgument &arg : x.v.Arguments().v) { + if (auto *object{omp::GetArgumentObject(arg)}) { + ResolveOmpObject(*object, Symbol::Flag::OmpDeclareTarget); + } + } + + fo... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/160573 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits