Skip to content

Commit 7f43bc7

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 a70f7da commit 7f43bc7

38 files changed

+478
-574
lines changed

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)
@@ -705,6 +702,8 @@ class ParseTreeDumper {
705702
NODE(parser, OpenMPDeclarativeAssumes)
706703
NODE(parser, OmpAssumeDirective)
707704
NODE(parser, OmpEndAssumeDirective)
705+
NODE(parser, OmpBeginDirective)
706+
NODE(parser, OmpEndDirective)
708707
NODE(parser, OpenMPAtomicConstruct)
709708
NODE(parser, OpenMPBlockConstruct)
710709
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);
@@ -98,10 +93,8 @@ struct DirectiveNameScope {
9893
return GetOmpDirectiveName(x.v);
9994
}
10095
} else if constexpr (TupleTrait<T>) {
101-
if constexpr (std::is_same_v<T, OpenMPAllocatorsConstruct> ||
102-
std::is_same_v<T, OpenMPAtomicConstruct> ||
103-
std::is_same_v<T, OpenMPDispatchConstruct>) {
104-
return std::get<OmpDirectiveSpecification>(x.t).DirName();
96+
if constexpr (std::is_base_of_v<OmpBlockConstruct, T>) {
97+
return std::get<OmpBeginDirective>(x.t).DirName();
10598
} else if constexpr (std::is_same_v<T, OmpAssumeDirective> ||
10699
std::is_same_v<T, OmpCriticalDirective> ||
107100
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
@@ -4701,6 +4701,13 @@ struct OmpClauseList {
47014701

47024702
// --- Directives and constructs
47034703

4704+
#define INHERITED_TUPLE_CLASS_BOILERPLATE(classname, basename) \
4705+
template <typename... Ts, typename = common::NoLvalue<Ts...>> \
4706+
classname(Ts &&...args) : basename(std::move(args)...) {} \
4707+
classname(basename &&b) : basename(std::move(b)) {} \
4708+
using TupleTrait = std::true_type; \
4709+
BOILERPLATE(classname)
4710+
47044711
struct OmpDirectiveSpecification {
47054712
ENUM_CLASS(Flags, None, DeprecatedSyntax);
47064713
TUPLE_CLASS_BOILERPLATE(OmpDirectiveSpecification);
@@ -4719,6 +4726,33 @@ struct OmpDirectiveSpecification {
47194726
t;
47204727
};
47214728

4729+
// OmpBeginDirective and OmpEndDirective are needed for semantic analysis,
4730+
// where some checks are done specifically for either the begin or the end
4731+
// directive. The structure of both is identical, but the diffent types
4732+
// allow to distinguish them in the type-based parse-tree visitor.
4733+
struct OmpBeginDirective : public OmpDirectiveSpecification {
4734+
INHERITED_TUPLE_CLASS_BOILERPLATE(
4735+
OmpBeginDirective, OmpDirectiveSpecification);
4736+
};
4737+
4738+
struct OmpEndDirective : public OmpDirectiveSpecification {
4739+
INHERITED_TUPLE_CLASS_BOILERPLATE(OmpEndDirective, OmpDirectiveSpecification);
4740+
};
4741+
4742+
// Common base class for block-associated constructs.
4743+
struct OmpBlockConstruct {
4744+
TUPLE_CLASS_BOILERPLATE(OmpBlockConstruct);
4745+
const OmpBeginDirective &BeginDir() const {
4746+
return std::get<OmpBeginDirective>(t);
4747+
}
4748+
const std::optional<OmpEndDirective> &EndDir() const {
4749+
return std::get<std::optional<OmpEndDirective>>(t);
4750+
}
4751+
4752+
CharBlock source;
4753+
std::tuple<OmpBeginDirective, Block, std::optional<OmpEndDirective>> t;
4754+
};
4755+
47224756
struct OmpMetadirectiveDirective {
47234757
TUPLE_CLASS_BOILERPLATE(OmpMetadirectiveDirective);
47244758
std::tuple<Verbatim, OmpClauseList> t;
@@ -4824,12 +4858,6 @@ struct OpenMPSectionsConstruct {
48244858
t;
48254859
};
48264860

4827-
// OpenMP directive beginning or ending a block
4828-
struct OmpBlockDirective {
4829-
WRAPPER_CLASS_BOILERPLATE(OmpBlockDirective, llvm::omp::Directive);
4830-
CharBlock source;
4831-
};
4832-
48334861
struct OmpDeclareVariantDirective {
48344862
TUPLE_CLASS_BOILERPLATE(OmpDeclareVariantDirective);
48354863
CharBlock source;
@@ -4954,12 +4982,9 @@ struct OpenMPExecutableAllocate {
49544982
// ALLOCATORS [allocate-clause...]
49554983
// block
49564984
// [END ALLOCATORS]
4957-
struct OpenMPAllocatorsConstruct {
4958-
TUPLE_CLASS_BOILERPLATE(OpenMPAllocatorsConstruct);
4959-
CharBlock source;
4960-
std::tuple<OmpDirectiveSpecification, Block,
4961-
std::optional<OmpDirectiveSpecification>>
4962-
t;
4985+
struct OpenMPAllocatorsConstruct : public OmpBlockConstruct {
4986+
INHERITED_TUPLE_CLASS_BOILERPLATE(
4987+
OpenMPAllocatorsConstruct, OmpBlockConstruct);
49634988
};
49644989

49654990
// 2.17.7 Atomic construct/2.17.8 Flush construct [OpenMP 5.0]
@@ -4973,15 +4998,11 @@ struct OmpMemoryOrderClause {
49734998
CharBlock source;
49744999
};
49755000

4976-
struct OpenMPAtomicConstruct {
5001+
struct OpenMPAtomicConstruct : public OmpBlockConstruct {
49775002
llvm::omp::Clause GetKind() const;
49785003
bool IsCapture() const;
49795004
bool IsCompare() const;
4980-
TUPLE_CLASS_BOILERPLATE(OpenMPAtomicConstruct);
4981-
CharBlock source;
4982-
std::tuple<OmpDirectiveSpecification, Block,
4983-
std::optional<OmpDirectiveSpecification>>
4984-
t;
5005+
INHERITED_TUPLE_CLASS_BOILERPLATE(OpenMPAtomicConstruct, OmpBlockConstruct);
49855006

49865007
// Information filled out during semantic checks to avoid duplication
49875008
// of analyses.
@@ -5045,12 +5066,8 @@ struct OpenMPDepobjConstruct {
50455066
// nocontext-clause |
50465067
// novariants-clause |
50475068
// nowait-clause
5048-
struct OpenMPDispatchConstruct {
5049-
TUPLE_CLASS_BOILERPLATE(OpenMPDispatchConstruct);
5050-
CharBlock source;
5051-
std::tuple<OmpDirectiveSpecification, Block,
5052-
std::optional<OmpDirectiveSpecification>>
5053-
t;
5069+
struct OpenMPDispatchConstruct : public OmpBlockConstruct {
5070+
INHERITED_TUPLE_CLASS_BOILERPLATE(OpenMPDispatchConstruct, OmpBlockConstruct);
50545071
};
50555072

50565073
// [4.5:162-165], [5.0:242-246], [5.1:275-279], [5.2:315-316], [6.0:498-500]
@@ -5105,22 +5122,8 @@ struct OmpEndLoopDirective {
51055122
CharBlock source;
51065123
};
51075124

5108-
struct OmpBeginBlockDirective {
5109-
TUPLE_CLASS_BOILERPLATE(OmpBeginBlockDirective);
5110-
std::tuple<OmpBlockDirective, OmpClauseList> t;
5111-
CharBlock source;
5112-
};
5113-
5114-
struct OmpEndBlockDirective {
5115-
TUPLE_CLASS_BOILERPLATE(OmpEndBlockDirective);
5116-
std::tuple<OmpBlockDirective, OmpClauseList> t;
5117-
CharBlock source;
5118-
};
5119-
5120-
struct OpenMPBlockConstruct {
5121-
TUPLE_CLASS_BOILERPLATE(OpenMPBlockConstruct);
5122-
std::tuple<OmpBeginBlockDirective, Block, std::optional<OmpEndBlockDirective>>
5123-
t;
5125+
struct OpenMPBlockConstruct : public OmpBlockConstruct {
5126+
INHERITED_TUPLE_CLASS_BOILERPLATE(OpenMPBlockConstruct, OmpBlockConstruct);
51245127
};
51255128

51265129
// 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
@@ -706,7 +706,7 @@ void Fortran::lower::omp::lowerAtomic(
706706
};
707707

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

flang/lib/Lower/OpenMP/DataSharingProcessor.cpp

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -395,26 +395,25 @@ getSource(const semantics::SemanticsContext &semaCtx,
395395
const parser::CharBlock *source = nullptr;
396396

397397
auto ompConsVisit = [&](const parser::OpenMPConstruct &x) {
398-
std::visit(
399-
common::visitors{
400-
[&](const parser::OpenMPSectionsConstruct &x) {
401-
source = &std::get<0>(x.t).source;
402-
},
403-
[&](const parser::OpenMPLoopConstruct &x) {
404-
source = &std::get<0>(x.t).source;
405-
},
406-
[&](const parser::OpenMPBlockConstruct &x) {
407-
source = &std::get<0>(x.t).source;
408-
},
409-
[&](const parser::OpenMPCriticalConstruct &x) {
410-
source = &std::get<0>(x.t).source;
411-
},
412-
[&](const parser::OpenMPAtomicConstruct &x) {
413-
source = &std::get<parser::OmpDirectiveSpecification>(x.t).source;
414-
},
415-
[&](const auto &x) { source = &x.source; },
416-
},
417-
x.u);
398+
std::visit(common::visitors{
399+
[&](const parser::OpenMPSectionsConstruct &x) {
400+
source = &std::get<0>(x.t).source;
401+
},
402+
[&](const parser::OpenMPLoopConstruct &x) {
403+
source = &std::get<0>(x.t).source;
404+
},
405+
[&](const parser::OpenMPBlockConstruct &x) {
406+
source = &std::get<0>(x.t).source;
407+
},
408+
[&](const parser::OpenMPCriticalConstruct &x) {
409+
source = &std::get<0>(x.t).source;
410+
},
411+
[&](const parser::OpenMPAtomicConstruct &x) {
412+
source = &x.BeginDir().source;
413+
},
414+
[&](const auto &x) { source = &x.source; },
415+
},
416+
x.u);
418417
};
419418

420419
eval.visit(common::visitors{

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)