Skip to content

Commit 6533ad0

Browse files
authored
[flang][OpenMP] Make all block constructs share the same structure (#150956)
The structure is - OmpBeginDirective (aka OmpDirectiveSpecification) - Block - optional<OmpEndDirective> (aka optional<OmpDirectiveSpecification>) The OmpBeginDirective and OmpEndDirective are effectively different names for OmpDirectiveSpecification. They exist to allow the semantic analyses to distinguish between the beginning and the ending of a block construct without maintaining additional context. The actual changes are in the parser: parse-tree.h and openmp-parser.cpp in particular. The rest is simply changing the way the directive/clause information is accessed (typically for the simpler). All standalone and block constructs now use OmpDirectiveSpecification to store the directive/clause information.
1 parent 1ee1bdd commit 6533ad0

38 files changed

+460
-557
lines changed

flang/examples/FeatureList/FeatureList.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -445,10 +445,9 @@ struct NodeVisitor {
445445
READ_FEATURE(ObjectDecl)
446446
READ_FEATURE(OldParameterStmt)
447447
READ_FEATURE(OmpAlignedClause)
448-
READ_FEATURE(OmpBeginBlockDirective)
448+
READ_FEATURE(OmpBeginDirective)
449449
READ_FEATURE(OmpBeginLoopDirective)
450450
READ_FEATURE(OmpBeginSectionsDirective)
451-
READ_FEATURE(OmpBlockDirective)
452451
READ_FEATURE(OmpClause)
453452
READ_FEATURE(OmpClauseList)
454453
READ_FEATURE(OmpCriticalDirective)
@@ -472,7 +471,7 @@ struct NodeVisitor {
472471
READ_FEATURE(OmpIteration)
473472
READ_FEATURE(OmpIterationOffset)
474473
READ_FEATURE(OmpIterationVector)
475-
READ_FEATURE(OmpEndBlockDirective)
474+
READ_FEATURE(OmpEndDirective)
476475
READ_FEATURE(OmpEndCriticalDirective)
477476
READ_FEATURE(OmpEndLoopDirective)
478477
READ_FEATURE(OmpEndSectionsDirective)

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -534,10 +534,8 @@ class ParseTreeDumper {
534534
NODE(parser, OmpAtClause)
535535
NODE_ENUM(OmpAtClause, ActionTime)
536536
NODE_ENUM(OmpSeverityClause, Severity)
537-
NODE(parser, OmpBeginBlockDirective)
538537
NODE(parser, OmpBeginLoopDirective)
539538
NODE(parser, OmpBeginSectionsDirective)
540-
NODE(parser, OmpBlockDirective)
541539
static std::string GetNodeName(const llvm::omp::Directive &x) {
542540
return llvm::Twine("llvm::omp::Directive = ",
543541
llvm::omp::getOpenMPDirectiveName(x, llvm::omp::FallbackVersion))
@@ -586,7 +584,6 @@ class ParseTreeDumper {
586584
NODE(parser, OmpDetachClause)
587585
NODE(parser, OmpDoacrossClause)
588586
NODE(parser, OmpDestroyClause)
589-
NODE(parser, OmpEndBlockDirective)
590587
NODE(parser, OmpEndCriticalDirective)
591588
NODE(parser, OmpEndLoopDirective)
592589
NODE(parser, OmpEndSectionsDirective)
@@ -708,6 +705,8 @@ class ParseTreeDumper {
708705
NODE(parser, OpenMPDeclarativeAssumes)
709706
NODE(parser, OmpAssumeDirective)
710707
NODE(parser, OmpEndAssumeDirective)
708+
NODE(parser, OmpBeginDirective)
709+
NODE(parser, OmpEndDirective)
711710
NODE(parser, OpenMPAtomicConstruct)
712711
NODE(parser, OpenMPBlockConstruct)
713712
NODE(parser, OpenMPCancelConstruct)

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

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,6 @@ struct DirectiveNameScope {
6868
return MakeName(x.source, llvm::omp::Directive::OMPD_nothing);
6969
}
7070

71-
static OmpDirectiveName GetOmpDirectiveName(const OmpBeginBlockDirective &x) {
72-
auto &dir{std::get<OmpBlockDirective>(x.t)};
73-
return MakeName(dir.source, dir.v);
74-
}
75-
7671
static OmpDirectiveName GetOmpDirectiveName(const OmpBeginLoopDirective &x) {
7772
auto &dir{std::get<OmpLoopDirective>(x.t)};
7873
return MakeName(dir.source, dir.v);
@@ -106,10 +101,8 @@ struct DirectiveNameScope {
106101
return GetOmpDirectiveName(x.v);
107102
}
108103
} else if constexpr (TupleTrait<T>) {
109-
if constexpr (std::is_same_v<T, OpenMPAllocatorsConstruct> ||
110-
std::is_same_v<T, OpenMPAtomicConstruct> ||
111-
std::is_same_v<T, OpenMPDispatchConstruct>) {
112-
return std::get<OmpDirectiveSpecification>(x.t).DirName();
104+
if constexpr (std::is_base_of_v<OmpBlockConstruct, T>) {
105+
return std::get<OmpBeginDirective>(x.t).DirName();
113106
} else if constexpr (std::is_same_v<T, OmpAssumeDirective> ||
114107
std::is_same_v<T, OmpCriticalDirective> ||
115108
std::is_same_v<T, OmpDeclareVariantDirective> ||

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

Lines changed: 42 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3469,6 +3469,12 @@ WRAPPER_CLASS(PauseStmt, std::optional<StopCode>);
34693469

34703470
// --- Common definitions
34713471

3472+
#define INHERITED_TUPLE_CLASS_BOILERPLATE(classname, basename) \
3473+
using basename::basename; \
3474+
classname(basename &&b) : basename(std::move(b)) {} \
3475+
using TupleTrait = std::true_type; \
3476+
BOILERPLATE(classname)
3477+
34723478
#define INHERITED_WRAPPER_CLASS_BOILERPLATE(classname, basename) \
34733479
BOILERPLATE(classname); \
34743480
using basename::basename; \
@@ -4750,6 +4756,33 @@ struct OmpDirectiveSpecification {
47504756
t;
47514757
};
47524758

4759+
// OmpBeginDirective and OmpEndDirective are needed for semantic analysis,
4760+
// where some checks are done specifically for either the begin or the end
4761+
// directive. The structure of both is identical, but the diffent types
4762+
// allow to distinguish them in the type-based parse-tree visitor.
4763+
struct OmpBeginDirective : public OmpDirectiveSpecification {
4764+
INHERITED_TUPLE_CLASS_BOILERPLATE(
4765+
OmpBeginDirective, OmpDirectiveSpecification);
4766+
};
4767+
4768+
struct OmpEndDirective : public OmpDirectiveSpecification {
4769+
INHERITED_TUPLE_CLASS_BOILERPLATE(OmpEndDirective, OmpDirectiveSpecification);
4770+
};
4771+
4772+
// Common base class for block-associated constructs.
4773+
struct OmpBlockConstruct {
4774+
TUPLE_CLASS_BOILERPLATE(OmpBlockConstruct);
4775+
const OmpBeginDirective &BeginDir() const {
4776+
return std::get<OmpBeginDirective>(t);
4777+
}
4778+
const std::optional<OmpEndDirective> &EndDir() const {
4779+
return std::get<std::optional<OmpEndDirective>>(t);
4780+
}
4781+
4782+
CharBlock source;
4783+
std::tuple<OmpBeginDirective, Block, std::optional<OmpEndDirective>> t;
4784+
};
4785+
47534786
struct OmpMetadirectiveDirective {
47544787
TUPLE_CLASS_BOILERPLATE(OmpMetadirectiveDirective);
47554788
std::tuple<Verbatim, OmpClauseList> t;
@@ -4854,12 +4887,6 @@ struct OpenMPSectionsConstruct {
48544887
t;
48554888
};
48564889

4857-
// OpenMP directive beginning or ending a block
4858-
struct OmpBlockDirective {
4859-
WRAPPER_CLASS_BOILERPLATE(OmpBlockDirective, llvm::omp::Directive);
4860-
CharBlock source;
4861-
};
4862-
48634890
struct OmpDeclareVariantDirective {
48644891
TUPLE_CLASS_BOILERPLATE(OmpDeclareVariantDirective);
48654892
CharBlock source;
@@ -4984,12 +5011,9 @@ struct OpenMPExecutableAllocate {
49845011
// ALLOCATORS [allocate-clause...]
49855012
// block
49865013
// [END ALLOCATORS]
4987-
struct OpenMPAllocatorsConstruct {
4988-
TUPLE_CLASS_BOILERPLATE(OpenMPAllocatorsConstruct);
4989-
CharBlock source;
4990-
std::tuple<OmpDirectiveSpecification, Block,
4991-
std::optional<OmpDirectiveSpecification>>
4992-
t;
5014+
struct OpenMPAllocatorsConstruct : public OmpBlockConstruct {
5015+
INHERITED_TUPLE_CLASS_BOILERPLATE(
5016+
OpenMPAllocatorsConstruct, OmpBlockConstruct);
49935017
};
49945018

49955019
// 2.17.7 Atomic construct/2.17.8 Flush construct [OpenMP 5.0]
@@ -5003,15 +5027,11 @@ struct OmpMemoryOrderClause {
50035027
CharBlock source;
50045028
};
50055029

5006-
struct OpenMPAtomicConstruct {
5030+
struct OpenMPAtomicConstruct : public OmpBlockConstruct {
50075031
llvm::omp::Clause GetKind() const;
50085032
bool IsCapture() const;
50095033
bool IsCompare() const;
5010-
TUPLE_CLASS_BOILERPLATE(OpenMPAtomicConstruct);
5011-
CharBlock source;
5012-
std::tuple<OmpDirectiveSpecification, Block,
5013-
std::optional<OmpDirectiveSpecification>>
5014-
t;
5034+
INHERITED_TUPLE_CLASS_BOILERPLATE(OpenMPAtomicConstruct, OmpBlockConstruct);
50155035

50165036
// Information filled out during semantic checks to avoid duplication
50175037
// of analyses.
@@ -5075,12 +5095,8 @@ struct OpenMPDepobjConstruct {
50755095
// nocontext-clause |
50765096
// novariants-clause |
50775097
// nowait-clause
5078-
struct OpenMPDispatchConstruct {
5079-
TUPLE_CLASS_BOILERPLATE(OpenMPDispatchConstruct);
5080-
CharBlock source;
5081-
std::tuple<OmpDirectiveSpecification, Block,
5082-
std::optional<OmpDirectiveSpecification>>
5083-
t;
5098+
struct OpenMPDispatchConstruct : public OmpBlockConstruct {
5099+
INHERITED_TUPLE_CLASS_BOILERPLATE(OpenMPDispatchConstruct, OmpBlockConstruct);
50845100
};
50855101

50865102
// [4.5:162-165], [5.0:242-246], [5.1:275-279], [5.2:315-316], [6.0:498-500]
@@ -5135,22 +5151,8 @@ struct OmpEndLoopDirective {
51355151
CharBlock source;
51365152
};
51375153

5138-
struct OmpBeginBlockDirective {
5139-
TUPLE_CLASS_BOILERPLATE(OmpBeginBlockDirective);
5140-
std::tuple<OmpBlockDirective, OmpClauseList> t;
5141-
CharBlock source;
5142-
};
5143-
5144-
struct OmpEndBlockDirective {
5145-
TUPLE_CLASS_BOILERPLATE(OmpEndBlockDirective);
5146-
std::tuple<OmpBlockDirective, OmpClauseList> t;
5147-
CharBlock source;
5148-
};
5149-
5150-
struct OpenMPBlockConstruct {
5151-
TUPLE_CLASS_BOILERPLATE(OpenMPBlockConstruct);
5152-
std::tuple<OmpBeginBlockDirective, Block, std::optional<OmpEndBlockDirective>>
5153-
t;
5154+
struct OpenMPBlockConstruct : public OmpBlockConstruct {
5155+
INHERITED_TUPLE_CLASS_BOILERPLATE(OpenMPBlockConstruct, OmpBlockConstruct);
51545156
};
51555157

51565158
// OpenMP directives enclosing do loop

flang/lib/Lower/OpenMP/Atomic.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,7 @@ void Fortran::lower::omp::lowerAtomic(
707707
};
708708

709709
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
710-
auto &dirSpec = std::get<parser::OmpDirectiveSpecification>(construct.t);
710+
const parser::OmpDirectiveSpecification &dirSpec = construct.BeginDir();
711711
omp::List<omp::Clause> clauses = makeClauses(dirSpec.Clauses(), semaCtx);
712712
lower::StatementContext stmtCtx;
713713

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 14 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -407,16 +407,9 @@ static void processHostEvalClauses(lower::AbstractConverter &converter,
407407
common::visit(
408408
common::visitors{
409409
[&](const parser::OpenMPBlockConstruct &ompConstruct) {
410-
const auto &beginDirective =
411-
std::get<parser::OmpBeginBlockDirective>(ompConstruct.t);
412-
beginClauseList =
413-
&std::get<parser::OmpClauseList>(beginDirective.t);
414-
if (auto &endDirective =
415-
std::get<std::optional<parser::OmpEndBlockDirective>>(
416-
ompConstruct.t)) {
417-
endClauseList =
418-
&std::get<parser::OmpClauseList>(endDirective->t);
419-
}
410+
beginClauseList = &ompConstruct.BeginDir().Clauses();
411+
if (auto &endSpec = ompConstruct.EndDir())
412+
endClauseList = &endSpec->Clauses();
420413
},
421414
[&](const parser::OpenMPLoopConstruct &ompConstruct) {
422415
const auto &beginDirective =
@@ -3733,25 +3726,16 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
37333726
semantics::SemanticsContext &semaCtx,
37343727
lower::pft::Evaluation &eval,
37353728
const parser::OpenMPBlockConstruct &blockConstruct) {
3736-
const auto &beginBlockDirective =
3737-
std::get<parser::OmpBeginBlockDirective>(blockConstruct.t);
3738-
mlir::Location currentLocation =
3739-
converter.genLocation(beginBlockDirective.source);
3740-
const auto origDirective =
3741-
std::get<parser::OmpBlockDirective>(beginBlockDirective.t).v;
3742-
List<Clause> clauses = makeClauses(
3743-
std::get<parser::OmpClauseList>(beginBlockDirective.t), semaCtx);
3744-
3745-
if (const auto &endBlockDirective =
3746-
std::get<std::optional<parser::OmpEndBlockDirective>>(
3747-
blockConstruct.t)) {
3748-
clauses.append(makeClauses(
3749-
std::get<parser::OmpClauseList>(endBlockDirective->t), semaCtx));
3750-
}
3751-
3752-
assert(llvm::omp::blockConstructSet.test(origDirective) &&
3729+
const parser::OmpDirectiveSpecification &beginSpec =
3730+
blockConstruct.BeginDir();
3731+
List<Clause> clauses = makeClauses(beginSpec.Clauses(), semaCtx);
3732+
if (auto &endSpec = blockConstruct.EndDir())
3733+
clauses.append(makeClauses(endSpec->Clauses(), semaCtx));
3734+
3735+
llvm::omp::Directive directive = beginSpec.DirId();
3736+
assert(llvm::omp::blockConstructSet.test(directive) &&
37533737
"Expected block construct");
3754-
(void)origDirective;
3738+
mlir::Location currentLocation = converter.genLocation(beginSpec.source);
37553739

37563740
for (const Clause &clause : clauses) {
37573741
mlir::Location clauseLocation = converter.genLocation(clause.source);
@@ -3794,13 +3778,9 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
37943778
}
37953779
}
37963780

3797-
llvm::omp::Directive directive =
3798-
std::get<parser::OmpBlockDirective>(beginBlockDirective.t).v;
3799-
const parser::CharBlock &source =
3800-
std::get<parser::OmpBlockDirective>(beginBlockDirective.t).source;
38013781
ConstructQueue queue{
38023782
buildConstructQueue(converter.getFirOpBuilder().getModule(), semaCtx,
3803-
eval, source, directive, clauses)};
3783+
eval, beginSpec.source, directive, clauses)};
38043784
genOMPDispatch(converter, symTable, semaCtx, eval, currentLocation, queue,
38053785
queue.begin());
38063786
}
@@ -4088,8 +4068,7 @@ bool Fortran::lower::isOpenMPTargetConstruct(
40884068
const parser::OpenMPConstruct &omp) {
40894069
llvm::omp::Directive dir = llvm::omp::Directive::OMPD_unknown;
40904070
if (const auto *block = std::get_if<parser::OpenMPBlockConstruct>(&omp.u)) {
4091-
const auto &begin = std::get<parser::OmpBeginBlockDirective>(block->t);
4092-
dir = std::get<parser::OmpBlockDirective>(begin.t).v;
4071+
dir = block->BeginDir().DirId();
40934072
} else if (const auto *loop =
40944073
std::get_if<parser::OpenMPLoopConstruct>(&omp.u)) {
40954074
const auto &begin = std::get<parser::OmpBeginLoopDirective>(loop->t);

0 commit comments

Comments
 (0)