aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--flang/examples/FeatureList/FeatureList.cpp8
-rw-r--r--flang/include/flang/Parser/dump-parse-tree.h8
-rw-r--r--flang/include/flang/Parser/parse-tree.h52
-rw-r--r--flang/include/flang/Semantics/openmp-modifiers.h19
-rw-r--r--flang/lib/Lower/OpenMP/ClauseProcessor.cpp6
-rw-r--r--flang/lib/Lower/OpenMP/Clauses.cpp56
-rw-r--r--flang/lib/Lower/OpenMP/Clauses.h5
-rw-r--r--flang/lib/Parser/openmp-parsers.cpp45
-rw-r--r--flang/lib/Parser/unparse.cpp32
-rw-r--r--flang/lib/Semantics/check-omp-structure.cpp48
-rw-r--r--flang/lib/Semantics/openmp-modifiers.cpp50
-rw-r--r--flang/lib/Semantics/resolve-directives.cpp13
-rw-r--r--flang/test/Parser/OpenMP/allocators-unparse.f9019
-rw-r--r--flang/test/Semantics/OpenMP/allocate-clause01.f9010
-rw-r--r--flang/test/Semantics/OpenMP/allocators01.f902
-rw-r--r--flang/test/Semantics/OpenMP/allocators04.f902
-rw-r--r--flang/test/Semantics/OpenMP/allocators05.f902
-rw-r--r--flang/test/Semantics/OpenMP/allocators06.f902
-rw-r--r--flang/test/Semantics/OpenMP/resolve06.f902
-rw-r--r--llvm/include/llvm/Frontend/OpenMP/ClauseT.h6
-rw-r--r--llvm/unittests/Frontend/OpenMPDecompositionTest.cpp50
21 files changed, 231 insertions, 206 deletions
diff --git a/flang/examples/FeatureList/FeatureList.cpp b/flang/examples/FeatureList/FeatureList.cpp
index 6ae92ac..f7086b9 100644
--- a/flang/examples/FeatureList/FeatureList.cpp
+++ b/flang/examples/FeatureList/FeatureList.cpp
@@ -516,10 +516,10 @@ public:
READ_FEATURE(OmpReductionInitializerClause)
READ_FEATURE(OmpReductionIdentifier)
READ_FEATURE(OmpAllocateClause)
- READ_FEATURE(OmpAllocateClause::AllocateModifier)
- READ_FEATURE(OmpAllocateClause::AllocateModifier::Allocator)
- READ_FEATURE(OmpAllocateClause::AllocateModifier::ComplexModifier)
- READ_FEATURE(OmpAllocateClause::AllocateModifier::Align)
+ READ_FEATURE(OmpAllocateClause::Modifier)
+ READ_FEATURE(OmpAllocatorSimpleModifier)
+ READ_FEATURE(OmpAllocatorComplexModifier)
+ READ_FEATURE(OmpAlignModifier)
READ_FEATURE(OmpScheduleClause)
READ_FEATURE(OmpScheduleClause::Kind)
READ_FEATURE(OmpScheduleClause::Modifier)
diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h
index 68f9406..d499b41 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -586,10 +586,10 @@ public:
NODE(parser, OmpReductionInitializerClause)
NODE(parser, OmpReductionIdentifier)
NODE(parser, OmpAllocateClause)
- NODE(OmpAllocateClause, AllocateModifier)
- NODE(OmpAllocateClause::AllocateModifier, Allocator)
- NODE(OmpAllocateClause::AllocateModifier, ComplexModifier)
- NODE(OmpAllocateClause::AllocateModifier, Align)
+ NODE(OmpAllocateClause, Modifier)
+ NODE(parser, OmpAlignModifier)
+ NODE(parser, OmpAllocatorComplexModifier)
+ NODE(parser, OmpAllocatorSimpleModifier)
NODE(parser, OmpScheduleClause)
NODE(OmpScheduleClause, Modifier)
NODE_ENUM(OmpScheduleClause, Kind)
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 8d7119a..e9a02a8 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -3457,6 +3457,30 @@ inline namespace modifier {
// ENUM_CLASS(Value, Keyword1, Keyword2);
// };
+// Ref: [5.1:184-185], [5.2:178-179]
+//
+// align-modifier ->
+// ALIGN(alignment) // since 5.1
+struct OmpAlignModifier {
+ WRAPPER_CLASS_BOILERPLATE(OmpAlignModifier, ScalarIntExpr);
+};
+
+// Ref: [5.0:158-159], [5.1:184-185], [5.2:178-179]
+//
+// allocator-simple-modifier ->
+// allocator // since 5.0
+struct OmpAllocatorSimpleModifier {
+ WRAPPER_CLASS_BOILERPLATE(OmpAllocatorSimpleModifier, ScalarIntExpr);
+};
+
+// Ref: [5.1:184-185], [5.2:178-179]
+//
+// allocator-complex-modifier ->
+// ALLOCATOR(allocator) // since 5.1
+struct OmpAllocatorComplexModifier {
+ WRAPPER_CLASS_BOILERPLATE(OmpAllocatorComplexModifier, ScalarIntExpr);
+};
+
// Ref: [5.2:252-254]
//
// chunk-modifier ->
@@ -3646,24 +3670,20 @@ struct OmpAlignedClause {
std::tuple<OmpObjectList, std::optional<ScalarIntConstantExpr>> t;
};
-// OMP 5.0 2.11.4 allocate-clause -> ALLOCATE ([allocator:] variable-name-list)
-// OMP 5.2 2.13.4 allocate-clause -> ALLOCATE ([allocate-modifier [,
-// allocate-modifier] :]
-// variable-name-list)
-// allocate-modifier -> allocator | align
+// Ref: [5.0:158-159], [5.1:184-185], [5.2:178-179]
+//
+// allocate-clause ->
+// ALLOCATE(
+// [allocator-simple-modifier:] list) | // since 5.0
+// ALLOCATE([modifier...:] list) // since 5.1
+// modifier ->
+// allocator-simple-modifier |
+// allocator-complex-modifier | align-modifier // since 5.1
struct OmpAllocateClause {
- struct AllocateModifier {
- WRAPPER_CLASS(Allocator, ScalarIntExpr);
- WRAPPER_CLASS(Align, ScalarIntExpr);
- struct ComplexModifier {
- TUPLE_CLASS_BOILERPLATE(ComplexModifier);
- std::tuple<Allocator, Align> t;
- };
- UNION_CLASS_BOILERPLATE(AllocateModifier);
- std::variant<Allocator, ComplexModifier, Align> u;
- };
+ MODIFIER_BOILERPLATE(OmpAlignModifier, OmpAllocatorSimpleModifier,
+ OmpAllocatorComplexModifier);
TUPLE_CLASS_BOILERPLATE(OmpAllocateClause);
- std::tuple<std::optional<AllocateModifier>, OmpObjectList> t;
+ std::tuple<MODIFIERS(), OmpObjectList> t;
};
// OMP 5.0 2.4 atomic-default-mem-order-clause ->
diff --git a/flang/include/flang/Semantics/openmp-modifiers.h b/flang/include/flang/Semantics/openmp-modifiers.h
index 60f116e..a6316cf 100644
--- a/flang/include/flang/Semantics/openmp-modifiers.h
+++ b/flang/include/flang/Semantics/openmp-modifiers.h
@@ -67,6 +67,9 @@ template <typename SpecificTy> const OmpModifierDescriptor &OmpGetDescriptor();
#define DECLARE_DESCRIPTOR(name) \
template <> const OmpModifierDescriptor &OmpGetDescriptor<name>()
+DECLARE_DESCRIPTOR(parser::OmpAlignModifier);
+DECLARE_DESCRIPTOR(parser::OmpAllocatorComplexModifier);
+DECLARE_DESCRIPTOR(parser::OmpAllocatorSimpleModifier);
DECLARE_DESCRIPTOR(parser::OmpChunkModifier);
DECLARE_DESCRIPTOR(parser::OmpDependenceType);
DECLARE_DESCRIPTOR(parser::OmpExpectation);
@@ -216,10 +219,26 @@ OmpGetRepeatableModifier(const std::optional<std::list<UnionTy>> &modifiers) {
OmpSpecificModifierIterator(items, items->end()));
}
+// Attempt to prevent creating a range based on an expiring modifier list.
template <typename SpecificTy, typename UnionTy>
llvm::iterator_range<OmpSpecificModifierIterator<SpecificTy>>
OmpGetRepeatableModifier(std::optional<std::list<UnionTy>> &&) = delete;
+template <typename SpecificTy, typename UnionTy>
+Fortran::parser::CharBlock OmpGetModifierSource(
+ const std::optional<std::list<UnionTy>> &modifiers,
+ const SpecificTy *specific) {
+ if (!modifiers || !specific) {
+ return Fortran::parser::CharBlock{};
+ }
+ for (auto &m : *modifiers) {
+ if (std::get_if<SpecificTy>(&m.u) == specific) {
+ return m.source;
+ }
+ }
+ llvm_unreachable("`specific` must be a member of `modifiers`");
+}
+
namespace detail {
template <typename T> constexpr const T *make_nullptr() {
return static_cast<const T *>(nullptr);
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index ace21c1..c251d8b 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -81,12 +81,8 @@ genAllocateClause(lower::AbstractConverter &converter,
// Check if allocate clause has allocator specified. If so, add it
// to list of allocators, otherwise, add default allocator to
// list of allocators.
- using SimpleModifier = Allocate::AllocatorSimpleModifier;
using ComplexModifier = Allocate::AllocatorComplexModifier;
- if (auto &mod = std::get<std::optional<SimpleModifier>>(clause.t)) {
- mlir::Value operand = fir::getBase(converter.genExprValue(*mod, stmtCtx));
- allocatorOperands.append(objects.size(), operand);
- } else if (auto &mod = std::get<std::optional<ComplexModifier>>(clause.t)) {
+ if (auto &mod = std::get<std::optional<ComplexModifier>>(clause.t)) {
mlir::Value operand = fir::getBase(converter.genExprValue(mod->v, stmtCtx));
allocatorOperands.append(objects.size(), operand);
} else {
diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp
index bf20f42..ddc91ef 100644
--- a/flang/lib/Lower/OpenMP/Clauses.cpp
+++ b/flang/lib/Lower/OpenMP/Clauses.cpp
@@ -415,47 +415,29 @@ Aligned make(const parser::OmpClause::Aligned &inp,
Allocate make(const parser::OmpClause::Allocate &inp,
semantics::SemanticsContext &semaCtx) {
// inp.v -> parser::OmpAllocateClause
- using wrapped = parser::OmpAllocateClause;
- auto &t0 = std::get<std::optional<wrapped::AllocateModifier>>(inp.v.t);
+ auto &mods = semantics::OmpGetModifiers(inp.v);
+ auto *m0 = semantics::OmpGetUniqueModifier<parser::OmpAlignModifier>(mods);
+ auto *m1 =
+ semantics::OmpGetUniqueModifier<parser::OmpAllocatorComplexModifier>(
+ mods);
+ auto *m2 =
+ semantics::OmpGetUniqueModifier<parser::OmpAllocatorSimpleModifier>(mods);
auto &t1 = std::get<parser::OmpObjectList>(inp.v.t);
- if (!t0) {
- return Allocate{{/*AllocatorSimpleModifier=*/std::nullopt,
- /*AllocatorComplexModifier=*/std::nullopt,
- /*AlignModifier=*/std::nullopt,
- /*List=*/makeObjects(t1, semaCtx)}};
- }
+ auto makeAllocator = [&](auto *mod) -> std::optional<Allocator> {
+ if (mod)
+ return Allocator{makeExpr(mod->v, semaCtx)};
+ return std::nullopt;
+ };
- using Tuple = decltype(Allocate::t);
+ auto makeAlign = [&](const parser::ScalarIntExpr &expr) {
+ return Align{makeExpr(expr, semaCtx)};
+ };
- return Allocate{Fortran::common::visit(
- common::visitors{
- // simple-modifier
- [&](const wrapped::AllocateModifier::Allocator &v) -> Tuple {
- return {/*AllocatorSimpleModifier=*/makeExpr(v.v, semaCtx),
- /*AllocatorComplexModifier=*/std::nullopt,
- /*AlignModifier=*/std::nullopt,
- /*List=*/makeObjects(t1, semaCtx)};
- },
- // complex-modifier + align-modifier
- [&](const wrapped::AllocateModifier::ComplexModifier &v) -> Tuple {
- auto &s0 = std::get<wrapped::AllocateModifier::Allocator>(v.t);
- auto &s1 = std::get<wrapped::AllocateModifier::Align>(v.t);
- return {
- /*AllocatorSimpleModifier=*/std::nullopt,
- /*AllocatorComplexModifier=*/Allocator{makeExpr(s0.v, semaCtx)},
- /*AlignModifier=*/Align{makeExpr(s1.v, semaCtx)},
- /*List=*/makeObjects(t1, semaCtx)};
- },
- // align-modifier
- [&](const wrapped::AllocateModifier::Align &v) -> Tuple {
- return {/*AllocatorSimpleModifier=*/std::nullopt,
- /*AllocatorComplexModifier=*/std::nullopt,
- /*AlignModifier=*/Align{makeExpr(v.v, semaCtx)},
- /*List=*/makeObjects(t1, semaCtx)};
- },
- },
- t0->u)};
+ auto maybeAllocator = m1 ? makeAllocator(m1) : makeAllocator(m2);
+ return Allocate{{/*AllocatorComplexModifier=*/std::move(maybeAllocator),
+ /*AlignModifier=*/maybeApplyToV(makeAlign, m0),
+ /*List=*/makeObjects(t1, semaCtx)}};
}
Allocator make(const parser::OmpClause::Allocator &inp,
diff --git a/flang/lib/Lower/OpenMP/Clauses.h b/flang/lib/Lower/OpenMP/Clauses.h
index 5fac5c2..562685e 100644
--- a/flang/lib/Lower/OpenMP/Clauses.h
+++ b/flang/lib/Lower/OpenMP/Clauses.h
@@ -153,10 +153,11 @@ std::optional<ResultTy> maybeApply(FuncTy &&func,
return func(*arg);
}
-template <
+template < //
typename FuncTy, //
typename ArgTy, //
- typename ResultTy = std::invoke_result_t<FuncTy, typename ArgTy::Value>>
+ typename ResultTy =
+ std::invoke_result_t<FuncTy, decltype(std::declval<ArgTy>().v)>>
std::optional<ResultTy> maybeApplyToV(FuncTy &&func, const ArgTy *arg) {
if (!arg)
return std::nullopt;
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 2040a3e..f231290 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -91,6 +91,14 @@ static TypeDeclarationStmt makeIterSpecDecl(std::list<ObjectName> &&names) {
// --- Parsers for clause modifiers -----------------------------------
+TYPE_PARSER(construct<OmpAlignModifier>( //
+ "ALIGN" >> parenthesized(scalarIntExpr)))
+
+TYPE_PARSER(construct<OmpAllocatorComplexModifier>(
+ "ALLOCATOR" >> parenthesized(scalarIntExpr)))
+
+TYPE_PARSER(construct<OmpAllocatorSimpleModifier>(scalarIntExpr))
+
TYPE_PARSER(construct<OmpChunkModifier>( //
"SIMD" >> pure(OmpChunkModifier::Value::Simd)))
@@ -183,6 +191,16 @@ TYPE_PARSER(construct<OmpVariableCategory>(
"SCALAR" >> pure(OmpVariableCategory::Value::Scalar)))
// This could be auto-generated.
+TYPE_PARSER(sourced(construct<OmpAllocateClause::Modifier>(sourced(
+ construct<OmpAllocateClause::Modifier>(Parser<OmpAlignModifier>{}) ||
+ construct<OmpAllocateClause::Modifier>(
+ Parser<OmpAllocatorComplexModifier>{}) ||
+ construct<OmpAllocateClause::Modifier>(
+ Parser<OmpAllocatorSimpleModifier>{})))))
+
+TYPE_PARSER(sourced(
+ construct<OmpDefaultmapClause::Modifier>(Parser<OmpVariableCategory>{})))
+
TYPE_PARSER(sourced(construct<OmpFromClause::Modifier>(
sourced(construct<OmpFromClause::Modifier>(Parser<OmpExpectation>{}) ||
construct<OmpFromClause::Modifier>(Parser<OmpMapper>{}) ||
@@ -211,9 +229,6 @@ TYPE_PARSER(sourced(construct<OmpToClause::Modifier>(
construct<OmpToClause::Modifier>(Parser<OmpMapper>{}) ||
construct<OmpToClause::Modifier>(Parser<OmpIterator>{})))))
-TYPE_PARSER(sourced(
- construct<OmpDefaultmapClause::Modifier>(Parser<OmpVariableCategory>{})))
-
// --- Parsers for clauses --------------------------------------------
/// `MOBClause` is a clause that has a
@@ -334,29 +349,7 @@ TYPE_PARSER(construct<OmpInReductionClause>(
// variable-name-list)
// allocate-modifier -> allocator | align
TYPE_PARSER(construct<OmpAllocateClause>(
- maybe(
- first(
- construct<OmpAllocateClause::AllocateModifier>("ALLOCATOR" >>
- construct<OmpAllocateClause::AllocateModifier::ComplexModifier>(
- parenthesized(construct<
- OmpAllocateClause::AllocateModifier::Allocator>(
- scalarIntExpr)) /
- ",",
- "ALIGN" >> parenthesized(construct<
- OmpAllocateClause::AllocateModifier::Align>(
- scalarIntExpr)))),
- construct<OmpAllocateClause::AllocateModifier>("ALLOCATOR" >>
- parenthesized(
- construct<OmpAllocateClause::AllocateModifier::Allocator>(
- scalarIntExpr))),
- construct<OmpAllocateClause::AllocateModifier>("ALIGN" >>
- parenthesized(
- construct<OmpAllocateClause::AllocateModifier::Align>(
- scalarIntExpr))),
- construct<OmpAllocateClause::AllocateModifier>(
- construct<OmpAllocateClause::AllocateModifier::Allocator>(
- scalarIntExpr))) /
- ":"),
+ maybe(nonemptyList(Parser<OmpAllocateClause::Modifier>{}) / ":"),
Parser<OmpObjectList>{}))
// iteration-offset -> +/- non-negative-constant-expr
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index e170815..49e5d91 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2148,35 +2148,21 @@ public:
Walk(std::get<OmpObjectList>(x.t));
}
void Unparse(const OmpAllocateClause &x) {
- Walk(
- std::get<std::optional<OmpAllocateClause::AllocateModifier>>(x.t), ":");
+ using Modifier = OmpAllocateClause::Modifier;
+ Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
Walk(std::get<OmpObjectList>(x.t));
}
- void Unparse(const OmpAllocateClause::AllocateModifier &x) {
- common::visit(
- common::visitors{
- [&](const OmpAllocateClause::AllocateModifier::Allocator &y) {
- Walk(y);
- },
- [&](const OmpAllocateClause::AllocateModifier::ComplexModifier &y) {
- Word("ALLOCATOR(");
- Walk(std::get<OmpAllocateClause::AllocateModifier::Allocator>(
- y.t));
- Put(")");
- Put(",");
- Walk(std::get<OmpAllocateClause::AllocateModifier::Align>(y.t));
- },
- [&](const OmpAllocateClause::AllocateModifier::Align &y) {
- Walk(y);
- },
- },
- x.u);
- }
- void Unparse(const OmpAllocateClause::AllocateModifier::Align &x) {
+ void Unparse(const OmpAlignModifier &x) {
Word("ALIGN(");
Walk(x.v);
Put(")");
}
+ void Unparse(const OmpAllocatorSimpleModifier &x) { Walk(x.v); }
+ void Unparse(const OmpAllocatorComplexModifier &x) {
+ Word("ALLOCATOR(");
+ Walk(x.v);
+ Put(")");
+ }
void Unparse(const OmpOrderClause &x) {
using Modifier = OmpOrderClause::Modifier;
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ":");
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index 3733ebf..b49258d 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -1481,34 +1481,26 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Allocator &x) {
void OmpStructureChecker::Enter(const parser::OmpClause::Allocate &x) {
CheckAllowedClause(llvm::omp::Clause::OMPC_allocate);
- if (const auto &modifier{
- std::get<std::optional<parser::OmpAllocateClause::AllocateModifier>>(
- x.v.t)}) {
- common::visit(
- common::visitors{
- [&](const parser::OmpAllocateClause::AllocateModifier::Allocator
- &y) {
- RequiresPositiveParameter(llvm::omp::Clause::OMPC_allocate, y.v);
- isPredefinedAllocator = GetIntValue(y.v).has_value();
- },
- [&](const parser::OmpAllocateClause::AllocateModifier::
- ComplexModifier &y) {
- const auto &alloc = std::get<
- parser::OmpAllocateClause::AllocateModifier::Allocator>(y.t);
- const auto &align =
- std::get<parser::OmpAllocateClause::AllocateModifier::Align>(
- y.t);
- RequiresPositiveParameter(
- llvm::omp::Clause::OMPC_allocate, alloc.v);
- RequiresPositiveParameter(
- llvm::omp::Clause::OMPC_allocate, align.v);
- isPredefinedAllocator = GetIntValue(alloc.v).has_value();
- },
- [&](const parser::OmpAllocateClause::AllocateModifier::Align &y) {
- RequiresPositiveParameter(llvm::omp::Clause::OMPC_allocate, y.v);
- },
- },
- modifier->u);
+ if (OmpVerifyModifiers(
+ x.v, llvm::omp::OMPC_allocate, GetContext().clauseSource, context_)) {
+ auto &modifiers{OmpGetModifiers(x.v)};
+ if (auto *align{
+ OmpGetUniqueModifier<parser::OmpAlignModifier>(modifiers)}) {
+ if (const auto &v{GetIntValue(align->v)}; !v || *v <= 0) {
+ context_.Say(OmpGetModifierSource(modifiers, align),
+ "The alignment value should be a constant positive integer"_err_en_US);
+ }
+ }
+ // The simple and complex modifiers have the same structure. They only
+ // differ in their syntax.
+ if (auto *alloc{OmpGetUniqueModifier<parser::OmpAllocatorComplexModifier>(
+ modifiers)}) {
+ isPredefinedAllocator = GetIntValue(alloc->v).has_value();
+ }
+ if (auto *alloc{OmpGetUniqueModifier<parser::OmpAllocatorSimpleModifier>(
+ modifiers)}) {
+ isPredefinedAllocator = GetIntValue(alloc->v).has_value();
+ }
}
}
diff --git a/flang/lib/Semantics/openmp-modifiers.cpp b/flang/lib/Semantics/openmp-modifiers.cpp
index 1fd2358..18863b7 100644
--- a/flang/lib/Semantics/openmp-modifiers.cpp
+++ b/flang/lib/Semantics/openmp-modifiers.cpp
@@ -75,6 +75,56 @@ unsigned OmpModifierDescriptor::since(llvm::omp::Clause id) const {
// generated in the future.
template <>
+const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpAlignModifier>() {
+ static const OmpModifierDescriptor desc{
+ /*name=*/"align-modifier",
+ /*props=*/
+ {
+ {51, {OmpProperty::Unique}},
+ },
+ /*clauses=*/
+ {
+ {51, {Clause::OMPC_allocate}},
+ },
+ };
+ return desc;
+}
+
+template <>
+const OmpModifierDescriptor &
+OmpGetDescriptor<parser::OmpAllocatorComplexModifier>() {
+ static const OmpModifierDescriptor desc{
+ /*name=*/"allocator-complex-modifier",
+ /*props=*/
+ {
+ {51, {OmpProperty::Unique}},
+ },
+ /*clauses=*/
+ {
+ {51, {Clause::OMPC_allocate}},
+ },
+ };
+ return desc;
+}
+
+template <>
+const OmpModifierDescriptor &
+OmpGetDescriptor<parser::OmpAllocatorSimpleModifier>() {
+ static const OmpModifierDescriptor desc{
+ /*name=*/"allocator-simple-modifier",
+ /*props=*/
+ {
+ {50, {OmpProperty::Exclusive, OmpProperty::Unique}},
+ },
+ /*clauses=*/
+ {
+ {50, {Clause::OMPC_allocate}},
+ },
+ };
+ return desc;
+}
+
+template <>
const OmpModifierDescriptor &OmpGetDescriptor<parser::OmpChunkModifier>() {
static const OmpModifierDescriptor desc{
/*name=*/"chunk-modifier",
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 55dd94c..7bee8ad 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -2097,17 +2097,16 @@ void OmpAttributeVisitor::Post(const parser::OpenMPAllocatorsConstruct &x) {
std::get<parser::OmpObjectList>(alloc->v.t),
std::get<parser::Statement<parser::AllocateStmt>>(x.t).statement);
- const auto &allocMod{
- std::get<std::optional<parser::OmpAllocateClause::AllocateModifier>>(
- alloc->v.t)};
+ auto &modifiers{OmpGetModifiers(alloc->v)};
+ bool hasAllocator{
+ OmpGetUniqueModifier<parser::OmpAllocatorSimpleModifier>(modifiers) ||
+ OmpGetUniqueModifier<parser::OmpAllocatorComplexModifier>(modifiers)};
+
// TODO: As with allocate directive, exclude the case when a requires
// directive with the dynamic_allocators clause is present in
// the same compilation unit (OMP5.0 2.11.3).
if (IsNestedInDirective(llvm::omp::Directive::OMPD_target) &&
- (!allocMod.has_value() ||
- std::holds_alternative<
- parser::OmpAllocateClause::AllocateModifier::Align>(
- allocMod->u))) {
+ !hasAllocator) {
context_.Say(x.source,
"ALLOCATORS directives that appear in a TARGET region "
"must specify an allocator"_err_en_US);
diff --git a/flang/test/Parser/OpenMP/allocators-unparse.f90 b/flang/test/Parser/OpenMP/allocators-unparse.f90
index 062a48b..5cd0230 100644
--- a/flang/test/Parser/OpenMP/allocators-unparse.f90
+++ b/flang/test/Parser/OpenMP/allocators-unparse.f90
@@ -18,18 +18,18 @@ subroutine allocate()
end subroutine allocate
!CHECK: INTEGER, ALLOCATABLE :: arr1(:), arr2(:,:)
-!CHECK-NEXT:!$OMP ALLOCATE ALLOCATE(omp_default_mem_alloc:arr1)
+!CHECK-NEXT:!$OMP ALLOCATE ALLOCATE(omp_default_mem_alloc: arr1)
!CHECK-NEXT: ALLOCATE(arr1(5))
-!CHECK-NEXT:!$OMP ALLOCATE ALLOCATE(ALLOCATOR(omp_default_mem_alloc),ALIGN(32):arr1) ALLOC&
-!CHECK-NEXT:!$OMP&ATE(omp_default_mem_alloc:arr2)
+!CHECK-NEXT:!$OMP ALLOCATE ALLOCATE(ALLOCATOR(omp_default_mem_alloc), ALIGN(32): arr1) ALL&
+!CHECK-NEXT:!$OMP&OCATE(omp_default_mem_alloc: arr2)
!CHECK-NEXT: ALLOCATE(arr1(10), arr2(3,2))
-!CHECK-NEXT:!$OMP ALLOCATE ALLOCATE(ALIGN(32):arr2)
+!CHECK-NEXT:!$OMP ALLOCATE ALLOCATE(ALIGN(32): arr2)
!CHECK-NEXT: ALLOCATE(arr2(5,3))
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAllocatorsConstruct
!PARSE-TREE-NEXT: Verbatim
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Allocate -> OmpAllocateClause
-!PARSE-TREE-NEXT: AllocateModifier -> Allocator -> Scalar -> Integer -> Expr -> Designator -> DataRef -> Name =
+!PARSE-TREE-NEXT: Modifier -> OmpAllocatorSimpleModifier -> Scalar -> Integer -> Expr -> Designator -> DataRef -> Name = 'omp_default_mem_alloc'
!PARSE-TREE-NEXT: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'arr1'
!PARSE-TREE-NEXT: AllocateStmt
!PARSE-TREE-NEXT: Allocation
@@ -38,12 +38,11 @@ end subroutine allocate
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAllocatorsConstruct
!PARSE-TREE-NEXT: Verbatim
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Allocate -> OmpAllocateClause
-!PARSE-TREE-NEXT: AllocateModifier -> ComplexModifier
-!PARSE-TREE-NEXT: Allocator -> Scalar -> Integer -> Expr -> Designator -> DataRef -> Name =
-!PARSE-TREE-NEXT: Align -> Scalar -> Integer -> Expr -> LiteralConstant -> IntLiteralConstant = '32'
+!PARSE-TREE-NEXT: Modifier -> OmpAllocatorComplexModifier -> Scalar -> Integer -> Expr -> Designator -> DataRef -> Name = 'omp_default_mem_alloc'
+!PARSE-TREE-NEXT: Modifier -> OmpAlignModifier -> Scalar -> Integer -> Expr -> LiteralConstant -> IntLiteralConstant = '32'
!PARSE-TREE-NEXT: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'arr1'
!PARSE-TREE-NEXT: OmpClause -> Allocate -> OmpAllocateClause
-!PARSE-TREE-NEXT: AllocateModifier -> Allocator -> Scalar -> Integer -> Expr -> Designator -> DataRef -> Name =
+!PARSE-TREE-NEXT: Modifier -> OmpAllocatorSimpleModifier -> Scalar -> Integer -> Expr -> Designator -> DataRef -> Name = 'omp_default_mem_alloc'
!PARSE-TREE-NEXT: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'arr2'
!PARSE-TREE-NEXT: AllocateStmt
!PARSE-TREE-NEXT: Allocation
@@ -56,7 +55,7 @@ end subroutine allocate
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAllocatorsConstruct
!PARSE-TREE-NEXT: Verbatim
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Allocate -> OmpAllocateClause
-!PARSE-TREE-NEXT: AllocateModifier -> Align -> Scalar -> Integer -> Expr -> LiteralConstant -> IntLiteralConstant = '32'
+!PARSE-TREE-NEXT: Modifier -> OmpAlignModifier -> Scalar -> Integer -> Expr -> LiteralConstant -> IntLiteralConstant = '32'
!PARSE-TREE-NEXT: OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'arr2'
!PARSE-TREE-NEXT: AllocateStmt
!PARSE-TREE-NEXT: Allocation
diff --git a/flang/test/Semantics/OpenMP/allocate-clause01.f90 b/flang/test/Semantics/OpenMP/allocate-clause01.f90
index 2b9a72e9..a014b54 100644
--- a/flang/test/Semantics/OpenMP/allocate-clause01.f90
+++ b/flang/test/Semantics/OpenMP/allocate-clause01.f90
@@ -1,6 +1,6 @@
! REQUIRES: openmp_runtime
-! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=51
! OpenMP Version 5.2
! The allocate clause's allocator modifier must be of type allocator_handle
! and the align modifier must be constant, positive integer expression
@@ -10,15 +10,11 @@ subroutine allocate()
integer, allocatable :: a, b, c
- !ERROR: The parameter of the ALLOCATE clause must be a positive integer expression
- !$omp allocators allocate(-1: a)
- allocate(a)
-
- !ERROR: The parameter of the ALLOCATE clause must be a positive integer expression
+ !ERROR: The alignment value should be a constant positive integer
!$omp allocators allocate(allocator(-2), align(-3): b)
allocate(b)
- !ERROR: The parameter of the ALLOCATE clause must be a positive integer expression
+ !ERROR: The alignment value should be a constant positive integer
!$omp allocators allocate(align(-4): c)
allocate(c)
end subroutine
diff --git a/flang/test/Semantics/OpenMP/allocators01.f90 b/flang/test/Semantics/OpenMP/allocators01.f90
index c75c522..ff92fa3 100644
--- a/flang/test/Semantics/OpenMP/allocators01.f90
+++ b/flang/test/Semantics/OpenMP/allocators01.f90
@@ -1,6 +1,6 @@
! REQUIRES: openmp_runtime
-! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=50
! OpenMP Version 5.2
! 6.7 allocators construct
! A list item that appears in an allocate clause must appear as
diff --git a/flang/test/Semantics/OpenMP/allocators04.f90 b/flang/test/Semantics/OpenMP/allocators04.f90
index 1d2e964..212e48f 100644
--- a/flang/test/Semantics/OpenMP/allocators04.f90
+++ b/flang/test/Semantics/OpenMP/allocators04.f90
@@ -1,6 +1,6 @@
! REQUIRES: openmp_runtime
-! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=50
! OpenMP Version 5.2
! Inherited from 2.11.3 allocate Directive
! If list items within the ALLOCATE directive have the SAVE attribute, are a common block name, or are declared in the scope of a
diff --git a/flang/test/Semantics/OpenMP/allocators05.f90 b/flang/test/Semantics/OpenMP/allocators05.f90
index d0e11ca..0e8366a 100644
--- a/flang/test/Semantics/OpenMP/allocators05.f90
+++ b/flang/test/Semantics/OpenMP/allocators05.f90
@@ -1,6 +1,6 @@
! REQUIRES: openmp_runtime
-! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=50
! OpenMP Version 5.2
! Inherited from 2.11.3 allocate directive
! allocate directives that appear in a target region must specify an
diff --git a/flang/test/Semantics/OpenMP/allocators06.f90 b/flang/test/Semantics/OpenMP/allocators06.f90
index a975204..8e63512 100644
--- a/flang/test/Semantics/OpenMP/allocators06.f90
+++ b/flang/test/Semantics/OpenMP/allocators06.f90
@@ -1,6 +1,6 @@
! REQUIRES: openmp_runtime
-! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=50
! OpenMP Version 5.2
! Inherited from 2.11.3 allocate directive
! The allocate directive must appear in the same scope as the declarations of
diff --git a/flang/test/Semantics/OpenMP/resolve06.f90 b/flang/test/Semantics/OpenMP/resolve06.f90
index 358b1b1..cf544df 100644
--- a/flang/test/Semantics/OpenMP/resolve06.f90
+++ b/flang/test/Semantics/OpenMP/resolve06.f90
@@ -1,6 +1,6 @@
! REQUIRES: openmp_runtime
-! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags
+! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags -fopenmp-version=50
use omp_lib
!2.11.4 Allocate Clause
!For any list item that is specified in the allocate
diff --git a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
index ce09bb5..07efd6fd 100644
--- a/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
+++ b/llvm/include/llvm/Frontend/OpenMP/ClauseT.h
@@ -384,15 +384,13 @@ struct AllocatorT;
// V5.2: [6.6] `allocate` clause
template <typename T, typename I, typename E> //
struct AllocateT {
- using AllocatorSimpleModifier = E;
+ // AllocatorSimpleModifier is same as AllocatorComplexModifier.
using AllocatorComplexModifier = AllocatorT<T, I, E>;
using AlignModifier = AlignT<T, I, E>;
using List = ObjectListT<I, E>;
using TupleTrait = std::true_type;
- std::tuple<OPT(AllocatorSimpleModifier), OPT(AllocatorComplexModifier),
- OPT(AlignModifier), List>
- t;
+ std::tuple<OPT(AllocatorComplexModifier), OPT(AlignModifier), List> t;
};
// V5.2: [6.4] `allocator` clause
diff --git a/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp b/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp
index f954113..8f195c4 100644
--- a/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp
+++ b/llvm/unittests/Frontend/OpenMPDecompositionTest.cpp
@@ -686,12 +686,12 @@ TEST_F(OpenMPDecompositionTest, Order1) {
std::string Dir3 = stringify(Dec.output[3]);
std::string Dir4 = stringify(Dec.output[4]);
std::string Dir5 = stringify(Dec.output[5]);
- ASSERT_EQ(Dir0, "target"); // (31)
- ASSERT_EQ(Dir1, "teams"); // (31)
+ ASSERT_EQ(Dir0, "target"); // (31)
+ ASSERT_EQ(Dir1, "teams"); // (31)
ASSERT_EQ(Dir2, "distribute order(1, 0)"); // (31)
- ASSERT_EQ(Dir3, "parallel"); // (31)
- ASSERT_EQ(Dir4, "for order(1, 0)"); // (31)
- ASSERT_EQ(Dir5, "simd order(1, 0)"); // (31)
+ ASSERT_EQ(Dir3, "parallel"); // (31)
+ ASSERT_EQ(Dir4, "for order(1, 0)"); // (31)
+ ASSERT_EQ(Dir5, "simd order(1, 0)"); // (31)
}
// ALLOCATE
@@ -708,8 +708,7 @@ TEST_F(OpenMPDecompositionTest, Allocate1) {
// Allocate + firstprivate
omp::List<omp::Clause> Clauses{
- {OMPC_allocate,
- omp::clause::Allocate{{std::nullopt, std::nullopt, std::nullopt, {x}}}},
+ {OMPC_allocate, omp::clause::Allocate{{std::nullopt, std::nullopt, {x}}}},
{OMPC_firstprivate, omp::clause::Firstprivate{{x}}},
};
@@ -719,8 +718,8 @@ TEST_F(OpenMPDecompositionTest, Allocate1) {
std::string Dir0 = stringify(Dec.output[0]);
std::string Dir1 = stringify(Dec.output[1]);
- ASSERT_EQ(Dir0, "parallel shared(x)"); // (33)
- ASSERT_EQ(Dir1, "sections firstprivate(x) allocate(, , , (x))"); // (33)
+ ASSERT_EQ(Dir0, "parallel shared(x)"); // (33)
+ ASSERT_EQ(Dir1, "sections firstprivate(x) allocate(, , (x))"); // (33)
}
TEST_F(OpenMPDecompositionTest, Allocate2) {
@@ -729,8 +728,7 @@ TEST_F(OpenMPDecompositionTest, Allocate2) {
// Allocate + in_reduction
omp::List<omp::Clause> Clauses{
- {OMPC_allocate,
- omp::clause::Allocate{{std::nullopt, std::nullopt, std::nullopt, {x}}}},
+ {OMPC_allocate, omp::clause::Allocate{{std::nullopt, std::nullopt, {x}}}},
{OMPC_in_reduction, omp::clause::InReduction{{{Add}, {x}}}},
};
@@ -740,8 +738,8 @@ TEST_F(OpenMPDecompositionTest, Allocate2) {
std::string Dir0 = stringify(Dec.output[0]);
std::string Dir1 = stringify(Dec.output[1]);
- ASSERT_EQ(Dir0, "target in_reduction((3), (x)) allocate(, , , (x))"); // (33)
- ASSERT_EQ(Dir1, "parallel"); // (33)
+ ASSERT_EQ(Dir0, "target in_reduction((3), (x)) allocate(, , (x))"); // (33)
+ ASSERT_EQ(Dir1, "parallel"); // (33)
}
TEST_F(OpenMPDecompositionTest, Allocate3) {
@@ -749,8 +747,7 @@ TEST_F(OpenMPDecompositionTest, Allocate3) {
// Allocate + linear
omp::List<omp::Clause> Clauses{
- {OMPC_allocate,
- omp::clause::Allocate{{std::nullopt, std::nullopt, std::nullopt, {x}}}},
+ {OMPC_allocate, omp::clause::Allocate{{std::nullopt, std::nullopt, {x}}}},
{OMPC_linear,
omp::clause::Linear{{std::nullopt, std::nullopt, std::nullopt, {x}}}},
};
@@ -765,7 +762,7 @@ TEST_F(OpenMPDecompositionTest, Allocate3) {
// should be fixed eventually.
ASSERT_EQ(Dir0, "parallel shared(x) shared(x)"); // (33)
ASSERT_EQ(Dir1, "for linear(, , , (x)) firstprivate(x) lastprivate(, (x)) "
- "allocate(, , , (x))"); // (33)
+ "allocate(, , (x))"); // (33)
}
TEST_F(OpenMPDecompositionTest, Allocate4) {
@@ -773,8 +770,7 @@ TEST_F(OpenMPDecompositionTest, Allocate4) {
// Allocate + lastprivate
omp::List<omp::Clause> Clauses{
- {OMPC_allocate,
- omp::clause::Allocate{{std::nullopt, std::nullopt, std::nullopt, {x}}}},
+ {OMPC_allocate, omp::clause::Allocate{{std::nullopt, std::nullopt, {x}}}},
{OMPC_lastprivate, omp::clause::Lastprivate{{std::nullopt, {x}}}},
};
@@ -784,8 +780,8 @@ TEST_F(OpenMPDecompositionTest, Allocate4) {
std::string Dir0 = stringify(Dec.output[0]);
std::string Dir1 = stringify(Dec.output[1]);
- ASSERT_EQ(Dir0, "parallel shared(x)"); // (33)
- ASSERT_EQ(Dir1, "sections lastprivate(, (x)) allocate(, , , (x))"); // (33)
+ ASSERT_EQ(Dir0, "parallel shared(x)"); // (33)
+ ASSERT_EQ(Dir1, "sections lastprivate(, (x)) allocate(, , (x))"); // (33)
}
TEST_F(OpenMPDecompositionTest, Allocate5) {
@@ -793,8 +789,7 @@ TEST_F(OpenMPDecompositionTest, Allocate5) {
// Allocate + private
omp::List<omp::Clause> Clauses{
- {OMPC_allocate,
- omp::clause::Allocate{{std::nullopt, std::nullopt, std::nullopt, {x}}}},
+ {OMPC_allocate, omp::clause::Allocate{{std::nullopt, std::nullopt, {x}}}},
{OMPC_private, omp::clause::Private{{x}}},
};
@@ -804,8 +799,8 @@ TEST_F(OpenMPDecompositionTest, Allocate5) {
std::string Dir0 = stringify(Dec.output[0]);
std::string Dir1 = stringify(Dec.output[1]);
- ASSERT_EQ(Dir0, "parallel"); // (33)
- ASSERT_EQ(Dir1, "sections private(x) allocate(, , , (x))"); // (33)
+ ASSERT_EQ(Dir0, "parallel"); // (33)
+ ASSERT_EQ(Dir1, "sections private(x) allocate(, , (x))"); // (33)
}
TEST_F(OpenMPDecompositionTest, Allocate6) {
@@ -814,8 +809,7 @@ TEST_F(OpenMPDecompositionTest, Allocate6) {
// Allocate + reduction
omp::List<omp::Clause> Clauses{
- {OMPC_allocate,
- omp::clause::Allocate{{std::nullopt, std::nullopt, std::nullopt, {x}}}},
+ {OMPC_allocate, omp::clause::Allocate{{std::nullopt, std::nullopt, {x}}}},
{OMPC_reduction, omp::clause::Reduction{{std::nullopt, {Add}, {x}}}},
};
@@ -825,8 +819,8 @@ TEST_F(OpenMPDecompositionTest, Allocate6) {
std::string Dir0 = stringify(Dec.output[0]);
std::string Dir1 = stringify(Dec.output[1]);
- ASSERT_EQ(Dir0, "parallel shared(x)"); // (33)
- ASSERT_EQ(Dir1, "sections reduction(, (3), (x)) allocate(, , , (x))"); // (33)
+ ASSERT_EQ(Dir0, "parallel shared(x)"); // (33)
+ ASSERT_EQ(Dir1, "sections reduction(, (3), (x)) allocate(, , (x))"); // (33)
}
// REDUCTION