Skip to content

Commit cd3a5b9

Browse files
committed
[flang][OpenMP] Make all block constructs share the same structure
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 0d64559 commit cd3a5b9

38 files changed

+461
-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))
@@ -584,7 +582,6 @@ class ParseTreeDumper {
584582
NODE(parser, OmpDetachClause)
585583
NODE(parser, OmpDoacrossClause)
586584
NODE(parser, OmpDestroyClause)
587-
NODE(parser, OmpEndBlockDirective)
588585
NODE(parser, OmpEndCriticalDirective)
589586
NODE(parser, OmpEndLoopDirective)
590587
NODE(parser, OmpEndSectionsDirective)
@@ -704,6 +701,8 @@ class ParseTreeDumper {
704701
NODE(parser, OpenMPDeclarativeAssumes)
705702
NODE(parser, OmpAssumeDirective)
706703
NODE(parser, OmpEndAssumeDirective)
704+
NODE(parser, OmpBeginDirective)
705+
NODE(parser, OmpEndDirective)
707706
NODE(parser, OpenMPAtomicConstruct)
708707
NODE(parser, OpenMPBlockConstruct)
709708
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: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3469,6 +3469,13 @@ WRAPPER_CLASS(PauseStmt, std::optional<StopCode>);
34693469

34703470
// --- Common definitions
34713471

3472+
#define INHERITED_TUPLE_CLASS_BOILERPLATE(classname, basename) \
3473+
template <typename... Ts, typename = common::NoLvalue<Ts...>> \
3474+
classname(Ts &&...args) : basename(std::move(args)...) {} \
3475+
classname(basename &&b) : basename(std::move(b)) {} \
3476+
using TupleTrait = std::true_type; \
3477+
BOILERPLATE(classname)
3478+
34723479
#define INHERITED_WRAPPER_CLASS_BOILERPLATE(classname, basename) \
34733480
BOILERPLATE(classname); \
34743481
classname(decltype(basename::v) &&x) : basename(std::move(x)) {} \
@@ -4729,6 +4736,33 @@ struct OmpDirectiveSpecification {
47294736
t;
47304737
};
47314738

4739+
// OmpBeginDirective and OmpEndDirective are needed for semantic analysis,
4740+
// where some checks are done specifically for either the begin or the end
4741+
// directive. The structure of both is identical, but the diffent types
4742+
// allow to distinguish them in the type-based parse-tree visitor.
4743+
struct OmpBeginDirective : public OmpDirectiveSpecification {
4744+
INHERITED_TUPLE_CLASS_BOILERPLATE(
4745+
OmpBeginDirective, OmpDirectiveSpecification);
4746+
};
4747+
4748+
struct OmpEndDirective : public OmpDirectiveSpecification {
4749+
INHERITED_TUPLE_CLASS_BOILERPLATE(OmpEndDirective, OmpDirectiveSpecification);
4750+
};
4751+
4752+
// Common base class for block-associated constructs.
4753+
struct OmpBlockConstruct {
4754+
TUPLE_CLASS_BOILERPLATE(OmpBlockConstruct);
4755+
const OmpBeginDirective &BeginDir() const {
4756+
return std::get<OmpBeginDirective>(t);
4757+
}
4758+
const std::optional<OmpEndDirective> &EndDir() const {
4759+
return std::get<std::optional<OmpEndDirective>>(t);
4760+
}
4761+
4762+
CharBlock source;
4763+
std::tuple<OmpBeginDirective, Block, std::optional<OmpEndDirective>> t;
4764+
};
4765+
47324766
struct OmpMetadirectiveDirective {
47334767
TUPLE_CLASS_BOILERPLATE(OmpMetadirectiveDirective);
47344768
std::tuple<Verbatim, OmpClauseList> t;
@@ -4833,12 +4867,6 @@ struct OpenMPSectionsConstruct {
48334867
t;
48344868
};
48354869

4836-
// OpenMP directive beginning or ending a block
4837-
struct OmpBlockDirective {
4838-
WRAPPER_CLASS_BOILERPLATE(OmpBlockDirective, llvm::omp::Directive);
4839-
CharBlock source;
4840-
};
4841-
48424870
struct OmpDeclareVariantDirective {
48434871
TUPLE_CLASS_BOILERPLATE(OmpDeclareVariantDirective);
48444872
CharBlock source;
@@ -4963,12 +4991,9 @@ struct OpenMPExecutableAllocate {
49634991
// ALLOCATORS [allocate-clause...]
49644992
// block
49654993
// [END ALLOCATORS]
4966-
struct OpenMPAllocatorsConstruct {
4967-
TUPLE_CLASS_BOILERPLATE(OpenMPAllocatorsConstruct);
4968-
CharBlock source;
4969-
std::tuple<OmpDirectiveSpecification, Block,
4970-
std::optional<OmpDirectiveSpecification>>
4971-
t;
4994+
struct OpenMPAllocatorsConstruct : public OmpBlockConstruct {
4995+
INHERITED_TUPLE_CLASS_BOILERPLATE(
4996+
OpenMPAllocatorsConstruct, OmpBlockConstruct);
49724997
};
49734998

49744999
// 2.17.7 Atomic construct/2.17.8 Flush construct [OpenMP 5.0]
@@ -4982,15 +5007,11 @@ struct OmpMemoryOrderClause {
49825007
CharBlock source;
49835008
};
49845009

4985-
struct OpenMPAtomicConstruct {
5010+
struct OpenMPAtomicConstruct : public OmpBlockConstruct {
49865011
llvm::omp::Clause GetKind() const;
49875012
bool IsCapture() const;
49885013
bool IsCompare() const;
4989-
TUPLE_CLASS_BOILERPLATE(OpenMPAtomicConstruct);
4990-
CharBlock source;
4991-
std::tuple<OmpDirectiveSpecification, Block,
4992-
std::optional<OmpDirectiveSpecification>>
4993-
t;
5014+
INHERITED_TUPLE_CLASS_BOILERPLATE(OpenMPAtomicConstruct, OmpBlockConstruct);
49945015

49955016
// Information filled out during semantic checks to avoid duplication
49965017
// of analyses.
@@ -5054,12 +5075,8 @@ struct OpenMPDepobjConstruct {
50545075
// nocontext-clause |
50555076
// novariants-clause |
50565077
// nowait-clause
5057-
struct OpenMPDispatchConstruct {
5058-
TUPLE_CLASS_BOILERPLATE(OpenMPDispatchConstruct);
5059-
CharBlock source;
5060-
std::tuple<OmpDirectiveSpecification, Block,
5061-
std::optional<OmpDirectiveSpecification>>
5062-
t;
5078+
struct OpenMPDispatchConstruct : public OmpBlockConstruct {
5079+
INHERITED_TUPLE_CLASS_BOILERPLATE(OpenMPDispatchConstruct, OmpBlockConstruct);
50635080
};
50645081

50655082
// [4.5:162-165], [5.0:242-246], [5.1:275-279], [5.2:315-316], [6.0:498-500]
@@ -5114,22 +5131,8 @@ struct OmpEndLoopDirective {
51145131
CharBlock source;
51155132
};
51165133

5117-
struct OmpBeginBlockDirective {
5118-
TUPLE_CLASS_BOILERPLATE(OmpBeginBlockDirective);
5119-
std::tuple<OmpBlockDirective, OmpClauseList> t;
5120-
CharBlock source;
5121-
};
5122-
5123-
struct OmpEndBlockDirective {
5124-
TUPLE_CLASS_BOILERPLATE(OmpEndBlockDirective);
5125-
std::tuple<OmpBlockDirective, OmpClauseList> t;
5126-
CharBlock source;
5127-
};
5128-
5129-
struct OpenMPBlockConstruct {
5130-
TUPLE_CLASS_BOILERPLATE(OpenMPBlockConstruct);
5131-
std::tuple<OmpBeginBlockDirective, Block, std::optional<OmpEndBlockDirective>>
5132-
t;
5134+
struct OpenMPBlockConstruct : public OmpBlockConstruct {
5135+
INHERITED_TUPLE_CLASS_BOILERPLATE(OpenMPBlockConstruct, OmpBlockConstruct);
51335136
};
51345137

51355138
// 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
@@ -699,7 +699,7 @@ void Fortran::lower::omp::lowerAtomic(
699699
};
700700

701701
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
702-
auto &dirSpec = std::get<parser::OmpDirectiveSpecification>(construct.t);
702+
const parser::OmpDirectiveSpecification &dirSpec = construct.BeginDir();
703703
omp::List<omp::Clause> clauses = makeClauses(dirSpec.Clauses(), semaCtx);
704704
lower::StatementContext stmtCtx;
705705

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 =
@@ -3716,25 +3709,16 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
37163709
semantics::SemanticsContext &semaCtx,
37173710
lower::pft::Evaluation &eval,
37183711
const parser::OpenMPBlockConstruct &blockConstruct) {
3719-
const auto &beginBlockDirective =
3720-
std::get<parser::OmpBeginBlockDirective>(blockConstruct.t);
3721-
mlir::Location currentLocation =
3722-
converter.genLocation(beginBlockDirective.source);
3723-
const auto origDirective =
3724-
std::get<parser::OmpBlockDirective>(beginBlockDirective.t).v;
3725-
List<Clause> clauses = makeClauses(
3726-
std::get<parser::OmpClauseList>(beginBlockDirective.t), semaCtx);
3727-
3728-
if (const auto &endBlockDirective =
3729-
std::get<std::optional<parser::OmpEndBlockDirective>>(
3730-
blockConstruct.t)) {
3731-
clauses.append(makeClauses(
3732-
std::get<parser::OmpClauseList>(endBlockDirective->t), semaCtx));
3733-
}
3734-
3735-
assert(llvm::omp::blockConstructSet.test(origDirective) &&
3712+
const parser::OmpDirectiveSpecification &beginSpec =
3713+
blockConstruct.BeginDir();
3714+
List<Clause> clauses = makeClauses(beginSpec.Clauses(), semaCtx);
3715+
if (auto &endSpec = blockConstruct.EndDir())
3716+
clauses.append(makeClauses(endSpec->Clauses(), semaCtx));
3717+
3718+
llvm::omp::Directive directive = beginSpec.DirId();
3719+
assert(llvm::omp::blockConstructSet.test(directive) &&
37363720
"Expected block construct");
3737-
(void)origDirective;
3721+
mlir::Location currentLocation = converter.genLocation(beginSpec.source);
37383722

37393723
for (const Clause &clause : clauses) {
37403724
mlir::Location clauseLocation = converter.genLocation(clause.source);
@@ -3777,13 +3761,9 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
37773761
}
37783762
}
37793763

3780-
llvm::omp::Directive directive =
3781-
std::get<parser::OmpBlockDirective>(beginBlockDirective.t).v;
3782-
const parser::CharBlock &source =
3783-
std::get<parser::OmpBlockDirective>(beginBlockDirective.t).source;
37843764
ConstructQueue queue{
37853765
buildConstructQueue(converter.getFirOpBuilder().getModule(), semaCtx,
3786-
eval, source, directive, clauses)};
3766+
eval, beginSpec.source, directive, clauses)};
37873767
genOMPDispatch(converter, symTable, semaCtx, eval, currentLocation, queue,
37883768
queue.begin());
37893769
}
@@ -4071,8 +4051,7 @@ bool Fortran::lower::isOpenMPTargetConstruct(
40714051
const parser::OpenMPConstruct &omp) {
40724052
llvm::omp::Directive dir = llvm::omp::Directive::OMPD_unknown;
40734053
if (const auto *block = std::get_if<parser::OpenMPBlockConstruct>(&omp.u)) {
4074-
const auto &begin = std::get<parser::OmpBeginBlockDirective>(block->t);
4075-
dir = std::get<parser::OmpBlockDirective>(begin.t).v;
4054+
dir = block->BeginDir().DirId();
40764055
} else if (const auto *loop =
40774056
std::get_if<parser::OpenMPLoopConstruct>(&omp.u)) {
40784057
const auto &begin = std::get<parser::OmpBeginLoopDirective>(loop->t);

0 commit comments

Comments
 (0)