-
Notifications
You must be signed in to change notification settings - Fork 14.5k
[flang][OpenMP] Sema checks, lowering with new format of MAP modifiers #149137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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.
OpenMP 6.0 has changed the modifiers on the MAP clause. Previous patch has introduced parsing support for them. This patch introduces processing of the new forms in semantic checks and in lowering. This only applies to existing modifiers, which were updated in the 6.0 spec. Any of the newly introduced modifiers (SELF and REF) are ignored.
@llvm/pr-subscribers-flang-fir-hlfir @llvm/pr-subscribers-flang-semantics Author: Krzysztof Parzyszek (kparzysz) ChangesOpenMP 6.0 has changed the modifiers on the MAP clause. Previous patch has introduced parsing support for them. This patch introduces processing of the new forms in semantic checks and in lowering. This only applies to existing modifiers, which were updated in the 6.0 spec. Any of the newly introduced modifiers (SELF and REF) are ignored. Patch is 27.27 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/149137.diff 14 Files Affected:
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index 74087d42a8e6e..ec71014c36093 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -1315,7 +1315,8 @@ bool ClauseProcessor::processMap(
const parser::CharBlock &source) {
using Map = omp::clause::Map;
mlir::Location clauseLocation = converter.genLocation(source);
- const auto &[mapType, typeMods, mappers, iterator, objects] = clause.t;
+ const auto &[mapType, typeMods, refMod, mappers, iterator, objects] =
+ clause.t;
llvm::omp::OpenMPOffloadMappingFlags mapTypeBits =
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_NONE;
std::string mapperIdName = "__implicit_mapper";
@@ -1342,16 +1343,13 @@ bool ClauseProcessor::processMap(
mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO |
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM;
break;
- case Map::MapType::Alloc:
- case Map::MapType::Release:
+ case Map::MapType::Storage:
// alloc and release is the default map_type for the Target Data
// Ops, i.e. if no bits for map_type is supplied then alloc/release
- // is implicitly assumed based on the target directive. Default
- // value for Target Data and Enter Data is alloc and for Exit Data
- // it is release.
+ // (aka storage in 6.0+) is implicitly assumed based on the target
+ // directive. Default value for Target Data and Enter Data is alloc
+ // and for Exit Data it is release.
break;
- case Map::MapType::Delete:
- mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_DELETE;
}
if (typeMods) {
@@ -1362,6 +1360,8 @@ bool ClauseProcessor::processMap(
mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_PRESENT;
if (llvm::is_contained(*typeMods, Map::MapTypeModifier::Close))
mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_CLOSE;
+ if (llvm::is_contained(*typeMods, Map::MapTypeModifier::Delete))
+ mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_DELETE;
if (llvm::is_contained(*typeMods, Map::MapTypeModifier::OmpxHold))
mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_OMPX_HOLD;
}
diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp
index 22a07219d3a50..18e49719b6013 100644
--- a/flang/lib/Lower/OpenMP/Clauses.cpp
+++ b/flang/lib/Lower/OpenMP/Clauses.cpp
@@ -1001,64 +1001,105 @@ Map make(const parser::OmpClause::Map &inp,
semantics::SemanticsContext &semaCtx) {
// inp.v -> parser::OmpMapClause
CLAUSET_ENUM_CONVERT( //
- convert1, parser::OmpMapType::Value, Map::MapType,
+ convert1, parser::OmpMapTypeModifier::Value, Map::MapTypeModifier,
// clang-format off
- MS(Alloc, Alloc)
- MS(Delete, Delete)
- MS(From, From)
- MS(Release, Release)
- MS(To, To)
- MS(Tofrom, Tofrom)
+ MS(Always, Always)
+ MS(Close, Close)
+ MS(Ompx_Hold, OmpxHold)
+ MS(Present, Present)
// clang-format on
);
CLAUSET_ENUM_CONVERT( //
- convert2, parser::OmpMapTypeModifier::Value, Map::MapTypeModifier,
+ convert2, parser::OmpRefModifier::Value, Map::RefModifier,
// clang-format off
- MS(Always, Always)
- MS(Close, Close)
- MS(Ompx_Hold, OmpxHold)
- MS(Present, Present)
+ MS(Ref_Ptee, RefPtee)
+ MS(Ref_Ptr, RefPtr)
+ MS(Ref_Ptr_Ptee, RefPtrPtee)
// clang-format on
);
+ // Treat always, close, present, self, delete modifiers as map-type-
+ // modifiers.
auto &mods = semantics::OmpGetModifiers(inp.v);
- auto *t1 = semantics::OmpGetUniqueModifier<parser::OmpMapper>(mods);
- auto *t2 = semantics::OmpGetUniqueModifier<parser::OmpIterator>(mods);
- auto *t3 = semantics::OmpGetUniqueModifier<parser::OmpMapType>(mods);
- auto &t4 = std::get<parser::OmpObjectList>(inp.v.t);
- auto mappers = [&]() -> std::optional<List<Mapper>> {
- if (t1)
- return List<Mapper>{Mapper{makeObject(t1->v, semaCtx)}};
- return std::nullopt;
- }();
-
- auto iterator = [&]() -> std::optional<Iterator> {
- if (t2)
- return makeIterator(*t2, semaCtx);
- return std::nullopt;
- }();
+ auto *t1 = semantics::OmpGetUniqueModifier<parser::OmpMapType>(mods);
+ auto &t2 = std::get<parser::OmpObjectList>(inp.v.t);
auto type = [&]() -> std::optional<Map::MapType> {
- if (t3)
- return convert1(t3->v);
- return std::nullopt;
+ std::optional<Map::MapType> type;
+ if (t1) {
+ switch (t1->v) {
+ case parser::OmpMapType::Value::Alloc:
+ case parser::OmpMapType::Value::Delete:
+ case parser::OmpMapType::Value::Release:
+ case parser::OmpMapType::Value::Storage:
+ type = Map::MapType::Storage;
+ break;
+ case parser::OmpMapType::Value::From:
+ type = Map::MapType::From;
+ break;
+ case parser::OmpMapType::Value::To:
+ type = Map::MapType::To;
+ break;
+ case parser::OmpMapType::Value::Tofrom:
+ type = Map::MapType::Tofrom;
+ break;
+ default:
+ break;
+ }
+ }
+ return type;
}();
- Map::MapTypeModifiers typeMods;
+ llvm::DenseSet<Map::MapTypeModifier> modSet;
+ if (t1 && t1->v == parser::OmpMapType::Value::Delete)
+ modSet.insert(Map::MapTypeModifier::Delete);
+
for (auto *typeMod :
semantics::OmpGetRepeatableModifier<parser::OmpMapTypeModifier>(mods)) {
- typeMods.push_back(convert2(typeMod->v));
+ modSet.insert(convert1(typeMod->v));
}
+ if (semantics::OmpGetUniqueModifier<parser::OmpAlwaysModifier>(mods))
+ modSet.insert(Map::MapTypeModifier::Always);
+ if (semantics::OmpGetUniqueModifier<parser::OmpCloseModifier>(mods))
+ modSet.insert(Map::MapTypeModifier::Close);
+ if (semantics::OmpGetUniqueModifier<parser::OmpDeleteModifier>(mods))
+ modSet.insert(Map::MapTypeModifier::Delete);
+ if (semantics::OmpGetUniqueModifier<parser::OmpPresentModifier>(mods))
+ modSet.insert(Map::MapTypeModifier::Present);
+ if (semantics::OmpGetUniqueModifier<parser::OmpSelfModifier>(mods))
+ modSet.insert(Map::MapTypeModifier::Self);
+ if (semantics::OmpGetUniqueModifier<parser::OmpxHoldModifier>(mods))
+ modSet.insert(Map::MapTypeModifier::OmpxHold);
+
std::optional<Map::MapTypeModifiers> maybeTypeMods{};
- if (!typeMods.empty())
- maybeTypeMods = std::move(typeMods);
+ if (!modSet.empty())
+ maybeTypeMods = Map::MapTypeModifiers(modSet.begin(), modSet.end());
+
+ auto refMod = [&]() -> std::optional<Map::RefModifier> {
+ if (auto *t = semantics::OmpGetUniqueModifier<parser::OmpRefModifier>(mods))
+ return convert2(t->v);
+ return std::nullopt;
+ }();
+
+ auto mappers = [&]() -> std::optional<List<Mapper>> {
+ if (auto *t = semantics::OmpGetUniqueModifier<parser::OmpMapper>(mods))
+ return List<Mapper>{Mapper{makeObject(t->v, semaCtx)}};
+ return std::nullopt;
+ }();
+
+ auto iterator = [&]() -> std::optional<Iterator> {
+ if (auto *t = semantics::OmpGetUniqueModifier<parser::OmpIterator>(mods))
+ return makeIterator(*t, semaCtx);
+ return std::nullopt;
+ }();
return Map{{/*MapType=*/std::move(type),
/*MapTypeModifiers=*/std::move(maybeTypeMods),
- /*Mapper=*/std::move(mappers), /*Iterator=*/std::move(iterator),
- /*LocatorList=*/makeObjects(t4, semaCtx)}};
+ /*RefModifier=*/std::move(refMod), /*Mapper=*/std::move(mappers),
+ /*Iterator=*/std::move(iterator),
+ /*LocatorList=*/makeObjects(t2, semaCtx)}};
}
Match make(const parser::OmpClause::Match &inp,
diff --git a/flang/lib/Semantics/canonicalize-omp.cpp b/flang/lib/Semantics/canonicalize-omp.cpp
index 46aaab19ded0a..77e2fd6ca5097 100644
--- a/flang/lib/Semantics/canonicalize-omp.cpp
+++ b/flang/lib/Semantics/canonicalize-omp.cpp
@@ -402,6 +402,11 @@ class CanonicalizationOfOmp {
// 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) {
+ unsigned version{context_.langOptions().OpenMPVersion};
+ if (version >= 60) {
+ return;
+ }
+
// Omp{Always, Close, Present, xHold}Modifier -> OmpMapTypeModifier
// OmpDeleteModifier -> OmpMapType
using Modifier = parser::OmpMapClause::Modifier;
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 2425265e196c6..94dee3d7afe21 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -37,6 +37,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Frontend/OpenMP/OMP.h"
@@ -3399,23 +3400,22 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Detach &x) {
}
}
-void OmpStructureChecker::CheckAllowedMapTypes(
- const parser::OmpMapType::Value &type,
- const std::list<parser::OmpMapType::Value> &allowedMapTypeList) {
- if (!llvm::is_contained(allowedMapTypeList, type)) {
- std::string commaSeparatedMapTypes;
- llvm::interleave(
- allowedMapTypeList.begin(), allowedMapTypeList.end(),
- [&](const parser::OmpMapType::Value &mapType) {
- commaSeparatedMapTypes.append(parser::ToUpperCaseLetters(
- parser::OmpMapType::EnumToString(mapType)));
- },
- [&] { commaSeparatedMapTypes.append(", "); });
- context_.Say(GetContext().clauseSource,
- "Only the %s map types are permitted "
- "for MAP clauses on the %s directive"_err_en_US,
- commaSeparatedMapTypes, ContextDirectiveAsFortran());
+void OmpStructureChecker::CheckAllowedMapTypes(parser::OmpMapType::Value type,
+ llvm::ArrayRef<parser::OmpMapType::Value> allowed) {
+ if (llvm::is_contained(allowed, type)) {
+ return;
}
+
+ llvm::SmallVector<std::string> names;
+ llvm::transform(
+ allowed, std::back_inserter(names), [](parser::OmpMapType::Value val) {
+ return parser::ToUpperCaseLetters(
+ parser::OmpMapType::EnumToString(val));
+ });
+ llvm::sort(names);
+ context_.Say(GetContext().clauseSource,
+ "Only the %s map types are permitted for MAP clauses on the %s directive"_err_en_US,
+ llvm::join(names, ", "), ContextDirectiveAsFortran());
}
void OmpStructureChecker::Enter(const parser::OmpClause::Map &x) {
@@ -3436,27 +3436,62 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Map &x) {
CheckIteratorModifier(*iter);
}
if (auto *type{OmpGetUniqueModifier<parser::OmpMapType>(modifiers)}) {
+ using Directive = llvm::omp::Directive;
using Value = parser::OmpMapType::Value;
- switch (GetContext().directive) {
- case llvm::omp::Directive::OMPD_target:
- case llvm::omp::Directive::OMPD_target_teams:
- case llvm::omp::Directive::OMPD_target_teams_distribute:
- case llvm::omp::Directive::OMPD_target_teams_distribute_simd:
- case llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do:
- case llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do_simd:
- case llvm::omp::Directive::OMPD_target_data:
- CheckAllowedMapTypes(
- type->v, {Value::To, Value::From, Value::Tofrom, Value::Alloc});
- break;
- case llvm::omp::Directive::OMPD_target_enter_data:
- CheckAllowedMapTypes(type->v, {Value::To, Value::Alloc});
- break;
- case llvm::omp::Directive::OMPD_target_exit_data:
- CheckAllowedMapTypes(
- type->v, {Value::From, Value::Release, Value::Delete});
- break;
- default:
- break;
+
+ static auto isValidForVersion{
+ [](parser::OmpMapType::Value t, unsigned version) {
+ switch (t) {
+ case parser::OmpMapType::Value::Alloc:
+ case parser::OmpMapType::Value::Delete:
+ case parser::OmpMapType::Value::Release:
+ return version < 60;
+ case parser::OmpMapType::Value::Storage:
+ return version >= 60;
+ default:
+ return true;
+ }
+ }};
+
+ llvm::SmallVector<parser::OmpMapType::Value> mapEnteringTypes{[&]() {
+ llvm::SmallVector<parser::OmpMapType::Value> result;
+ for (size_t i{0}; i != parser::OmpMapType::Value_enumSize; ++i) {
+ auto t{static_cast<parser::OmpMapType::Value>(i)};
+ if (isValidForVersion(t, version) && IsMapEnteringType(t)) {
+ result.push_back(t);
+ }
+ }
+ return result;
+ }()};
+ llvm::SmallVector<parser::OmpMapType::Value> mapExitingTypes{[&]() {
+ llvm::SmallVector<parser::OmpMapType::Value> result;
+ for (size_t i{0}; i != parser::OmpMapType::Value_enumSize; ++i) {
+ auto t{static_cast<parser::OmpMapType::Value>(i)};
+ if (isValidForVersion(t, version) && IsMapExitingType(t)) {
+ result.push_back(t);
+ }
+ }
+ return result;
+ }()};
+
+ llvm::omp::Directive dir{GetContext().directive};
+ llvm::ArrayRef<llvm::omp::Directive> leafs{
+ llvm::omp::getLeafConstructsOrSelf(dir)};
+
+ if (llvm::is_contained(leafs, Directive::OMPD_target) ||
+ llvm::is_contained(leafs, Directive::OMPD_target_data)) {
+ if (version >= 60) {
+ // Map types listed in the decay table. [6.0:276]
+ CheckAllowedMapTypes(
+ type->v, {Value::Storage, Value::From, Value::To, Value::Tofrom});
+ } else {
+ CheckAllowedMapTypes(
+ type->v, {Value::Alloc, Value::From, Value::To, Value::Tofrom});
+ }
+ } else if (llvm::is_contained(leafs, Directive::OMPD_target_enter_data)) {
+ CheckAllowedMapTypes(type->v, mapEnteringTypes);
+ } else if (llvm::is_contained(leafs, Directive::OMPD_target_exit_data)) {
+ CheckAllowedMapTypes(type->v, mapExitingTypes);
}
}
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 6a877a5d0a7c0..f4a291dc255c8 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -179,8 +179,8 @@ class OmpStructureChecker
void HasInvalidDistributeNesting(const parser::OpenMPLoopConstruct &x);
void HasInvalidLoopBinding(const parser::OpenMPLoopConstruct &x);
// specific clause related
- void CheckAllowedMapTypes(const parser::OmpMapType::Value &,
- const std::list<parser::OmpMapType::Value> &);
+ void CheckAllowedMapTypes(
+ parser::OmpMapType::Value, llvm::ArrayRef<parser::OmpMapType::Value>);
const std::list<parser::OmpTraitProperty> &GetTraitPropertyList(
const parser::OmpTraitSelector &);
diff --git a/flang/lib/Semantics/openmp-utils.cpp b/flang/lib/Semantics/openmp-utils.cpp
index f43d2cc75620e..da14507aa9fe6 100644
--- a/flang/lib/Semantics/openmp-utils.cpp
+++ b/flang/lib/Semantics/openmp-utils.cpp
@@ -143,6 +143,31 @@ bool IsVarOrFunctionRef(const MaybeExpr &expr) {
}
}
+bool IsMapEnteringType(parser::OmpMapType::Value type) {
+ switch (type) {
+ case parser::OmpMapType::Value::Alloc:
+ case parser::OmpMapType::Value::Storage:
+ case parser::OmpMapType::Value::To:
+ case parser::OmpMapType::Value::Tofrom:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsMapExitingType(parser::OmpMapType::Value type) {
+ switch (type) {
+ case parser::OmpMapType::Value::Delete:
+ case parser::OmpMapType::Value::From:
+ case parser::OmpMapType::Value::Release:
+ case parser::OmpMapType::Value::Storage:
+ case parser::OmpMapType::Value::Tofrom:
+ return true;
+ default:
+ return false;
+ }
+}
+
std::optional<SomeExpr> GetEvaluateExpr(const parser::Expr &parserExpr) {
const parser::TypedExpr &typedExpr{parserExpr.typedExpr};
// ForwardOwningPointer typedExpr
diff --git a/flang/lib/Semantics/openmp-utils.h b/flang/lib/Semantics/openmp-utils.h
index a96c008fb26e7..001fbeb45ceec 100644
--- a/flang/lib/Semantics/openmp-utils.h
+++ b/flang/lib/Semantics/openmp-utils.h
@@ -59,6 +59,9 @@ bool IsExtendedListItem(const Symbol &sym);
bool IsVariableListItem(const Symbol &sym);
bool IsVarOrFunctionRef(const MaybeExpr &expr);
+bool IsMapEnteringType(parser::OmpMapType::Value type);
+bool IsMapExitingType(parser::OmpMapType::Value type);
+
std::optional<SomeExpr> GetEvaluateExpr(const parser::Expr &parserExpr);
std::optional<evaluate::DynamicType> GetDynamicType(
const parser::Expr &parserExpr);
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 0b860314b4a1f..cbd14bc259d38 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -712,7 +712,15 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
void Post(const parser::EorLabel &eorLabel) { CheckSourceLabel(eorLabel.v); }
void Post(const parser::OmpMapClause &x) {
- Symbol::Flag ompFlag = Symbol::Flag::OmpMapToFrom;
+ unsigned version{context_.langOptions().OpenMPVersion};
+ llvm::omp::Directive id{GetContext().directive};
+ std::optional<Symbol::Flag> ompFlag;
+ // Expand "storage" into either "alloc" or "release", depending on the
+ // type of the construct.
+ Symbol::Flag ompFlagForStorage = llvm::omp::isMapEnteringConstruct(id)
+ ? Symbol::Flag::OmpMapAlloc
+ : Symbol::Flag::OmpMapRelease;
+
auto &mods{OmpGetModifiers(x)};
if (auto *mapType{OmpGetUniqueModifier<parser::OmpMapType>(mods)}) {
switch (mapType->v) {
@@ -734,10 +742,29 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
case parser::OmpMapType::Value::Delete:
ompFlag = Symbol::Flag::OmpMapDelete;
break;
- default:
+ case parser::OmpMapType::Value::Storage:
+ ompFlag = ompFlagForStorage;
break;
}
}
+ if (!ompFlag) {
+ if (version >= 60) {
+ // [6.0:275:12-15]
+ // When a map-type is not specified for a clause on which it may be
+ // specified, the map-type defaults to storage if the delete-modifier
+ // is present on the clause or if the list item for which the map-type
+ // is not specified is an assumed-size array.
+ if (OmpGetUniqueModifier<parser::OmpDeleteModifier>(mods)) {
+ ompFlag = ompFlagForStorage;
+ }
+ // Otherwise, if delete-modifier is absent, leave ompFlag unset.
+ } else {
+ // [5.2:151:10]
+ // If a map-type is not specified, the map-type defaults to tofrom.
+ ompFlag = Symbol::Flag::OmpMapToFrom;
+ }
+ }
+
const auto &ompObjList{std::get<parser::OmpObjectList>(x.t)};
for (const auto &ompObj : ompObjList.v) {
common::visit(
@@ -746,15 +773,14 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
if (const auto *name{
semantics::getDesignatorNameIfDataRef(designator)}) {
if (name->symbol) {
- name->symbol->set(ompFlag);
- AddToContextObjectWithDSA(*name->symbol, ompFlag);
- }
- if (name->symbol &&
- semantics::IsAssumedSizeArray(*name->symbol)) {
- context_.Say(designator.source,
- "Assumed-size whole arrays may not appear on the %s "
- "clause"_err_en_US,
- "MAP");
+ name->symbol->set(ompFlag.value_or(ompFlagForStorage));
+ AddToContextObjectWithDSA(*name->symbol, *ompFlag);
+ if (semantics::IsAssumedSizeArray(*name->symbol)) {
+ context_.Say(designator.source,
+ "Assumed-size whole arrays may not appear on the %s "
+ "clause"_err_en_US,
+ "MAP");
+ }
}
}
},
@@ -762,7 +788,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
},
ompObj.u);
- ResolveOmpObject(ompObj, ompFlag);
+ ResolveOmpObject(ompObj, ompFlag.value_or(...
[truncated]
|
@llvm/pr-subscribers-flang-openmp Author: Krzysztof Parzyszek (kparzysz) ChangesOpenMP 6.0 has changed the modifiers on the MAP clause. Previous patch has introduced parsing support for them. This patch introduces processing of the new forms in semantic checks and in lowering. This only applies to existing modifiers, which were updated in the 6.0 spec. Any of the newly introduced modifiers (SELF and REF) are ignored. Patch is 27.27 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/149137.diff 14 Files Affected:
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index 74087d42a8e6e..ec71014c36093 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -1315,7 +1315,8 @@ bool ClauseProcessor::processMap(
const parser::CharBlock &source) {
using Map = omp::clause::Map;
mlir::Location clauseLocation = converter.genLocation(source);
- const auto &[mapType, typeMods, mappers, iterator, objects] = clause.t;
+ const auto &[mapType, typeMods, refMod, mappers, iterator, objects] =
+ clause.t;
llvm::omp::OpenMPOffloadMappingFlags mapTypeBits =
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_NONE;
std::string mapperIdName = "__implicit_mapper";
@@ -1342,16 +1343,13 @@ bool ClauseProcessor::processMap(
mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_TO |
llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_FROM;
break;
- case Map::MapType::Alloc:
- case Map::MapType::Release:
+ case Map::MapType::Storage:
// alloc and release is the default map_type for the Target Data
// Ops, i.e. if no bits for map_type is supplied then alloc/release
- // is implicitly assumed based on the target directive. Default
- // value for Target Data and Enter Data is alloc and for Exit Data
- // it is release.
+ // (aka storage in 6.0+) is implicitly assumed based on the target
+ // directive. Default value for Target Data and Enter Data is alloc
+ // and for Exit Data it is release.
break;
- case Map::MapType::Delete:
- mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_DELETE;
}
if (typeMods) {
@@ -1362,6 +1360,8 @@ bool ClauseProcessor::processMap(
mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_PRESENT;
if (llvm::is_contained(*typeMods, Map::MapTypeModifier::Close))
mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_CLOSE;
+ if (llvm::is_contained(*typeMods, Map::MapTypeModifier::Delete))
+ mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_DELETE;
if (llvm::is_contained(*typeMods, Map::MapTypeModifier::OmpxHold))
mapTypeBits |= llvm::omp::OpenMPOffloadMappingFlags::OMP_MAP_OMPX_HOLD;
}
diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp
index 22a07219d3a50..18e49719b6013 100644
--- a/flang/lib/Lower/OpenMP/Clauses.cpp
+++ b/flang/lib/Lower/OpenMP/Clauses.cpp
@@ -1001,64 +1001,105 @@ Map make(const parser::OmpClause::Map &inp,
semantics::SemanticsContext &semaCtx) {
// inp.v -> parser::OmpMapClause
CLAUSET_ENUM_CONVERT( //
- convert1, parser::OmpMapType::Value, Map::MapType,
+ convert1, parser::OmpMapTypeModifier::Value, Map::MapTypeModifier,
// clang-format off
- MS(Alloc, Alloc)
- MS(Delete, Delete)
- MS(From, From)
- MS(Release, Release)
- MS(To, To)
- MS(Tofrom, Tofrom)
+ MS(Always, Always)
+ MS(Close, Close)
+ MS(Ompx_Hold, OmpxHold)
+ MS(Present, Present)
// clang-format on
);
CLAUSET_ENUM_CONVERT( //
- convert2, parser::OmpMapTypeModifier::Value, Map::MapTypeModifier,
+ convert2, parser::OmpRefModifier::Value, Map::RefModifier,
// clang-format off
- MS(Always, Always)
- MS(Close, Close)
- MS(Ompx_Hold, OmpxHold)
- MS(Present, Present)
+ MS(Ref_Ptee, RefPtee)
+ MS(Ref_Ptr, RefPtr)
+ MS(Ref_Ptr_Ptee, RefPtrPtee)
// clang-format on
);
+ // Treat always, close, present, self, delete modifiers as map-type-
+ // modifiers.
auto &mods = semantics::OmpGetModifiers(inp.v);
- auto *t1 = semantics::OmpGetUniqueModifier<parser::OmpMapper>(mods);
- auto *t2 = semantics::OmpGetUniqueModifier<parser::OmpIterator>(mods);
- auto *t3 = semantics::OmpGetUniqueModifier<parser::OmpMapType>(mods);
- auto &t4 = std::get<parser::OmpObjectList>(inp.v.t);
- auto mappers = [&]() -> std::optional<List<Mapper>> {
- if (t1)
- return List<Mapper>{Mapper{makeObject(t1->v, semaCtx)}};
- return std::nullopt;
- }();
-
- auto iterator = [&]() -> std::optional<Iterator> {
- if (t2)
- return makeIterator(*t2, semaCtx);
- return std::nullopt;
- }();
+ auto *t1 = semantics::OmpGetUniqueModifier<parser::OmpMapType>(mods);
+ auto &t2 = std::get<parser::OmpObjectList>(inp.v.t);
auto type = [&]() -> std::optional<Map::MapType> {
- if (t3)
- return convert1(t3->v);
- return std::nullopt;
+ std::optional<Map::MapType> type;
+ if (t1) {
+ switch (t1->v) {
+ case parser::OmpMapType::Value::Alloc:
+ case parser::OmpMapType::Value::Delete:
+ case parser::OmpMapType::Value::Release:
+ case parser::OmpMapType::Value::Storage:
+ type = Map::MapType::Storage;
+ break;
+ case parser::OmpMapType::Value::From:
+ type = Map::MapType::From;
+ break;
+ case parser::OmpMapType::Value::To:
+ type = Map::MapType::To;
+ break;
+ case parser::OmpMapType::Value::Tofrom:
+ type = Map::MapType::Tofrom;
+ break;
+ default:
+ break;
+ }
+ }
+ return type;
}();
- Map::MapTypeModifiers typeMods;
+ llvm::DenseSet<Map::MapTypeModifier> modSet;
+ if (t1 && t1->v == parser::OmpMapType::Value::Delete)
+ modSet.insert(Map::MapTypeModifier::Delete);
+
for (auto *typeMod :
semantics::OmpGetRepeatableModifier<parser::OmpMapTypeModifier>(mods)) {
- typeMods.push_back(convert2(typeMod->v));
+ modSet.insert(convert1(typeMod->v));
}
+ if (semantics::OmpGetUniqueModifier<parser::OmpAlwaysModifier>(mods))
+ modSet.insert(Map::MapTypeModifier::Always);
+ if (semantics::OmpGetUniqueModifier<parser::OmpCloseModifier>(mods))
+ modSet.insert(Map::MapTypeModifier::Close);
+ if (semantics::OmpGetUniqueModifier<parser::OmpDeleteModifier>(mods))
+ modSet.insert(Map::MapTypeModifier::Delete);
+ if (semantics::OmpGetUniqueModifier<parser::OmpPresentModifier>(mods))
+ modSet.insert(Map::MapTypeModifier::Present);
+ if (semantics::OmpGetUniqueModifier<parser::OmpSelfModifier>(mods))
+ modSet.insert(Map::MapTypeModifier::Self);
+ if (semantics::OmpGetUniqueModifier<parser::OmpxHoldModifier>(mods))
+ modSet.insert(Map::MapTypeModifier::OmpxHold);
+
std::optional<Map::MapTypeModifiers> maybeTypeMods{};
- if (!typeMods.empty())
- maybeTypeMods = std::move(typeMods);
+ if (!modSet.empty())
+ maybeTypeMods = Map::MapTypeModifiers(modSet.begin(), modSet.end());
+
+ auto refMod = [&]() -> std::optional<Map::RefModifier> {
+ if (auto *t = semantics::OmpGetUniqueModifier<parser::OmpRefModifier>(mods))
+ return convert2(t->v);
+ return std::nullopt;
+ }();
+
+ auto mappers = [&]() -> std::optional<List<Mapper>> {
+ if (auto *t = semantics::OmpGetUniqueModifier<parser::OmpMapper>(mods))
+ return List<Mapper>{Mapper{makeObject(t->v, semaCtx)}};
+ return std::nullopt;
+ }();
+
+ auto iterator = [&]() -> std::optional<Iterator> {
+ if (auto *t = semantics::OmpGetUniqueModifier<parser::OmpIterator>(mods))
+ return makeIterator(*t, semaCtx);
+ return std::nullopt;
+ }();
return Map{{/*MapType=*/std::move(type),
/*MapTypeModifiers=*/std::move(maybeTypeMods),
- /*Mapper=*/std::move(mappers), /*Iterator=*/std::move(iterator),
- /*LocatorList=*/makeObjects(t4, semaCtx)}};
+ /*RefModifier=*/std::move(refMod), /*Mapper=*/std::move(mappers),
+ /*Iterator=*/std::move(iterator),
+ /*LocatorList=*/makeObjects(t2, semaCtx)}};
}
Match make(const parser::OmpClause::Match &inp,
diff --git a/flang/lib/Semantics/canonicalize-omp.cpp b/flang/lib/Semantics/canonicalize-omp.cpp
index 46aaab19ded0a..77e2fd6ca5097 100644
--- a/flang/lib/Semantics/canonicalize-omp.cpp
+++ b/flang/lib/Semantics/canonicalize-omp.cpp
@@ -402,6 +402,11 @@ class CanonicalizationOfOmp {
// 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) {
+ unsigned version{context_.langOptions().OpenMPVersion};
+ if (version >= 60) {
+ return;
+ }
+
// Omp{Always, Close, Present, xHold}Modifier -> OmpMapTypeModifier
// OmpDeleteModifier -> OmpMapType
using Modifier = parser::OmpMapClause::Modifier;
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 2425265e196c6..94dee3d7afe21 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -37,6 +37,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Frontend/OpenMP/OMP.h"
@@ -3399,23 +3400,22 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Detach &x) {
}
}
-void OmpStructureChecker::CheckAllowedMapTypes(
- const parser::OmpMapType::Value &type,
- const std::list<parser::OmpMapType::Value> &allowedMapTypeList) {
- if (!llvm::is_contained(allowedMapTypeList, type)) {
- std::string commaSeparatedMapTypes;
- llvm::interleave(
- allowedMapTypeList.begin(), allowedMapTypeList.end(),
- [&](const parser::OmpMapType::Value &mapType) {
- commaSeparatedMapTypes.append(parser::ToUpperCaseLetters(
- parser::OmpMapType::EnumToString(mapType)));
- },
- [&] { commaSeparatedMapTypes.append(", "); });
- context_.Say(GetContext().clauseSource,
- "Only the %s map types are permitted "
- "for MAP clauses on the %s directive"_err_en_US,
- commaSeparatedMapTypes, ContextDirectiveAsFortran());
+void OmpStructureChecker::CheckAllowedMapTypes(parser::OmpMapType::Value type,
+ llvm::ArrayRef<parser::OmpMapType::Value> allowed) {
+ if (llvm::is_contained(allowed, type)) {
+ return;
}
+
+ llvm::SmallVector<std::string> names;
+ llvm::transform(
+ allowed, std::back_inserter(names), [](parser::OmpMapType::Value val) {
+ return parser::ToUpperCaseLetters(
+ parser::OmpMapType::EnumToString(val));
+ });
+ llvm::sort(names);
+ context_.Say(GetContext().clauseSource,
+ "Only the %s map types are permitted for MAP clauses on the %s directive"_err_en_US,
+ llvm::join(names, ", "), ContextDirectiveAsFortran());
}
void OmpStructureChecker::Enter(const parser::OmpClause::Map &x) {
@@ -3436,27 +3436,62 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Map &x) {
CheckIteratorModifier(*iter);
}
if (auto *type{OmpGetUniqueModifier<parser::OmpMapType>(modifiers)}) {
+ using Directive = llvm::omp::Directive;
using Value = parser::OmpMapType::Value;
- switch (GetContext().directive) {
- case llvm::omp::Directive::OMPD_target:
- case llvm::omp::Directive::OMPD_target_teams:
- case llvm::omp::Directive::OMPD_target_teams_distribute:
- case llvm::omp::Directive::OMPD_target_teams_distribute_simd:
- case llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do:
- case llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do_simd:
- case llvm::omp::Directive::OMPD_target_data:
- CheckAllowedMapTypes(
- type->v, {Value::To, Value::From, Value::Tofrom, Value::Alloc});
- break;
- case llvm::omp::Directive::OMPD_target_enter_data:
- CheckAllowedMapTypes(type->v, {Value::To, Value::Alloc});
- break;
- case llvm::omp::Directive::OMPD_target_exit_data:
- CheckAllowedMapTypes(
- type->v, {Value::From, Value::Release, Value::Delete});
- break;
- default:
- break;
+
+ static auto isValidForVersion{
+ [](parser::OmpMapType::Value t, unsigned version) {
+ switch (t) {
+ case parser::OmpMapType::Value::Alloc:
+ case parser::OmpMapType::Value::Delete:
+ case parser::OmpMapType::Value::Release:
+ return version < 60;
+ case parser::OmpMapType::Value::Storage:
+ return version >= 60;
+ default:
+ return true;
+ }
+ }};
+
+ llvm::SmallVector<parser::OmpMapType::Value> mapEnteringTypes{[&]() {
+ llvm::SmallVector<parser::OmpMapType::Value> result;
+ for (size_t i{0}; i != parser::OmpMapType::Value_enumSize; ++i) {
+ auto t{static_cast<parser::OmpMapType::Value>(i)};
+ if (isValidForVersion(t, version) && IsMapEnteringType(t)) {
+ result.push_back(t);
+ }
+ }
+ return result;
+ }()};
+ llvm::SmallVector<parser::OmpMapType::Value> mapExitingTypes{[&]() {
+ llvm::SmallVector<parser::OmpMapType::Value> result;
+ for (size_t i{0}; i != parser::OmpMapType::Value_enumSize; ++i) {
+ auto t{static_cast<parser::OmpMapType::Value>(i)};
+ if (isValidForVersion(t, version) && IsMapExitingType(t)) {
+ result.push_back(t);
+ }
+ }
+ return result;
+ }()};
+
+ llvm::omp::Directive dir{GetContext().directive};
+ llvm::ArrayRef<llvm::omp::Directive> leafs{
+ llvm::omp::getLeafConstructsOrSelf(dir)};
+
+ if (llvm::is_contained(leafs, Directive::OMPD_target) ||
+ llvm::is_contained(leafs, Directive::OMPD_target_data)) {
+ if (version >= 60) {
+ // Map types listed in the decay table. [6.0:276]
+ CheckAllowedMapTypes(
+ type->v, {Value::Storage, Value::From, Value::To, Value::Tofrom});
+ } else {
+ CheckAllowedMapTypes(
+ type->v, {Value::Alloc, Value::From, Value::To, Value::Tofrom});
+ }
+ } else if (llvm::is_contained(leafs, Directive::OMPD_target_enter_data)) {
+ CheckAllowedMapTypes(type->v, mapEnteringTypes);
+ } else if (llvm::is_contained(leafs, Directive::OMPD_target_exit_data)) {
+ CheckAllowedMapTypes(type->v, mapExitingTypes);
}
}
diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h
index 6a877a5d0a7c0..f4a291dc255c8 100644
--- a/flang/lib/Semantics/check-omp-structure.h
+++ b/flang/lib/Semantics/check-omp-structure.h
@@ -179,8 +179,8 @@ class OmpStructureChecker
void HasInvalidDistributeNesting(const parser::OpenMPLoopConstruct &x);
void HasInvalidLoopBinding(const parser::OpenMPLoopConstruct &x);
// specific clause related
- void CheckAllowedMapTypes(const parser::OmpMapType::Value &,
- const std::list<parser::OmpMapType::Value> &);
+ void CheckAllowedMapTypes(
+ parser::OmpMapType::Value, llvm::ArrayRef<parser::OmpMapType::Value>);
const std::list<parser::OmpTraitProperty> &GetTraitPropertyList(
const parser::OmpTraitSelector &);
diff --git a/flang/lib/Semantics/openmp-utils.cpp b/flang/lib/Semantics/openmp-utils.cpp
index f43d2cc75620e..da14507aa9fe6 100644
--- a/flang/lib/Semantics/openmp-utils.cpp
+++ b/flang/lib/Semantics/openmp-utils.cpp
@@ -143,6 +143,31 @@ bool IsVarOrFunctionRef(const MaybeExpr &expr) {
}
}
+bool IsMapEnteringType(parser::OmpMapType::Value type) {
+ switch (type) {
+ case parser::OmpMapType::Value::Alloc:
+ case parser::OmpMapType::Value::Storage:
+ case parser::OmpMapType::Value::To:
+ case parser::OmpMapType::Value::Tofrom:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool IsMapExitingType(parser::OmpMapType::Value type) {
+ switch (type) {
+ case parser::OmpMapType::Value::Delete:
+ case parser::OmpMapType::Value::From:
+ case parser::OmpMapType::Value::Release:
+ case parser::OmpMapType::Value::Storage:
+ case parser::OmpMapType::Value::Tofrom:
+ return true;
+ default:
+ return false;
+ }
+}
+
std::optional<SomeExpr> GetEvaluateExpr(const parser::Expr &parserExpr) {
const parser::TypedExpr &typedExpr{parserExpr.typedExpr};
// ForwardOwningPointer typedExpr
diff --git a/flang/lib/Semantics/openmp-utils.h b/flang/lib/Semantics/openmp-utils.h
index a96c008fb26e7..001fbeb45ceec 100644
--- a/flang/lib/Semantics/openmp-utils.h
+++ b/flang/lib/Semantics/openmp-utils.h
@@ -59,6 +59,9 @@ bool IsExtendedListItem(const Symbol &sym);
bool IsVariableListItem(const Symbol &sym);
bool IsVarOrFunctionRef(const MaybeExpr &expr);
+bool IsMapEnteringType(parser::OmpMapType::Value type);
+bool IsMapExitingType(parser::OmpMapType::Value type);
+
std::optional<SomeExpr> GetEvaluateExpr(const parser::Expr &parserExpr);
std::optional<evaluate::DynamicType> GetDynamicType(
const parser::Expr &parserExpr);
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 0b860314b4a1f..cbd14bc259d38 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -712,7 +712,15 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
void Post(const parser::EorLabel &eorLabel) { CheckSourceLabel(eorLabel.v); }
void Post(const parser::OmpMapClause &x) {
- Symbol::Flag ompFlag = Symbol::Flag::OmpMapToFrom;
+ unsigned version{context_.langOptions().OpenMPVersion};
+ llvm::omp::Directive id{GetContext().directive};
+ std::optional<Symbol::Flag> ompFlag;
+ // Expand "storage" into either "alloc" or "release", depending on the
+ // type of the construct.
+ Symbol::Flag ompFlagForStorage = llvm::omp::isMapEnteringConstruct(id)
+ ? Symbol::Flag::OmpMapAlloc
+ : Symbol::Flag::OmpMapRelease;
+
auto &mods{OmpGetModifiers(x)};
if (auto *mapType{OmpGetUniqueModifier<parser::OmpMapType>(mods)}) {
switch (mapType->v) {
@@ -734,10 +742,29 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
case parser::OmpMapType::Value::Delete:
ompFlag = Symbol::Flag::OmpMapDelete;
break;
- default:
+ case parser::OmpMapType::Value::Storage:
+ ompFlag = ompFlagForStorage;
break;
}
}
+ if (!ompFlag) {
+ if (version >= 60) {
+ // [6.0:275:12-15]
+ // When a map-type is not specified for a clause on which it may be
+ // specified, the map-type defaults to storage if the delete-modifier
+ // is present on the clause or if the list item for which the map-type
+ // is not specified is an assumed-size array.
+ if (OmpGetUniqueModifier<parser::OmpDeleteModifier>(mods)) {
+ ompFlag = ompFlagForStorage;
+ }
+ // Otherwise, if delete-modifier is absent, leave ompFlag unset.
+ } else {
+ // [5.2:151:10]
+ // If a map-type is not specified, the map-type defaults to tofrom.
+ ompFlag = Symbol::Flag::OmpMapToFrom;
+ }
+ }
+
const auto &ompObjList{std::get<parser::OmpObjectList>(x.t)};
for (const auto &ompObj : ompObjList.v) {
common::visit(
@@ -746,15 +773,14 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
if (const auto *name{
semantics::getDesignatorNameIfDataRef(designator)}) {
if (name->symbol) {
- name->symbol->set(ompFlag);
- AddToContextObjectWithDSA(*name->symbol, ompFlag);
- }
- if (name->symbol &&
- semantics::IsAssumedSizeArray(*name->symbol)) {
- context_.Say(designator.source,
- "Assumed-size whole arrays may not appear on the %s "
- "clause"_err_en_US,
- "MAP");
+ name->symbol->set(ompFlag.value_or(ompFlagForStorage));
+ AddToContextObjectWithDSA(*name->symbol, *ompFlag);
+ if (semantics::IsAssumedSizeArray(*name->symbol)) {
+ context_.Say(designator.source,
+ "Assumed-size whole arrays may not appear on the %s "
+ "clause"_err_en_US,
+ "MAP");
+ }
}
}
},
@@ -762,7 +788,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
},
ompObj.u);
- ResolveOmpObject(ompObj, ompFlag);
+ ResolveOmpObject(ompObj, ompFlag.value_or(...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please could you add a lit tests for lowering: one showing OpenMP 5 style modifiers being converted to the new ones, and one showing the new ones working in OpenMP 6.0.
flang/lib/Lower/OpenMP/Clauses.cpp
Outdated
@@ -1003,12 +1003,13 @@ Map make(const parser::OmpClause::Map &inp, | |||
CLAUSET_ENUM_CONVERT( // | |||
convert1, parser::OmpMapType::Value, Map::MapType, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not new in this patch, but I don't really like the convert1
convert2
convert3
naming. It makes the later code harder to follow than it needs to be.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -402,6 +402,11 @@ class CanonicalizationOfOmp { | |||
// 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) { | |||
unsigned version{context_.langOptions().OpenMPVersion}; | |||
if (version >= 60) { | |||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we warn about the new map modifiers being used with older versions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The OmpValidateModifiiers function should be doing that. I can add a testcase for that.
There is a parsing test that shows the conversion, plus parsing of the new modifiers (in the parsing PR). Do you want something specific to lowering, e.g. show the same MLIR generated for a given modifier with -fopenmp-version=52 and 60? |
We're using "storage" instead of "alloc"/"release" in lowering, this will make things more consistent.
Ahh okay. Maybe we only need one test then, but it would be good to make sure this makes it through the clause processor okay. |
I added more RUN lines to flang/test/Lower/OpenMP/map-modifiers.f90 with different versions, plus a test for "always" modifier. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates. LGTM
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/157/builds/34563 Here is the relevant piece of the build log for the reference
|
CanonicalizationOfOmp(SemanticsContext &context) | ||
: context_{context}, messages_{context.messages()} {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This adds a use of SemanticContext
without including its header file. This means the build was failing when precompiled headers are disabled.
See https://lab.llvm.org/staging/#/builders/36/builds/21866
Fixed in 0586067
OpenMP 6.0 has changed the modifiers on the MAP clause. Previous patch has introduced parsing support for them. This patch introduces processing of the new forms in semantic checks and in lowering. This only applies to existing modifiers, which were updated in the 6.0 spec. Any of the newly introduced modifiers (SELF and REF) are ignored.