Skip to content

Commit 3d3fab1

Browse files
authored
[flang][OpenMP] Use OmpDirectiveSpecification in ALLOCATE (#165865)
The ALLOCATE directive has two forms: - A declarative form with a standalone directive: ``` !$OMP ALLOCATE (variable-list-item...) ``` - An executable form that consists of several directives followed by an ALLOCATE statement: ``` !$OMP ALLOCATE (variable-list-item...) !$OMP ALLOCATE (variable-list-item...) ... ALLOCATE (...) ``` The second form was deprecated in OpenMP 5.2 in favor of the ALLOCATORS construct. Since in the parse tree every type corresponding to a directive only corresponds to a single directive, the executable form is represented by a sequence of nested OmpAllocateDirectives, e.g. ``` !$OMP ALLOCATE(x) !$OMP ALLOCATE(y) ALLOCATE(x, y) ``` will become ``` OmpAllocateDirective |- ALLOCATE(x) // begin directive `- OmpAllocateDirective // block |- ALLOCATE(y) // begin directive `- ALLOCATE(x, y) // block ``` With this change all AST nodes for directives use OmpDirectiveSpecification as the directive representation.
1 parent 795fa9e commit 3d3fab1

27 files changed

+587
-412
lines changed

flang/examples/FeatureList/FeatureList.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ struct NodeVisitor {
445445
READ_FEATURE(ObjectDecl)
446446
READ_FEATURE(OldParameterStmt)
447447
READ_FEATURE(OmpAlignedClause)
448+
READ_FEATURE(OmpAllocateDirective)
448449
READ_FEATURE(OmpBeginDirective)
449450
READ_FEATURE(OmpBeginLoopDirective)
450451
READ_FEATURE(OmpBeginSectionsDirective)
@@ -541,7 +542,6 @@ struct NodeVisitor {
541542
READ_FEATURE(OpenMPCancellationPointConstruct)
542543
READ_FEATURE(OpenMPConstruct)
543544
READ_FEATURE(OpenMPCriticalConstruct)
544-
READ_FEATURE(OpenMPDeclarativeAllocate)
545545
READ_FEATURE(OpenMPDeclarativeConstruct)
546546
READ_FEATURE(OpenMPDeclareReductionConstruct)
547547
READ_FEATURE(OpenMPDeclareSimdConstruct)
@@ -550,7 +550,6 @@ struct NodeVisitor {
550550
READ_FEATURE(OmpAtomicDefaultMemOrderClause)
551551
READ_FEATURE(OpenMPFlushConstruct)
552552
READ_FEATURE(OpenMPLoopConstruct)
553-
READ_FEATURE(OpenMPExecutableAllocate)
554553
READ_FEATURE(OpenMPAllocatorsConstruct)
555554
READ_FEATURE(OpenMPRequiresConstruct)
556555
READ_FEATURE(OpenMPSimpleStandaloneConstruct)

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,7 @@ class ParseTreeDumper {
512512
NODE(parser, OmpAlignModifier)
513513
NODE(parser, OmpAllocateClause)
514514
NODE(OmpAllocateClause, Modifier)
515+
NODE(parser, OmpAllocateDirective)
515516
NODE(parser, OmpAllocatorComplexModifier)
516517
NODE(parser, OmpAllocatorSimpleModifier)
517518
NODE(parser, OmpAlwaysModifier)
@@ -739,7 +740,6 @@ class ParseTreeDumper {
739740
NODE(parser, OpenMPCancellationPointConstruct)
740741
NODE(parser, OpenMPConstruct)
741742
NODE(parser, OpenMPCriticalConstruct)
742-
NODE(parser, OpenMPDeclarativeAllocate)
743743
NODE(parser, OpenMPDeclarativeAssumes)
744744
NODE(parser, OpenMPDeclarativeConstruct)
745745
NODE(parser, OpenMPDeclareMapperConstruct)
@@ -748,7 +748,6 @@ class ParseTreeDumper {
748748
NODE(parser, OpenMPDeclareTargetConstruct)
749749
NODE(parser, OpenMPDepobjConstruct)
750750
NODE(parser, OpenMPDispatchConstruct)
751-
NODE(parser, OpenMPExecutableAllocate)
752751
NODE(parser, OpenMPFlushConstruct)
753752
NODE(parser, OpenMPGroupprivate)
754753
NODE(parser, OpenMPLoopConstruct)

flang/include/flang/Parser/openmp-utils.h

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <type_traits>
2323
#include <utility>
2424
#include <variant>
25+
#include <vector>
2526

2627
namespace Fortran::parser::omp {
2728

@@ -33,23 +34,6 @@ template <typename T> constexpr auto addr_if(const std::optional<T> &x) {
3334
}
3435

3536
namespace detail {
36-
using D = llvm::omp::Directive;
37-
38-
template <typename Construct> //
39-
struct ConstructId {
40-
static constexpr llvm::omp::Directive id{D::OMPD_unknown};
41-
};
42-
43-
#define MAKE_CONSTR_ID(Construct, Id) \
44-
template <> struct ConstructId<Construct> { \
45-
static constexpr llvm::omp::Directive id{Id}; \
46-
}
47-
48-
MAKE_CONSTR_ID(OpenMPDeclarativeAllocate, D::OMPD_allocate);
49-
MAKE_CONSTR_ID(OpenMPExecutableAllocate, D::OMPD_allocate);
50-
51-
#undef MAKE_CONSTR_ID
52-
5337
struct DirectiveNameScope {
5438
static OmpDirectiveName MakeName(CharBlock source = {},
5539
llvm::omp::Directive id = llvm::omp::Directive::OMPD_unknown) {
@@ -97,9 +81,6 @@ struct DirectiveNameScope {
9781
} else if constexpr (TupleTrait<T>) {
9882
if constexpr (std::is_base_of_v<OmpBlockConstruct, T>) {
9983
return std::get<OmpBeginDirective>(x.t).DirName();
100-
} else if constexpr (std::is_same_v<T, OpenMPDeclarativeAllocate> ||
101-
std::is_same_v<T, OpenMPExecutableAllocate>) {
102-
return MakeName(std::get<Verbatim>(x.t).source, ConstructId<T>::id);
10384
} else {
10485
return GetFromTuple(
10586
x.t, std::make_index_sequence<std::tuple_size_v<decltype(x.t)>>{});
@@ -139,6 +120,9 @@ template <typename T> OmpDirectiveName GetOmpDirectiveName(const T &x) {
139120
return detail::DirectiveNameScope::GetOmpDirectiveName(x);
140121
}
141122

123+
const OpenMPDeclarativeConstruct *GetOmp(const DeclarationConstruct &x);
124+
const OpenMPConstruct *GetOmp(const ExecutionPartConstruct &x);
125+
142126
const OmpObjectList *GetOmpObjectList(const OmpClause &clause);
143127

144128
template <typename T>
@@ -158,6 +142,13 @@ const OmpCombinerExpression *GetCombinerExpr(
158142
const OmpReductionSpecifier &rspec);
159143
const OmpInitializerExpression *GetInitializerExpr(const OmpClause &init);
160144

145+
struct OmpAllocateInfo {
146+
std::vector<const OmpAllocateDirective *> dirs;
147+
const ExecutionPartConstruct *body{nullptr};
148+
};
149+
150+
OmpAllocateInfo SplitOmpAllocate(const OmpAllocateDirective &x);
151+
161152
} // namespace Fortran::parser::omp
162153

163154
#endif // FORTRAN_PARSER_OPENMP_UTILS_H

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

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5151,17 +5151,42 @@ struct OpenMPThreadprivate {
51515151
CharBlock source;
51525152
};
51535153

5154-
// 2.11.3 allocate -> ALLOCATE (variable-name-list) [clause]
5155-
struct OpenMPDeclarativeAllocate {
5156-
TUPLE_CLASS_BOILERPLATE(OpenMPDeclarativeAllocate);
5157-
CharBlock source;
5158-
std::tuple<Verbatim, std::optional<OmpObjectList>, OmpClauseList> t;
5154+
// Ref: [4.5:310-312], [5.0:156-158], [5.1:181-184], [5.2:176-177],
5155+
// [6.0:310-312]
5156+
//
5157+
// allocate-directive ->
5158+
// ALLOCATE (variable-list-item...) | // since 4.5
5159+
// ALLOCATE (variable-list-item...) // since 5.0, until 5.1
5160+
// ...
5161+
// allocate-stmt
5162+
//
5163+
// The first form is the "declarative-allocate", and is a declarative
5164+
// directive. The second is the "executable-allocate" and is an executable
5165+
// directive. The executable form was deprecated in 5.2.
5166+
//
5167+
// The executable-allocate consists of several ALLOCATE directives. Since
5168+
// in the parse tree every type corresponding to a directive only corresponds
5169+
// to a single directive, the executable form is represented by a sequence
5170+
// of nested OmpAlocateDirectives, e.g.
5171+
// !$OMP ALLOCATE(x)
5172+
// !$OMP ALLOCATE(y)
5173+
// ALLOCATE(x, y)
5174+
// will become
5175+
// OmpAllocateDirective
5176+
// |- ALLOCATE(x) // begin directive
5177+
// `- OmpAllocateDirective // block
5178+
// |- ALLOCATE(y) // begin directive
5179+
// `- ALLOCATE(x, y) // block
5180+
//
5181+
// The block in the declarative-allocate will be empty.
5182+
struct OmpAllocateDirective : public OmpBlockConstruct {
5183+
INHERITED_TUPLE_CLASS_BOILERPLATE(OmpAllocateDirective, OmpBlockConstruct);
51595184
};
51605185

51615186
struct OpenMPDeclarativeConstruct {
51625187
UNION_CLASS_BOILERPLATE(OpenMPDeclarativeConstruct);
51635188
CharBlock source;
5164-
std::variant<OpenMPDeclarativeAllocate, OpenMPDeclarativeAssumes,
5189+
std::variant<OmpAllocateDirective, OpenMPDeclarativeAssumes,
51655190
OpenMPDeclareMapperConstruct, OpenMPDeclareReductionConstruct,
51665191
OpenMPDeclareSimdConstruct, OpenMPDeclareTargetConstruct,
51675192
OmpDeclareVariantDirective, OpenMPGroupprivate, OpenMPThreadprivate,
@@ -5174,19 +5199,6 @@ struct OpenMPCriticalConstruct : public OmpBlockConstruct {
51745199
INHERITED_TUPLE_CLASS_BOILERPLATE(OpenMPCriticalConstruct, OmpBlockConstruct);
51755200
};
51765201

5177-
// 2.11.3 allocate -> ALLOCATE [(variable-name-list)] [clause]
5178-
// [ALLOCATE (variable-name-list) [clause] [...]]
5179-
// allocate-statement
5180-
// clause -> allocator-clause
5181-
struct OpenMPExecutableAllocate {
5182-
TUPLE_CLASS_BOILERPLATE(OpenMPExecutableAllocate);
5183-
CharBlock source;
5184-
std::tuple<Verbatim, std::optional<OmpObjectList>, OmpClauseList,
5185-
std::optional<std::list<OpenMPDeclarativeAllocate>>,
5186-
Statement<AllocateStmt>>
5187-
t;
5188-
};
5189-
51905202
// Ref: [5.2:180-181], [6.0:315]
51915203
//
51925204
// allocators-construct ->
@@ -5342,9 +5354,9 @@ struct OpenMPConstruct {
53425354
UNION_CLASS_BOILERPLATE(OpenMPConstruct);
53435355
std::variant<OpenMPStandaloneConstruct, OpenMPSectionsConstruct,
53445356
OpenMPSectionConstruct, OpenMPLoopConstruct, OmpBlockConstruct,
5345-
OpenMPAtomicConstruct, OpenMPDeclarativeAllocate, OpenMPDispatchConstruct,
5346-
OpenMPUtilityConstruct, OpenMPExecutableAllocate,
5347-
OpenMPAllocatorsConstruct, OpenMPAssumeConstruct, OpenMPCriticalConstruct>
5357+
OpenMPAtomicConstruct, OmpAllocateDirective, OpenMPDispatchConstruct,
5358+
OpenMPUtilityConstruct, OpenMPAllocatorsConstruct, OpenMPAssumeConstruct,
5359+
OpenMPCriticalConstruct>
53485360
u;
53495361
};
53505362

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3503,12 +3503,12 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
35033503
lower::pft::Evaluation &eval,
35043504
const parser::OpenMPUtilityConstruct &);
35053505

3506-
static void
3507-
genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
3508-
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
3509-
const parser::OpenMPDeclarativeAllocate &declarativeAllocate) {
3506+
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
3507+
semantics::SemanticsContext &semaCtx,
3508+
lower::pft::Evaluation &eval,
3509+
const parser::OmpAllocateDirective &allocate) {
35103510
if (!semaCtx.langOptions().OpenMPSimd)
3511-
TODO(converter.getCurrentLocation(), "OpenMPDeclarativeAllocate");
3511+
TODO(converter.getCurrentLocation(), "OmpAllocateDirective");
35123512
}
35133513

35143514
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
@@ -3899,14 +3899,6 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
38993899
TODO(converter.getCurrentLocation(), "OpenMPDispatchConstruct");
39003900
}
39013901

3902-
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
3903-
semantics::SemanticsContext &semaCtx,
3904-
lower::pft::Evaluation &eval,
3905-
const parser::OpenMPExecutableAllocate &execAllocConstruct) {
3906-
if (!semaCtx.langOptions().OpenMPSimd)
3907-
TODO(converter.getCurrentLocation(), "OpenMPExecutableAllocate");
3908-
}
3909-
39103902
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
39113903
semantics::SemanticsContext &semaCtx,
39123904
lower::pft::Evaluation &eval,

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1778,6 +1778,31 @@ struct OmpBlockConstructParser {
17781778
llvm::omp::Directive dir_;
17791779
};
17801780

1781+
struct OmpDeclarativeAllocateParser {
1782+
using resultType = OmpAllocateDirective;
1783+
1784+
std::optional<resultType> Parse(ParseState &state) const {
1785+
constexpr llvm::omp::Directive dir{llvm::omp::Directive::OMPD_allocate};
1786+
if (auto &&begin{attempt(OmpBeginDirectiveParser(dir)).Parse(state)}) {
1787+
Block empty;
1788+
auto end{maybe(OmpEndDirectiveParser{dir}).Parse(state)};
1789+
return OmpAllocateDirective{std::move(*begin), std::move(empty),
1790+
llvm::transformOptional(std::move(*end),
1791+
[](auto &&s) { return OmpEndDirective(std::move(s)); })};
1792+
}
1793+
return std::nullopt;
1794+
}
1795+
};
1796+
1797+
struct OmpExecutableAllocateParser {
1798+
using resultType = OmpAllocateDirective;
1799+
1800+
std::optional<resultType> Parse(ParseState &state) const {
1801+
OmpStatementConstructParser p{llvm::omp::Directive::OMPD_allocate};
1802+
return construct<OmpAllocateDirective>(p).Parse(state);
1803+
}
1804+
};
1805+
17811806
TYPE_PARSER(sourced(construct<OpenMPAllocatorsConstruct>(
17821807
OmpStatementConstructParser{llvm::omp::Directive::OMPD_allocators})))
17831808

@@ -2044,14 +2069,6 @@ TYPE_PARSER(construct<OmpInitializerExpression>(OmpStylizedExpressionParser{}))
20442069
TYPE_PARSER(sourced(construct<OpenMPCriticalConstruct>(
20452070
OmpBlockConstructParser{llvm::omp::Directive::OMPD_critical})))
20462071

2047-
// 2.11.3 Executable Allocate directive
2048-
TYPE_PARSER(sourced(construct<OpenMPExecutableAllocate>(
2049-
verbatim("ALLOCATE"_tok), maybe(parenthesized(Parser<OmpObjectList>{})),
2050-
Parser<OmpClauseList>{},
2051-
maybe(nonemptyList(startOmpLine >> Parser<OpenMPDeclarativeAllocate>{})) /
2052-
endOmpLine,
2053-
statement(allocateStmt))))
2054-
20552072
// 2.8.2 Declare Simd construct
20562073
TYPE_PARSER(sourced(construct<OpenMPDeclareSimdConstruct>(
20572074
predicated(Parser<OmpDirectiveName>{},
@@ -2077,13 +2094,6 @@ TYPE_PARSER(sourced( //
20772094
IsDirective(llvm::omp::Directive::OMPD_threadprivate)) >=
20782095
Parser<OmpDirectiveSpecification>{})))
20792096

2080-
// 2.11.3 Declarative Allocate directive
2081-
TYPE_PARSER(
2082-
sourced(construct<OpenMPDeclarativeAllocate>(verbatim("ALLOCATE"_tok),
2083-
maybe(parenthesized(Parser<OmpObjectList>{})),
2084-
Parser<OmpClauseList>{})) /
2085-
lookAhead(endOmpLine / !statement(allocateStmt)))
2086-
20872097
// Assumes Construct
20882098
TYPE_PARSER(sourced(construct<OpenMPDeclarativeAssumes>(
20892099
predicated(OmpDirectiveNameParser{},
@@ -2106,7 +2116,7 @@ TYPE_PARSER(
21062116
construct<OpenMPDeclarativeConstruct>(
21072117
Parser<OmpDeclareVariantDirective>{}) ||
21082118
construct<OpenMPDeclarativeConstruct>(
2109-
Parser<OpenMPDeclarativeAllocate>{}) ||
2119+
sourced(OmpDeclarativeAllocateParser{})) ||
21102120
construct<OpenMPDeclarativeConstruct>(
21112121
Parser<OpenMPGroupprivate>{}) ||
21122122
construct<OpenMPDeclarativeConstruct>(
@@ -2194,16 +2204,16 @@ TYPE_CONTEXT_PARSER("OpenMP construct"_en_US,
21942204
withMessage("expected OpenMP construct"_err_en_US,
21952205
first(construct<OpenMPConstruct>(Parser<OpenMPSectionsConstruct>{}),
21962206
construct<OpenMPConstruct>(Parser<OpenMPLoopConstruct>{}),
2207+
construct<OpenMPConstruct>(
2208+
sourced(OmpExecutableAllocateParser{})),
21972209
construct<OpenMPConstruct>(Parser<OmpBlockConstruct>{}),
21982210
// OmpBlockConstruct is attempted before
21992211
// OpenMPStandaloneConstruct to resolve !$OMP ORDERED
22002212
construct<OpenMPConstruct>(Parser<OpenMPStandaloneConstruct>{}),
22012213
construct<OpenMPConstruct>(Parser<OpenMPAtomicConstruct>{}),
22022214
construct<OpenMPConstruct>(Parser<OpenMPUtilityConstruct>{}),
22032215
construct<OpenMPConstruct>(Parser<OpenMPDispatchConstruct>{}),
2204-
construct<OpenMPConstruct>(Parser<OpenMPExecutableAllocate>{}),
22052216
construct<OpenMPConstruct>(Parser<OpenMPAllocatorsConstruct>{}),
2206-
construct<OpenMPConstruct>(Parser<OpenMPDeclarativeAllocate>{}),
22072217
construct<OpenMPConstruct>(Parser<OpenMPAssumeConstruct>{}),
22082218
construct<OpenMPConstruct>(Parser<OpenMPCriticalConstruct>{}))))
22092219

flang/lib/Parser/openmp-utils.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,25 @@
2222

2323
namespace Fortran::parser::omp {
2424

25+
const OpenMPDeclarativeConstruct *GetOmp(const DeclarationConstruct &x) {
26+
if (auto *y = std::get_if<SpecificationConstruct>(&x.u)) {
27+
if (auto *z{std::get_if<common::Indirection<OpenMPDeclarativeConstruct>>(
28+
&y->u)}) {
29+
return &z->value();
30+
}
31+
}
32+
return nullptr;
33+
}
34+
35+
const OpenMPConstruct *GetOmp(const ExecutionPartConstruct &x) {
36+
if (auto *y{std::get_if<ExecutableConstruct>(&x.u)}) {
37+
if (auto *z{std::get_if<common::Indirection<OpenMPConstruct>>(&y->u)}) {
38+
return &z->value();
39+
}
40+
}
41+
return nullptr;
42+
}
43+
2544
const OmpObjectList *GetOmpObjectList(const OmpClause &clause) {
2645
// Clauses with OmpObjectList as its data member
2746
using MemberObjectListClauses = std::tuple<OmpClause::Copyin,
@@ -86,4 +105,24 @@ const OmpInitializerExpression *GetInitializerExpr(const OmpClause &init) {
86105
return nullptr;
87106
}
88107

108+
static void SplitOmpAllocateHelper(
109+
OmpAllocateInfo &n, const OmpAllocateDirective &x) {
110+
n.dirs.push_back(&x);
111+
const Block &body{std::get<Block>(x.t)};
112+
if (!body.empty()) {
113+
if (auto *omp{GetOmp(body.front())}) {
114+
if (auto *ad{std::get_if<OmpAllocateDirective>(&omp->u)}) {
115+
return SplitOmpAllocateHelper(n, *ad);
116+
}
117+
}
118+
n.body = &body.front();
119+
}
120+
}
121+
122+
OmpAllocateInfo SplitOmpAllocate(const OmpAllocateDirective &x) {
123+
OmpAllocateInfo info;
124+
SplitOmpAllocateHelper(info, x);
125+
return info;
126+
}
127+
89128
} // namespace Fortran::parser::omp

0 commit comments

Comments
 (0)