aboutsummaryrefslogtreecommitdiff
path: root/flang/lib
diff options
context:
space:
mode:
authorKrzysztof Parzyszek <Krzysztof.Parzyszek@amd.com>2025-07-21 10:55:37 -0500
committerGitHub <noreply@github.com>2025-07-21 10:55:37 -0500
commit2aa1e54fa1ff7f7c347e7108fe8650e94014c941 (patch)
tree01b425d895b9457c00a3f6cdcb41ae020c6e8e14 /flang/lib
parentc33c978d766a6bbaec28fce7638354c549a75111 (diff)
downloadllvm-2aa1e54fa1ff7f7c347e7108fe8650e94014c941.zip
llvm-2aa1e54fa1ff7f7c347e7108fe8650e94014c941.tar.gz
llvm-2aa1e54fa1ff7f7c347e7108fe8650e94014c941.tar.bz2
[flang][OpenMP] Parse OpenMP 6.0 map modifiers (#149134)
OpenMP 6.0 has changed the modifiers on the MAP clause: - map-type-modifier has been split into individual modifiers, - map-type "delete" has become a modifier, - new modifiers have been added. This patch adds parsing support for all of the OpenMP 6.0 modifiers. The old "map-type-modifier" is retained, but is no longer created in parsing. It will remain to take advantage of the preexisting modifier validation for older versions: when the OpenMP version is < 6.0, the modifiers will be rewritten back as map-type-modifiers (or map- type in case of "delete"). In this patch the modifiers will always be rewritten in the older format to isolate these changes to parsing as much as possible.
Diffstat (limited to 'flang/lib')
-rw-r--r--flang/lib/Parser/openmp-parsers.cpp53
-rw-r--r--flang/lib/Parser/unparse.cpp7
-rw-r--r--flang/lib/Semantics/canonicalize-omp.cpp38
-rw-r--r--flang/lib/Semantics/canonicalize-omp.h4
-rw-r--r--flang/lib/Semantics/openmp-modifiers.cpp115
-rw-r--r--flang/lib/Semantics/resolve-directives.cpp2
6 files changed, 203 insertions, 16 deletions
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 76c9499..d349d8c 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -274,6 +274,10 @@ TYPE_PARSER( //
construct<OmpTypeSpecifier>(Parser<DeclarationTypeSpec>{}) ||
construct<OmpTypeSpecifier>(Parser<TypeSpec>{}))
+// 2.15.3.6 REDUCTION (reduction-identifier: variable-name-list)
+TYPE_PARSER(construct<OmpReductionIdentifier>(Parser<DefinedOperator>{}) ||
+ construct<OmpReductionIdentifier>(Parser<ProcedureDesignator>{}))
+
TYPE_PARSER(construct<OmpReductionSpecifier>( //
Parser<OmpReductionIdentifier>{},
":"_tok >> nonemptyList(Parser<OmpTypeSpecifier>{}),
@@ -442,9 +446,18 @@ TYPE_PARSER(construct<OmpAllocatorComplexModifier>(
TYPE_PARSER(construct<OmpAllocatorSimpleModifier>(scalarIntExpr))
+TYPE_PARSER(construct<OmpAlwaysModifier>( //
+ "ALWAYS" >> pure(OmpAlwaysModifier::Value::Always)))
+
TYPE_PARSER(construct<OmpChunkModifier>( //
"SIMD" >> pure(OmpChunkModifier::Value::Simd)))
+TYPE_PARSER(construct<OmpCloseModifier>( //
+ "CLOSE" >> pure(OmpCloseModifier::Value::Close)))
+
+TYPE_PARSER(construct<OmpDeleteModifier>( //
+ "DELETE" >> pure(OmpDeleteModifier::Value::Delete)))
+
TYPE_PARSER(construct<OmpDependenceType>(
"SINK" >> pure(OmpDependenceType::Value::Sink) ||
"SOURCE" >> pure(OmpDependenceType::Value::Source)))
@@ -502,26 +515,16 @@ TYPE_PARSER(construct<OmpLinearModifier>( //
TYPE_PARSER(construct<OmpMapper>( //
"MAPPER"_tok >> parenthesized(Parser<ObjectName>{})))
-// map-type -> ALLOC | DELETE | FROM | RELEASE | TO | TOFROM
+// map-type -> ALLOC | DELETE | FROM | RELEASE | STORAGE | TO | TOFROM
TYPE_PARSER(construct<OmpMapType>( //
"ALLOC" >> pure(OmpMapType::Value::Alloc) ||
- "DELETE" >> pure(OmpMapType::Value::Delete) ||
+ // Parse "DELETE" as OmpDeleteModifier
"FROM" >> pure(OmpMapType::Value::From) ||
"RELEASE" >> pure(OmpMapType::Value::Release) ||
+ "STORAGE" >> pure(OmpMapType::Value::Storage) ||
"TO"_id >> pure(OmpMapType::Value::To) ||
"TOFROM" >> pure(OmpMapType::Value::Tofrom)))
-// map-type-modifier -> ALWAYS | CLOSE | OMPX_HOLD | PRESENT
-TYPE_PARSER(construct<OmpMapTypeModifier>(
- "ALWAYS" >> pure(OmpMapTypeModifier::Value::Always) ||
- "CLOSE" >> pure(OmpMapTypeModifier::Value::Close) ||
- "OMPX_HOLD" >> pure(OmpMapTypeModifier::Value::Ompx_Hold) ||
- "PRESENT" >> pure(OmpMapTypeModifier::Value::Present)))
-
-// 2.15.3.6 REDUCTION (reduction-identifier: variable-name-list)
-TYPE_PARSER(construct<OmpReductionIdentifier>(Parser<DefinedOperator>{}) ||
- construct<OmpReductionIdentifier>(Parser<ProcedureDesignator>{}))
-
TYPE_PARSER(construct<OmpOrderModifier>(
"REPRODUCIBLE" >> pure(OmpOrderModifier::Value::Reproducible) ||
"UNCONSTRAINED" >> pure(OmpOrderModifier::Value::Unconstrained)))
@@ -534,11 +537,22 @@ TYPE_PARSER(construct<OmpOrderingModifier>(
TYPE_PARSER(construct<OmpPrescriptiveness>(
"STRICT" >> pure(OmpPrescriptiveness::Value::Strict)))
+TYPE_PARSER(construct<OmpPresentModifier>( //
+ "PRESENT" >> pure(OmpPresentModifier::Value::Present)))
+
TYPE_PARSER(construct<OmpReductionModifier>(
"INSCAN" >> pure(OmpReductionModifier::Value::Inscan) ||
"TASK" >> pure(OmpReductionModifier::Value::Task) ||
"DEFAULT" >> pure(OmpReductionModifier::Value::Default)))
+TYPE_PARSER(construct<OmpRefModifier>( //
+ "REF_PTEE" >> pure(OmpRefModifier::Value::Ref_Ptee) ||
+ "REF_PTR"_id >> pure(OmpRefModifier::Value::Ref_Ptr) ||
+ "REF_PTR_PTEE" >> pure(OmpRefModifier::Value::Ref_Ptr_Ptee)))
+
+TYPE_PARSER(construct<OmpSelfModifier>( //
+ "SELF" >> pure(OmpSelfModifier::Value::Self)))
+
TYPE_PARSER(construct<OmpStepComplexModifier>( //
"STEP" >> parenthesized(scalarIntExpr)))
@@ -559,6 +573,9 @@ TYPE_PARSER(construct<OmpVariableCategory>(
"POINTER" >> pure(OmpVariableCategory::Value::Pointer) ||
"SCALAR" >> pure(OmpVariableCategory::Value::Scalar)))
+TYPE_PARSER(construct<OmpxHoldModifier>( //
+ "OMPX_HOLD" >> pure(OmpxHoldModifier::Value::Ompx_Hold)))
+
// This could be auto-generated.
TYPE_PARSER(
sourced(construct<OmpAffinityClause::Modifier>(Parser<OmpIterator>{})))
@@ -611,10 +628,16 @@ TYPE_PARSER(sourced(
construct<OmpLinearClause::Modifier>(Parser<OmpStepSimpleModifier>{})))
TYPE_PARSER(sourced(construct<OmpMapClause::Modifier>(
- sourced(construct<OmpMapClause::Modifier>(Parser<OmpMapTypeModifier>{}) ||
+ sourced(construct<OmpMapClause::Modifier>(Parser<OmpAlwaysModifier>{}) ||
+ construct<OmpMapClause::Modifier>(Parser<OmpCloseModifier>{}) ||
+ construct<OmpMapClause::Modifier>(Parser<OmpDeleteModifier>{}) ||
+ construct<OmpMapClause::Modifier>(Parser<OmpPresentModifier>{}) ||
+ construct<OmpMapClause::Modifier>(Parser<OmpRefModifier>{}) ||
+ construct<OmpMapClause::Modifier>(Parser<OmpSelfModifier>{}) ||
construct<OmpMapClause::Modifier>(Parser<OmpMapper>{}) ||
construct<OmpMapClause::Modifier>(Parser<OmpIterator>{}) ||
- construct<OmpMapClause::Modifier>(Parser<OmpMapType>{})))))
+ construct<OmpMapClause::Modifier>(Parser<OmpMapType>{}) ||
+ construct<OmpMapClause::Modifier>(Parser<OmpxHoldModifier>{})))))
TYPE_PARSER(
sourced(construct<OmpOrderClause::Modifier>(Parser<OmpOrderModifier>{})))
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index fbe89c6..8ed1690 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -3007,8 +3007,15 @@ public:
WALK_NESTED_ENUM(OmpPrescriptiveness, Value) // OMP prescriptiveness
WALK_NESTED_ENUM(OmpMapType, Value) // OMP map-type
WALK_NESTED_ENUM(OmpMapTypeModifier, Value) // OMP map-type-modifier
+ WALK_NESTED_ENUM(OmpAlwaysModifier, Value)
+ WALK_NESTED_ENUM(OmpCloseModifier, Value)
+ WALK_NESTED_ENUM(OmpDeleteModifier, Value)
+ WALK_NESTED_ENUM(OmpPresentModifier, Value)
+ WALK_NESTED_ENUM(OmpRefModifier, Value)
+ WALK_NESTED_ENUM(OmpSelfModifier, Value)
WALK_NESTED_ENUM(OmpTraitSelectorName, Value)
WALK_NESTED_ENUM(OmpTraitSetSelectorName, Value)
+ WALK_NESTED_ENUM(OmpxHoldModifier, Value)
#undef WALK_NESTED_ENUM
void Unparse(const ReductionOperator::Operator x) {
diff --git a/flang/lib/Semantics/canonicalize-omp.cpp b/flang/lib/Semantics/canonicalize-omp.cpp
index cf05d84..bba4d72 100644
--- a/flang/lib/Semantics/canonicalize-omp.cpp
+++ b/flang/lib/Semantics/canonicalize-omp.cpp
@@ -88,6 +88,8 @@ public:
CanonicalizeUtilityConstructs(spec);
}
+ void Post(parser::OmpMapClause &map) { CanonicalizeMapModifiers(map); }
+
private:
template <typename T> T *GetConstructIf(parser::ExecutionPartConstruct &x) {
if (auto *y{std::get_if<parser::ExecutableConstruct>(&x.u)}) {
@@ -390,6 +392,42 @@ private:
omps.erase(rlast.base(), omps.end());
}
+ // Map clause modifiers are parsed as per OpenMP 6.0 spec. That spec has
+ // changed properties of some of the modifiers, for example it has expanded
+ // map-type-modifier into 3 individual modifiers (one for each of the
+ // possible values of the original modifier), and the "map-type" modifier
+ // is no longer ultimate.
+ // To utilize the modifier validation framework for semantic checks,
+ // if the specified OpenMP version is less than 6.0, rewrite the affected
+ // modifiers back into the pre-6.0 forms.
+ void CanonicalizeMapModifiers(parser::OmpMapClause &map) {
+ // Omp{Always, Close, Present, xHold}Modifier -> OmpMapTypeModifier
+ // OmpDeleteModifier -> OmpMapType
+ using Modifier = parser::OmpMapClause::Modifier;
+ using Modifiers = std::optional<std::list<Modifier>>;
+ auto &modifiers{std::get<Modifiers>(map.t)};
+ if (!modifiers) {
+ return;
+ }
+
+ using MapTypeModifier = parser::OmpMapTypeModifier;
+ using MapType = parser::OmpMapType;
+
+ for (auto &mod : *modifiers) {
+ if (std::holds_alternative<parser::OmpAlwaysModifier>(mod.u)) {
+ mod.u = MapTypeModifier(MapTypeModifier::Value::Always);
+ } else if (std::holds_alternative<parser::OmpCloseModifier>(mod.u)) {
+ mod.u = MapTypeModifier(MapTypeModifier::Value::Close);
+ } else if (std::holds_alternative<parser::OmpPresentModifier>(mod.u)) {
+ mod.u = MapTypeModifier(MapTypeModifier::Value::Present);
+ } else if (std::holds_alternative<parser::OmpxHoldModifier>(mod.u)) {
+ mod.u = MapTypeModifier(MapTypeModifier::Value::Ompx_Hold);
+ } else if (std::holds_alternative<parser::OmpDeleteModifier>(mod.u)) {
+ mod.u = MapType(MapType::Value::Delete);
+ }
+ }
+ }
+
// Mapping from the specification parts to the blocks that follow in the
// same construct. This is for converting utility constructs to executable
// constructs.
diff --git a/flang/lib/Semantics/canonicalize-omp.h b/flang/lib/Semantics/canonicalize-omp.h
index c45d6bb..23350c5 100644
--- a/flang/lib/Semantics/canonicalize-omp.h
+++ b/flang/lib/Semantics/canonicalize-omp.h
@@ -15,7 +15,9 @@ class Messages;
} // namespace Fortran::parser
namespace Fortran::semantics {
+class SemanticsContext;
+
bool CanonicalizeOmp(parser::Messages &messages, parser::Program &program);
-}
+} // namespace Fortran::semantics
#endif // FORTRAN_SEMANTICS_CANONICALIZE_OMP_H_
diff --git a/flang/lib/Semantics/openmp-modifiers.cpp b/flang/lib/Semantics/openmp-modifiers.cpp
index c84e832..336ce4b 100644
--- a/flang/lib/Semantics/openmp-modifiers.cpp
+++ b/flang/lib/Semantics/openmp-modifiers.cpp
@@ -141,6 +141,22 @@ OmpGetDescriptor<parser::OmpAllocatorSimpleModifier>() {
}
template <>
+const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpAlwaysModifier>() {
+ static const OmpModifierDescriptor desc{
+ /*name=*/"always-modifier",
+ /*props=*/
+ {
+ {45, {OmpProperty::Unique}},
+ },
+ /*clauses=*/
+ {
+ {45, {Clause::OMPC_map}},
+ },
+ };
+ return desc;
+}
+
+template <>
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpChunkModifier>() {
static const OmpModifierDescriptor desc{
/*name=*/"chunk-modifier",
@@ -157,6 +173,22 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpChunkModifier>() {
}
template <>
+const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpCloseModifier>() {
+ static const OmpModifierDescriptor desc{
+ /*name=*/"close-modifier",
+ /*props=*/
+ {
+ {50, {OmpProperty::Unique}},
+ },
+ /*clauses=*/
+ {
+ {50, {Clause::OMPC_map}},
+ },
+ };
+ return desc;
+}
+
+template <>
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpContextSelector>() {
static const OmpModifierDescriptor desc{
/*name=*/"context-selector",
@@ -174,6 +206,23 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpContextSelector>() {
}
template <>
+const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpDeleteModifier>() {
+ static const OmpModifierDescriptor desc{
+ /*name=*/"delete-modifier",
+ /*props=*/
+ {
+ {45, {OmpProperty::Unique, OmpProperty::Ultimate}},
+ {60, {OmpProperty::Unique}},
+ },
+ /*clauses=*/
+ {
+ {45, {Clause::OMPC_map}},
+ },
+ };
+ return desc;
+}
+
+template <>
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpDependenceType>() {
static const OmpModifierDescriptor desc{
/*name=*/"dependence-type",
@@ -347,6 +396,7 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpMapType>() {
/*props=*/
{
{45, {OmpProperty::Ultimate}},
+ {60, {OmpProperty::Unique}},
},
/*clauses=*/
{
@@ -367,6 +417,7 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpMapTypeModifier>() {
/*clauses=*/
{
{45, {Clause::OMPC_map}},
+ {60, {}},
},
};
return desc;
@@ -421,6 +472,22 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpPrescriptiveness>() {
}
template <>
+const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpPresentModifier>() {
+ static const OmpModifierDescriptor desc{
+ /*name=*/"present-modifier",
+ /*props=*/
+ {
+ {51, {OmpProperty::Unique}},
+ },
+ /*clauses=*/
+ {
+ {51, {Clause::OMPC_map}},
+ },
+ };
+ return desc;
+}
+
+template <>
const OmpModifierDescriptor &
OmpGetDescriptor<parser::OmpReductionIdentifier>() {
static const OmpModifierDescriptor desc{
@@ -457,6 +524,38 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpReductionModifier>() {
}
template <>
+const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpRefModifier>() {
+ static const OmpModifierDescriptor desc{
+ /*name=*/"ref-modifier",
+ /*props=*/
+ {
+ {60, {OmpProperty::Unique}},
+ },
+ /*clauses=*/
+ {
+ {60, {Clause::OMPC_map}},
+ },
+ };
+ return desc;
+}
+
+template <>
+const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpSelfModifier>() {
+ static const OmpModifierDescriptor desc{
+ /*name=*/"self-modifier",
+ /*props=*/
+ {
+ {60, {OmpProperty::Unique}},
+ },
+ /*clauses=*/
+ {
+ {60, {Clause::OMPC_map}},
+ },
+ };
+ return desc;
+}
+
+template <>
const OmpModifierDescriptor &
OmpGetDescriptor<parser::OmpStepComplexModifier>() {
static const OmpModifierDescriptor desc{
@@ -522,4 +621,20 @@ const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpVariableCategory>() {
};
return desc;
}
+
+template <>
+const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpxHoldModifier>() {
+ static const OmpModifierDescriptor desc{
+ /*name=*/"ompx-hold-modifier",
+ /*props=*/
+ {
+ {45, {OmpProperty::Unique}},
+ },
+ /*clauses=*/
+ {
+ {45, {Clause::OMPC_map}},
+ },
+ };
+ return desc;
+}
} // namespace Fortran::semantics
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 521c743..332291a 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -749,6 +749,8 @@ public:
case parser::OmpMapType::Value::Delete:
ompFlag = Symbol::Flag::OmpMapDelete;
break;
+ default:
+ break;
}
}
const auto &ompObjList{std::get<parser::OmpObjectList>(x.t)};