Skip to content

Commit aa17e9d

Browse files
committed
[flang][OpenMP] Use new modifiers in ALLOCATE clause
Again, this simplifies the semantic checks and lowering quite a bit. Update the check for positive alignment to use a more informative message, and to highlight the modifier itsef, not the whole clause. Remove the checks for the allocator expression itself being positive: there is nothing in the spec that says that it should be positive. Remove the "simple" modifier from the AllocateT template, since both simple and complex modifiers are the same thing, only differing in syntax.
1 parent 3699931 commit aa17e9d

File tree

19 files changed

+205
-174
lines changed

19 files changed

+205
-174
lines changed

flang/include/flang/Parser/dump-parse-tree.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -586,10 +586,10 @@ class ParseTreeDumper {
586586
NODE(parser, OmpReductionInitializerClause)
587587
NODE(parser, OmpReductionIdentifier)
588588
NODE(parser, OmpAllocateClause)
589-
NODE(OmpAllocateClause, AllocateModifier)
590-
NODE(OmpAllocateClause::AllocateModifier, Allocator)
591-
NODE(OmpAllocateClause::AllocateModifier, ComplexModifier)
592-
NODE(OmpAllocateClause::AllocateModifier, Align)
589+
NODE(OmpAllocateClause, Modifier)
590+
NODE(parser, OmpAlignModifier)
591+
NODE(parser, OmpAllocatorComplexModifier)
592+
NODE(parser, OmpAllocatorSimpleModifier)
593593
NODE(parser, OmpScheduleClause)
594594
NODE(OmpScheduleClause, Modifier)
595595
NODE_ENUM(OmpScheduleClause, Kind)

flang/include/flang/Parser/parse-tree.h

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3457,6 +3457,30 @@ inline namespace modifier {
34573457
// ENUM_CLASS(Value, Keyword1, Keyword2);
34583458
// };
34593459

3460+
// Ref: [5.1:184-185], [5.2:178-179]
3461+
//
3462+
// align-modifier ->
3463+
// ALIGN(alignment) // since 5.1
3464+
struct OmpAlignModifier {
3465+
WRAPPER_CLASS_BOILERPLATE(OmpAlignModifier, ScalarIntExpr);
3466+
};
3467+
3468+
// Ref: [5.0:158-159], [5.1:184-185], [5.2:178-179]
3469+
//
3470+
// allocator-simple-modifier ->
3471+
// allocator // since 5.0
3472+
struct OmpAllocatorSimpleModifier {
3473+
WRAPPER_CLASS_BOILERPLATE(OmpAllocatorSimpleModifier, ScalarIntExpr);
3474+
};
3475+
3476+
// Ref: [5.1:184-185], [5.2:178-179]
3477+
//
3478+
// allocator-complex-modifier ->
3479+
// ALLOCATOR(allocator) // since 5.1
3480+
struct OmpAllocatorComplexModifier {
3481+
WRAPPER_CLASS_BOILERPLATE(OmpAllocatorComplexModifier, ScalarIntExpr);
3482+
};
3483+
34603484
// Ref: [5.2:252-254]
34613485
//
34623486
// chunk-modifier ->
@@ -3646,24 +3670,20 @@ struct OmpAlignedClause {
36463670
std::tuple<OmpObjectList, std::optional<ScalarIntConstantExpr>> t;
36473671
};
36483672

3649-
// OMP 5.0 2.11.4 allocate-clause -> ALLOCATE ([allocator:] variable-name-list)
3650-
// OMP 5.2 2.13.4 allocate-clause -> ALLOCATE ([allocate-modifier [,
3651-
// allocate-modifier] :]
3652-
// variable-name-list)
3653-
// allocate-modifier -> allocator | align
3673+
// Ref: [5.0:158-159], [5.1:184-185], [5.2:178-179]
3674+
//
3675+
// allocate-clause ->
3676+
// ALLOCATE(
3677+
// [allocator-simple-modifier:] list) | // since 5.0
3678+
// ALLOCATE([modifier...:] list) // since 5.1
3679+
// modifier ->
3680+
// allocator-simple-modifier |
3681+
// allocator-complex-modifier | align-modifier // since 5.1
36543682
struct OmpAllocateClause {
3655-
struct AllocateModifier {
3656-
WRAPPER_CLASS(Allocator, ScalarIntExpr);
3657-
WRAPPER_CLASS(Align, ScalarIntExpr);
3658-
struct ComplexModifier {
3659-
TUPLE_CLASS_BOILERPLATE(ComplexModifier);
3660-
std::tuple<Allocator, Align> t;
3661-
};
3662-
UNION_CLASS_BOILERPLATE(AllocateModifier);
3663-
std::variant<Allocator, ComplexModifier, Align> u;
3664-
};
3683+
MODIFIER_BOILERPLATE(OmpAlignModifier, OmpAllocatorSimpleModifier,
3684+
OmpAllocatorComplexModifier);
36653685
TUPLE_CLASS_BOILERPLATE(OmpAllocateClause);
3666-
std::tuple<std::optional<AllocateModifier>, OmpObjectList> t;
3686+
std::tuple<MODIFIERS(), OmpObjectList> t;
36673687
};
36683688

36693689
// OMP 5.0 2.4 atomic-default-mem-order-clause ->

flang/include/flang/Semantics/openmp-modifiers.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ template <typename SpecificTy> const OmpModifierDescriptor &OmpGetDescriptor();
6767
#define DECLARE_DESCRIPTOR(name) \
6868
template <> const OmpModifierDescriptor &OmpGetDescriptor<name>()
6969

70+
DECLARE_DESCRIPTOR(parser::OmpAlignModifier);
71+
DECLARE_DESCRIPTOR(parser::OmpAllocatorComplexModifier);
72+
DECLARE_DESCRIPTOR(parser::OmpAllocatorSimpleModifier);
7073
DECLARE_DESCRIPTOR(parser::OmpChunkModifier);
7174
DECLARE_DESCRIPTOR(parser::OmpDependenceType);
7275
DECLARE_DESCRIPTOR(parser::OmpExpectation);
@@ -216,10 +219,26 @@ OmpGetRepeatableModifier(const std::optional<std::list<UnionTy>> &modifiers) {
216219
OmpSpecificModifierIterator(items, items->end()));
217220
}
218221

222+
// Attempt to prevent creating a range based on an expiring modifier list.
219223
template <typename SpecificTy, typename UnionTy>
220224
llvm::iterator_range<OmpSpecificModifierIterator<SpecificTy>>
221225
OmpGetRepeatableModifier(std::optional<std::list<UnionTy>> &&) = delete;
222226

227+
template <typename SpecificTy, typename UnionTy>
228+
Fortran::parser::CharBlock OmpGetModifierSource(
229+
const std::optional<std::list<UnionTy>> &modifiers,
230+
const SpecificTy *specific) {
231+
if (!modifiers || !specific) {
232+
return Fortran::parser::CharBlock{};
233+
}
234+
for (auto &m : *modifiers) {
235+
if (std::get_if<SpecificTy>(&m.u) == specific) {
236+
return m.source;
237+
}
238+
}
239+
llvm_unreachable("`specific` must be a member of `modifiers`");
240+
}
241+
223242
namespace detail {
224243
template <typename T> constexpr const T *make_nullptr() {
225244
return static_cast<const T *>(nullptr);

flang/lib/Lower/OpenMP/ClauseProcessor.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,8 @@ genAllocateClause(lower::AbstractConverter &converter,
8181
// Check if allocate clause has allocator specified. If so, add it
8282
// to list of allocators, otherwise, add default allocator to
8383
// list of allocators.
84-
using SimpleModifier = Allocate::AllocatorSimpleModifier;
8584
using ComplexModifier = Allocate::AllocatorComplexModifier;
86-
if (auto &mod = std::get<std::optional<SimpleModifier>>(clause.t)) {
87-
mlir::Value operand = fir::getBase(converter.genExprValue(*mod, stmtCtx));
88-
allocatorOperands.append(objects.size(), operand);
89-
} else if (auto &mod = std::get<std::optional<ComplexModifier>>(clause.t)) {
85+
if (auto &mod = std::get<std::optional<ComplexModifier>>(clause.t)) {
9086
mlir::Value operand = fir::getBase(converter.genExprValue(mod->v, stmtCtx));
9187
allocatorOperands.append(objects.size(), operand);
9288
} else {

flang/lib/Lower/OpenMP/Clauses.cpp

Lines changed: 19 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -415,47 +415,29 @@ Aligned make(const parser::OmpClause::Aligned &inp,
415415
Allocate make(const parser::OmpClause::Allocate &inp,
416416
semantics::SemanticsContext &semaCtx) {
417417
// inp.v -> parser::OmpAllocateClause
418-
using wrapped = parser::OmpAllocateClause;
419-
auto &t0 = std::get<std::optional<wrapped::AllocateModifier>>(inp.v.t);
418+
auto &mods = semantics::OmpGetModifiers(inp.v);
419+
auto *m0 = semantics::OmpGetUniqueModifier<parser::OmpAlignModifier>(mods);
420+
auto *m1 =
421+
semantics::OmpGetUniqueModifier<parser::OmpAllocatorComplexModifier>(
422+
mods);
423+
auto *m2 =
424+
semantics::OmpGetUniqueModifier<parser::OmpAllocatorSimpleModifier>(mods);
420425
auto &t1 = std::get<parser::OmpObjectList>(inp.v.t);
421426

422-
if (!t0) {
423-
return Allocate{{/*AllocatorSimpleModifier=*/std::nullopt,
424-
/*AllocatorComplexModifier=*/std::nullopt,
425-
/*AlignModifier=*/std::nullopt,
426-
/*List=*/makeObjects(t1, semaCtx)}};
427-
}
427+
auto makeAllocator = [&](auto *mod) -> std::optional<Allocator> {
428+
if (mod)
429+
return Allocator{makeExpr(mod->v, semaCtx)};
430+
return std::nullopt;
431+
};
428432

429-
using Tuple = decltype(Allocate::t);
433+
auto makeAlign = [&](const parser::ScalarIntExpr &expr) {
434+
return Align{makeExpr(expr, semaCtx)};
435+
};
430436

431-
return Allocate{Fortran::common::visit(
432-
common::visitors{
433-
// simple-modifier
434-
[&](const wrapped::AllocateModifier::Allocator &v) -> Tuple {
435-
return {/*AllocatorSimpleModifier=*/makeExpr(v.v, semaCtx),
436-
/*AllocatorComplexModifier=*/std::nullopt,
437-
/*AlignModifier=*/std::nullopt,
438-
/*List=*/makeObjects(t1, semaCtx)};
439-
},
440-
// complex-modifier + align-modifier
441-
[&](const wrapped::AllocateModifier::ComplexModifier &v) -> Tuple {
442-
auto &s0 = std::get<wrapped::AllocateModifier::Allocator>(v.t);
443-
auto &s1 = std::get<wrapped::AllocateModifier::Align>(v.t);
444-
return {
445-
/*AllocatorSimpleModifier=*/std::nullopt,
446-
/*AllocatorComplexModifier=*/Allocator{makeExpr(s0.v, semaCtx)},
447-
/*AlignModifier=*/Align{makeExpr(s1.v, semaCtx)},
448-
/*List=*/makeObjects(t1, semaCtx)};
449-
},
450-
// align-modifier
451-
[&](const wrapped::AllocateModifier::Align &v) -> Tuple {
452-
return {/*AllocatorSimpleModifier=*/std::nullopt,
453-
/*AllocatorComplexModifier=*/std::nullopt,
454-
/*AlignModifier=*/Align{makeExpr(v.v, semaCtx)},
455-
/*List=*/makeObjects(t1, semaCtx)};
456-
},
457-
},
458-
t0->u)};
437+
auto maybeAllocator = m1 ? makeAllocator(m1) : makeAllocator(m2);
438+
return Allocate{{/*AllocatorComplexModifier=*/std::move(maybeAllocator),
439+
/*AlignModifier=*/maybeApplyToV(makeAlign, m0),
440+
/*List=*/makeObjects(t1, semaCtx)}};
459441
}
460442

461443
Allocator make(const parser::OmpClause::Allocator &inp,

flang/lib/Lower/OpenMP/Clauses.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,11 @@ std::optional<ResultTy> maybeApply(FuncTy &&func,
153153
return func(*arg);
154154
}
155155

156-
template <
156+
template < //
157157
typename FuncTy, //
158158
typename ArgTy, //
159-
typename ResultTy = std::invoke_result_t<FuncTy, typename ArgTy::Value>>
159+
typename ResultTy =
160+
std::invoke_result_t<FuncTy, decltype(std::declval<ArgTy>().v)>>
160161
std::optional<ResultTy> maybeApplyToV(FuncTy &&func, const ArgTy *arg) {
161162
if (!arg)
162163
return std::nullopt;

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,14 @@ static TypeDeclarationStmt makeIterSpecDecl(std::list<ObjectName> &&names) {
9191

9292
// --- Parsers for clause modifiers -----------------------------------
9393

94+
TYPE_PARSER(construct<OmpAlignModifier>( //
95+
"ALIGN" >> parenthesized(scalarIntExpr)))
96+
97+
TYPE_PARSER(construct<OmpAllocatorComplexModifier>(
98+
"ALLOCATOR" >> parenthesized(scalarIntExpr)))
99+
100+
TYPE_PARSER(construct<OmpAllocatorSimpleModifier>(scalarIntExpr))
101+
94102
TYPE_PARSER(construct<OmpChunkModifier>( //
95103
"SIMD" >> pure(OmpChunkModifier::Value::Simd)))
96104

@@ -183,6 +191,16 @@ TYPE_PARSER(construct<OmpVariableCategory>(
183191
"SCALAR" >> pure(OmpVariableCategory::Value::Scalar)))
184192

185193
// This could be auto-generated.
194+
TYPE_PARSER(sourced(construct<OmpAllocateClause::Modifier>(sourced(
195+
construct<OmpAllocateClause::Modifier>(Parser<OmpAlignModifier>{}) ||
196+
construct<OmpAllocateClause::Modifier>(
197+
Parser<OmpAllocatorComplexModifier>{}) ||
198+
construct<OmpAllocateClause::Modifier>(
199+
Parser<OmpAllocatorSimpleModifier>{})))))
200+
201+
TYPE_PARSER(sourced(
202+
construct<OmpDefaultmapClause::Modifier>(Parser<OmpVariableCategory>{})))
203+
186204
TYPE_PARSER(sourced(construct<OmpFromClause::Modifier>(
187205
sourced(construct<OmpFromClause::Modifier>(Parser<OmpExpectation>{}) ||
188206
construct<OmpFromClause::Modifier>(Parser<OmpMapper>{}) ||
@@ -211,9 +229,6 @@ TYPE_PARSER(sourced(construct<OmpToClause::Modifier>(
211229
construct<OmpToClause::Modifier>(Parser<OmpMapper>{}) ||
212230
construct<OmpToClause::Modifier>(Parser<OmpIterator>{})))))
213231

214-
TYPE_PARSER(sourced(
215-
construct<OmpDefaultmapClause::Modifier>(Parser<OmpVariableCategory>{})))
216-
217232
// --- Parsers for clauses --------------------------------------------
218233

219234
/// `MOBClause` is a clause that has a
@@ -334,29 +349,7 @@ TYPE_PARSER(construct<OmpInReductionClause>(
334349
// variable-name-list)
335350
// allocate-modifier -> allocator | align
336351
TYPE_PARSER(construct<OmpAllocateClause>(
337-
maybe(
338-
first(
339-
construct<OmpAllocateClause::AllocateModifier>("ALLOCATOR" >>
340-
construct<OmpAllocateClause::AllocateModifier::ComplexModifier>(
341-
parenthesized(construct<
342-
OmpAllocateClause::AllocateModifier::Allocator>(
343-
scalarIntExpr)) /
344-
",",
345-
"ALIGN" >> parenthesized(construct<
346-
OmpAllocateClause::AllocateModifier::Align>(
347-
scalarIntExpr)))),
348-
construct<OmpAllocateClause::AllocateModifier>("ALLOCATOR" >>
349-
parenthesized(
350-
construct<OmpAllocateClause::AllocateModifier::Allocator>(
351-
scalarIntExpr))),
352-
construct<OmpAllocateClause::AllocateModifier>("ALIGN" >>
353-
parenthesized(
354-
construct<OmpAllocateClause::AllocateModifier::Align>(
355-
scalarIntExpr))),
356-
construct<OmpAllocateClause::AllocateModifier>(
357-
construct<OmpAllocateClause::AllocateModifier::Allocator>(
358-
scalarIntExpr))) /
359-
":"),
352+
maybe(nonemptyList(Parser<OmpAllocateClause::Modifier>{}) / ":"),
360353
Parser<OmpObjectList>{}))
361354

362355
// iteration-offset -> +/- non-negative-constant-expr

flang/lib/Parser/unparse.cpp

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2148,35 +2148,21 @@ class UnparseVisitor {
21482148
Walk(std::get<OmpObjectList>(x.t));
21492149
}
21502150
void Unparse(const OmpAllocateClause &x) {
2151-
Walk(
2152-
std::get<std::optional<OmpAllocateClause::AllocateModifier>>(x.t), ":");
2151+
using Modifier = OmpAllocateClause::Modifier;
2152+
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ": ");
21532153
Walk(std::get<OmpObjectList>(x.t));
21542154
}
2155-
void Unparse(const OmpAllocateClause::AllocateModifier &x) {
2156-
common::visit(
2157-
common::visitors{
2158-
[&](const OmpAllocateClause::AllocateModifier::Allocator &y) {
2159-
Walk(y);
2160-
},
2161-
[&](const OmpAllocateClause::AllocateModifier::ComplexModifier &y) {
2162-
Word("ALLOCATOR(");
2163-
Walk(std::get<OmpAllocateClause::AllocateModifier::Allocator>(
2164-
y.t));
2165-
Put(")");
2166-
Put(",");
2167-
Walk(std::get<OmpAllocateClause::AllocateModifier::Align>(y.t));
2168-
},
2169-
[&](const OmpAllocateClause::AllocateModifier::Align &y) {
2170-
Walk(y);
2171-
},
2172-
},
2173-
x.u);
2174-
}
2175-
void Unparse(const OmpAllocateClause::AllocateModifier::Align &x) {
2155+
void Unparse(const OmpAlignModifier &x) {
21762156
Word("ALIGN(");
21772157
Walk(x.v);
21782158
Put(")");
21792159
}
2160+
void Unparse(const OmpAllocatorSimpleModifier &x) { Walk(x.v); }
2161+
void Unparse(const OmpAllocatorComplexModifier &x) {
2162+
Word("ALLOCATOR(");
2163+
Walk(x.v);
2164+
Put(")");
2165+
}
21802166
void Unparse(const OmpOrderClause &x) {
21812167
using Modifier = OmpOrderClause::Modifier;
21822168
Walk(std::get<std::optional<std::list<Modifier>>>(x.t), ":");

flang/lib/Semantics/check-omp-structure.cpp

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1481,34 +1481,26 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Allocator &x) {
14811481

14821482
void OmpStructureChecker::Enter(const parser::OmpClause::Allocate &x) {
14831483
CheckAllowedClause(llvm::omp::Clause::OMPC_allocate);
1484-
if (const auto &modifier{
1485-
std::get<std::optional<parser::OmpAllocateClause::AllocateModifier>>(
1486-
x.v.t)}) {
1487-
common::visit(
1488-
common::visitors{
1489-
[&](const parser::OmpAllocateClause::AllocateModifier::Allocator
1490-
&y) {
1491-
RequiresPositiveParameter(llvm::omp::Clause::OMPC_allocate, y.v);
1492-
isPredefinedAllocator = GetIntValue(y.v).has_value();
1493-
},
1494-
[&](const parser::OmpAllocateClause::AllocateModifier::
1495-
ComplexModifier &y) {
1496-
const auto &alloc = std::get<
1497-
parser::OmpAllocateClause::AllocateModifier::Allocator>(y.t);
1498-
const auto &align =
1499-
std::get<parser::OmpAllocateClause::AllocateModifier::Align>(
1500-
y.t);
1501-
RequiresPositiveParameter(
1502-
llvm::omp::Clause::OMPC_allocate, alloc.v);
1503-
RequiresPositiveParameter(
1504-
llvm::omp::Clause::OMPC_allocate, align.v);
1505-
isPredefinedAllocator = GetIntValue(alloc.v).has_value();
1506-
},
1507-
[&](const parser::OmpAllocateClause::AllocateModifier::Align &y) {
1508-
RequiresPositiveParameter(llvm::omp::Clause::OMPC_allocate, y.v);
1509-
},
1510-
},
1511-
modifier->u);
1484+
if (OmpVerifyModifiers(
1485+
x.v, llvm::omp::OMPC_allocate, GetContext().clauseSource, context_)) {
1486+
auto &modifiers{OmpGetModifiers(x.v)};
1487+
if (auto *align{
1488+
OmpGetUniqueModifier<parser::OmpAlignModifier>(modifiers)}) {
1489+
if (const auto &v{GetIntValue(align->v)}; !v || *v <= 0) {
1490+
context_.Say(OmpGetModifierSource(modifiers, align),
1491+
"The alignment value should be a constant positive integer"_err_en_US);
1492+
}
1493+
}
1494+
// The simple and complex modifiers have the same structure. They only
1495+
// differ in their syntax.
1496+
if (auto *alloc{OmpGetUniqueModifier<parser::OmpAllocatorComplexModifier>(
1497+
modifiers)}) {
1498+
isPredefinedAllocator = GetIntValue(alloc->v).has_value();
1499+
}
1500+
if (auto *alloc{OmpGetUniqueModifier<parser::OmpAllocatorSimpleModifier>(
1501+
modifiers)}) {
1502+
isPredefinedAllocator = GetIntValue(alloc->v).has_value();
1503+
}
15121504
}
15131505
}
15141506

0 commit comments

Comments
 (0)