[flang][OpenMP] Use 'present-modifier' instead of 'expectation' in 5.1 (#214083) The 5.1 spec lists PRESENT as an alternative in a 'motion-modifier'. The other alternatives are mapper and iterator. These already exist as separate modifiers, so 'motion-modifier' would best be expressed as a modifier group. While modifier groups are not implemented yet, borrow 'present-modifier' from the 6.0 spec. The 'expectation' modifier only existed in 5.2, it was replaced by 'present-modifier' in 6.0. GitOrigin-RevId: 53e7088562dd44518d6250dc768a4bd0a9e9a3c9
diff --git a/include/flang/Parser/parse-tree.h b/include/flang/Parser/parse-tree.h index d647879..6a21d5d 100644 --- a/include/flang/Parser/parse-tree.h +++ b/include/flang/Parser/parse-tree.h
@@ -4292,14 +4292,16 @@ WRAPPER_CLASS_BOILERPLATE(OmpPrescriptiveness, Value); }; -// Ref: [4.5:216-219], [5.0:315-324], [5.1:347-355], [5.2:150-158], -// [6.0:279-288] +// Ref: [5.1:205-210], [6.0:279-288] // // present-modifier -> -// PRESENT // since 5.1 +// PRESENT // since 5.1, until 5.1 +// // since 6.0 // -// Until 5.2, it was a part of map-type-modifier. Since 6.0 the -// map-type-modifier has been split into individual modifiers. +// In 5.1 it was a part of "motion-modifier" (on FROM and TO clauses), which +// should really be modeled as a modifier-group. In 5.2 it was replaced by +// "expectation". It was restored in 6.0 when map-type-modifier was broken up +// into individual modifiers. struct OmpPresentModifier { ENUM_CLASS(Value, Present) WRAPPER_CLASS_BOILERPLATE(OmpPresentModifier, Value); @@ -4711,17 +4713,24 @@ WRAPPER_CLASS_BOILERPLATE(OmpFailClause, MemoryOrder); }; -// Ref: [4.5:107-109], [5.0:176-180], [5.1:205-210], [5.2:167-168] +// Ref: [4.5:107-109], [5.0:176-180], [5.1:205-210], [5.2:167-168], +// [6.0:298-299] // // from-clause -> -// FROM(locator-list) | -// FROM(mapper-modifier: locator-list) | // since 5.0 -// FROM(motion-modifier[,] ...: locator-list) // since 5.1 +// FROM(locator-list) | // since 4.5 +// FROM(modifier[,] ...: locator-list) | // since 5.0 +// modifier -> +// mapper | // since 5.2 +// motion-modifier | // since 5.1, until 5.1 +// expectation | mapper | iterator // since 5.2, until 5.2 +// present-modifier | mapper | iterator | // since 6.0 +// directive-name-modifier // since 6.0 // motion-modifier -> // PRESENT | mapper-modifier | iterator-modifier struct OmpFromClause { TUPLE_CLASS_BOILERPLATE(OmpFromClause); - MODIFIER_BOILERPLATE(OmpExpectation, OmpIterator, OmpMapper); + MODIFIER_BOILERPLATE( + OmpExpectation, OmpPresentModifier, OmpIterator, OmpMapper); std::tuple<MODIFIERS(), OmpObjectList, /*CommaSeparated=*/bool> t; }; @@ -5070,18 +5079,25 @@ }; // Ref: [4.5:107-109], [5.0:176-180], [5.1:205-210], [5.2:167-168] +// [6.0:297-298] // // to-clause (in DECLARE TARGET) -> -// TO(extended-list) | // until 5.1 +// TO(extended-list) | // since 4.5, until 5.1 // to-clause (in TARGET UPDATE) -> -// TO(locator-list) | -// TO(mapper-modifier: locator-list) | // since 5.0 -// TO(motion-modifier[,] ...: locator-list) // since 5.1 -// motion-modifier -> +// TO(locator-list) | // since 4.5 +// TO(modifier[,] ...: locator-list) | // since 5.0 +// modifier -> +// mapper | // since 5.2 +// motion-modifier | // since 5.1, until 5.1 +// expectation | mapper | iterator // since 5.2, until 5.2 +// present-modifier | mapper | iterator | // since 6.0 +// directive-name-modifier // since 6.0 +// motion-modifier -> // PRESENT | mapper-modifier | iterator-modifier struct OmpToClause { TUPLE_CLASS_BOILERPLATE(OmpToClause); - MODIFIER_BOILERPLATE(OmpExpectation, OmpIterator, OmpMapper); + MODIFIER_BOILERPLATE( + OmpExpectation, OmpPresentModifier, OmpIterator, OmpMapper); std::tuple<MODIFIERS(), OmpObjectList, /*CommaSeparated=*/bool> t; };
diff --git a/lib/Lower/OpenMP/Clauses.cpp b/lib/Lower/OpenMP/Clauses.cpp index 1b9ce14..0d315c2 100644 --- a/lib/Lower/OpenMP/Clauses.cpp +++ b/lib/Lower/OpenMP/Clauses.cpp
@@ -974,7 +974,13 @@ semantics::SemanticsContext &semaCtx) { // inp.v -> parser::OmpFromClause CLAUSET_ENUM_CONVERT( // - convert, parser::OmpExpectation::Value, From::Expectation, + convertExp, parser::OmpExpectation::Value, From::Expectation, + // clang-format off + MS(Present, Present) + // clang-format on + ); + CLAUSET_ENUM_CONVERT( // + convertPre, parser::OmpPresentModifier::Value, From::Expectation, // clang-format off MS(Present, Present) // clang-format on @@ -982,26 +988,32 @@ auto &mods = semantics::OmpGetModifiers(inp.v); auto *t0 = semantics::OmpGetUniqueModifier<parser::OmpExpectation>(mods); - auto *t1 = semantics::OmpGetUniqueModifier<parser::OmpMapper>(mods); - auto *t2 = semantics::OmpGetUniqueModifier<parser::OmpIterator>(mods); - auto &t3 = std::get<parser::OmpObjectList>(inp.v.t); + auto *t1 = semantics::OmpGetUniqueModifier<parser::OmpPresentModifier>(mods); + auto *t2 = semantics::OmpGetUniqueModifier<parser::OmpMapper>(mods); + auto *t3 = semantics::OmpGetUniqueModifier<parser::OmpIterator>(mods); + auto &t4 = std::get<parser::OmpObjectList>(inp.v.t); + + std::optional<From::Expectation> maybeExp = // + t0 ? maybeApplyToV(convertExp, t0) + : t1 ? maybeApplyToV(convertPre, t1) + : std::optional<From::Expectation>{}; auto mappers = [&]() -> std::optional<List<Mapper>> { - if (t1) - return List<Mapper>{Mapper{makeObject(t1->v, semaCtx)}}; + if (t2) + return List<Mapper>{Mapper{makeObject(t2->v, semaCtx)}}; return std::nullopt; }(); auto iterator = [&]() -> std::optional<Iterator> { - if (t2) - return makeIterator(*t2, semaCtx); + if (t3) + return makeIterator(*t3, semaCtx); return std::nullopt; }(); - return From{{/*Expectation=*/maybeApplyToV(convert, t0), + return From{{/*Expectation=*/maybeExp, /*Mappers=*/std::move(mappers), /*Iterator=*/std::move(iterator), - /*LocatorList=*/makeObjects(t3, semaCtx)}}; + /*LocatorList=*/makeObjects(t4, semaCtx)}}; } // Full: empty @@ -1694,7 +1706,13 @@ semantics::SemanticsContext &semaCtx) { // inp.v -> parser::OmpToClause CLAUSET_ENUM_CONVERT( // - convert, parser::OmpExpectation::Value, To::Expectation, + convertExp, parser::OmpExpectation::Value, To::Expectation, + // clang-format off + MS(Present, Present) + // clang-format on + ); + CLAUSET_ENUM_CONVERT( // + convertPre, parser::OmpPresentModifier::Value, To::Expectation, // clang-format off MS(Present, Present) // clang-format on @@ -1702,26 +1720,32 @@ auto &mods = semantics::OmpGetModifiers(inp.v); auto *t0 = semantics::OmpGetUniqueModifier<parser::OmpExpectation>(mods); - auto *t1 = semantics::OmpGetUniqueModifier<parser::OmpMapper>(mods); - auto *t2 = semantics::OmpGetUniqueModifier<parser::OmpIterator>(mods); - auto &t3 = std::get<parser::OmpObjectList>(inp.v.t); + auto *t1 = semantics::OmpGetUniqueModifier<parser::OmpPresentModifier>(mods); + auto *t2 = semantics::OmpGetUniqueModifier<parser::OmpMapper>(mods); + auto *t3 = semantics::OmpGetUniqueModifier<parser::OmpIterator>(mods); + auto &t4 = std::get<parser::OmpObjectList>(inp.v.t); + + std::optional<To::Expectation> maybeExp = // + t0 ? maybeApplyToV(convertExp, t0) + : t1 ? maybeApplyToV(convertPre, t1) + : std::optional<To::Expectation>{}; auto mappers = [&]() -> std::optional<List<Mapper>> { - if (t1) - return List<Mapper>{Mapper{makeObject(t1->v, semaCtx)}}; + if (t2) + return List<Mapper>{Mapper{makeObject(t2->v, semaCtx)}}; return std::nullopt; }(); auto iterator = [&]() -> std::optional<Iterator> { - if (t2) - return makeIterator(*t2, semaCtx); + if (t3) + return makeIterator(*t3, semaCtx); return std::nullopt; }(); - return To{{/*Expectation=*/maybeApplyToV(convert, t0), + return To{{/*Expectation=*/maybeExp, /*Mappers=*/{std::move(mappers)}, /*Iterator=*/std::move(iterator), - /*LocatorList=*/makeObjects(t3, semaCtx)}}; + /*LocatorList=*/makeObjects(t4, semaCtx)}}; } UnifiedAddress make(const parser::OmpClause::UnifiedAddress &inp,
diff --git a/lib/Parser/openmp-parsers.cpp b/lib/Parser/openmp-parsers.cpp index ad74cb8..7c4e49a 100644 --- a/lib/Parser/openmp-parsers.cpp +++ b/lib/Parser/openmp-parsers.cpp
@@ -1088,10 +1088,27 @@ TYPE_PARSER( sourced(construct<OmpEnterClause::Modifier>(Parser<OmpAutomapModifier>{}))) -TYPE_PARSER(sourced(construct<OmpFromClause::Modifier>( - sourced(construct<OmpFromClause::Modifier>(Parser<OmpExpectation>{}) || - construct<OmpFromClause::Modifier>(Parser<OmpMapper>{}) || - construct<OmpFromClause::Modifier>(Parser<OmpIterator>{}))))) +template <typename MotionClause> struct OmpMotionClauseModifierParser { + using resultType = typename MotionClause::Modifier; + + std::optional<resultType> Parse(ParseState &state) const { + unsigned version{state.userState()->langOptions().OpenMPVersion}; + if (version == 52) { + auto expect{sourced(construct<resultType>(Parser<OmpExpectation>{}))}; + if (auto &&result{attempt(expect).Parse(state)}) { + return std::move(result); + } + } + auto parser{sourced( // + construct<resultType>(Parser<OmpPresentModifier>{}) || + construct<resultType>(Parser<OmpMapper>{}) || + construct<resultType>(Parser<OmpIterator>{}))}; + return parser.Parse(state); + } +}; + +TYPE_PARSER(OmpMotionClauseModifierParser<OmpFromClause>{}) +TYPE_PARSER(OmpMotionClauseModifierParser<OmpToClause>{}) TYPE_PARSER(sourced( construct<OmpGrainsizeClause::Modifier>(Parser<OmpPrescriptiveness>{}))) @@ -1176,11 +1193,6 @@ TYPE_PARSER(sourced( construct<OmpThreadLimitClause::Modifier>(Parser<OmpDimsModifier>{}))) -TYPE_PARSER(sourced(construct<OmpToClause::Modifier>( - sourced(construct<OmpToClause::Modifier>(Parser<OmpExpectation>{}) || - construct<OmpToClause::Modifier>(Parser<OmpMapper>{}) || - construct<OmpToClause::Modifier>(Parser<OmpIterator>{}))))) - TYPE_PARSER(sourced(construct<OmpWhenClause::Modifier>( // Parser<OmpContextSelector>{})))
diff --git a/lib/Semantics/openmp-modifiers.cpp b/lib/Semantics/openmp-modifiers.cpp index 972788a..293136d 100644 --- a/lib/Semantics/openmp-modifiers.cpp +++ b/lib/Semantics/openmp-modifiers.cpp
@@ -361,11 +361,12 @@ /*name=*/"expectation", /*props=*/ { - {51, {OmpProperty::Unique}}, + {52, {OmpProperty::Unique}}, }, /*clauses=*/ { - {51, {Clause::OMPC_from, Clause::OMPC_to}}, + {52, {Clause::OMPC_from, Clause::OMPC_to}}, + {60, {}}, }, }; return desc; @@ -629,7 +630,9 @@ }, /*clauses=*/ { - {51, {Clause::OMPC_map}}, + {51, {Clause::OMPC_from, Clause::OMPC_to}}, + {52, {}}, + {60, {Clause::OMPC_from, Clause::OMPC_map, Clause::OMPC_to}}, }, }; return desc;
diff --git a/test/Semantics/OpenMP/from-clause-v45.f90 b/test/Semantics/OpenMP/from-clause-v45.f90 index 654af4b..284511a 100644 --- a/test/Semantics/OpenMP/from-clause-v45.f90 +++ b/test/Semantics/OpenMP/from-clause-v45.f90
@@ -14,16 +14,16 @@ subroutine f02(x) integer :: x(10) -!WARNING: 'expectation' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 +!WARNING: 'present-modifier' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 !WARNING: 'iterator' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 !$omp target update from(present, iterator(i = 1:5): x(i)) end subroutine f03(x) integer :: x(10) -!WARNING: 'expectation' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 -!WARNING: 'expectation' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 -!ERROR: 'expectation' modifier cannot occur multiple times +!WARNING: 'present-modifier' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 +!WARNING: 'present-modifier' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 +!ERROR: 'present-modifier' modifier cannot occur multiple times !$omp target update from(present, present: x) end
diff --git a/test/Semantics/OpenMP/from-clause-v51.f90 b/test/Semantics/OpenMP/from-clause-v51.f90 index 8771f51..60252a8 100644 --- a/test/Semantics/OpenMP/from-clause-v51.f90 +++ b/test/Semantics/OpenMP/from-clause-v51.f90
@@ -8,7 +8,7 @@ subroutine f03(x) integer :: x(10) -!ERROR: 'expectation' modifier cannot occur multiple times +!ERROR: 'present-modifier' modifier cannot occur multiple times !$omp target update from(present, present: x) end
diff --git a/test/Semantics/OpenMP/to-clause-v45.f90 b/test/Semantics/OpenMP/to-clause-v45.f90 index 7e56817..2fff681 100644 --- a/test/Semantics/OpenMP/to-clause-v45.f90 +++ b/test/Semantics/OpenMP/to-clause-v45.f90
@@ -14,16 +14,16 @@ subroutine f02(x) integer :: x(10) -!WARNING: 'expectation' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 +!WARNING: 'present-modifier' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 !WARNING: 'iterator' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 !$omp target update to(present, iterator(i = 1:5): x(i)) end subroutine f03(x) integer :: x(10) -!WARNING: 'expectation' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 -!WARNING: 'expectation' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 -!ERROR: 'expectation' modifier cannot occur multiple times +!WARNING: 'present-modifier' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 +!WARNING: 'present-modifier' modifier is not supported in OpenMP v4.5, try -fopenmp-version=51 +!ERROR: 'present-modifier' modifier cannot occur multiple times !$omp target update to(present, present: x) end
diff --git a/test/Semantics/OpenMP/to-clause-v51.f90 b/test/Semantics/OpenMP/to-clause-v51.f90 index 0db292a..15e742c 100644 --- a/test/Semantics/OpenMP/to-clause-v51.f90 +++ b/test/Semantics/OpenMP/to-clause-v51.f90
@@ -8,7 +8,7 @@ subroutine f03(x) integer :: x(10) -!ERROR: 'expectation' modifier cannot occur multiple times +!ERROR: 'present-modifier' modifier cannot occur multiple times !$omp target update to(present, present: x) end