Skip to content

Commit 64bca90

Browse files
committed
[flang][OpenMP] Use OmpDirectiveSpecification in simple directives
The `OmpDirectiveSpecification` contains directive name, the list of arguments, and the list of clauses. It was introduced to store the directive specification in METADIRECTIVE, and could be reused everywhere a directive representation is needed. In the long term this would unify the handling of common directive properties, as well as creating actual constructs from METADIRECTIVE by linking the contained directive specification with any associated user code.
1 parent 7e9802f commit 64bca90

File tree

15 files changed

+131
-129
lines changed

15 files changed

+131
-129
lines changed

flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,10 +128,17 @@ std::string OpenMPCounterVisitor::getName(const OpenMPConstruct &c) {
128128
Fortran::common::visitors{
129129
[&](const OpenMPStandaloneConstruct &c) -> std::string {
130130
return std::visit(
131-
[&](const auto &c) {
132-
// Get source from the directive or verbatim fields
133-
const CharBlock &source{std::get<0>(c.t).source};
134-
return normalize_construct_name(source.ToString());
131+
Fortran::common::visitors{
132+
[&](const OpenMPSimpleStandaloneConstruct &d) {
133+
const CharBlock &source{
134+
std::get<OmpDirectiveName>(d.v.t).source};
135+
return normalize_construct_name(source.ToString());
136+
},
137+
[&](const auto &c) {
138+
// Get source from the directive or verbatim fields
139+
const CharBlock &source{std::get<0>(c.t).source};
140+
return normalize_construct_name(source.ToString());
141+
},
135142
},
136143
c.u);
137144
},

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,6 @@ class ParseTreeDumper {
663663
NODE_ENUM(OmpOrderingModifier, Value)
664664
NODE(parser, OmpSectionBlocks)
665665
NODE(parser, OmpSectionsDirective)
666-
NODE(parser, OmpSimpleStandaloneDirective)
667666
NODE(parser, OmpToClause)
668667
NODE(OmpToClause, Modifier)
669668
NODE(parser, Only)

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

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4934,15 +4934,10 @@ struct OpenMPFlushConstruct {
49344934
t;
49354935
};
49364936

4937-
struct OmpSimpleStandaloneDirective {
4938-
WRAPPER_CLASS_BOILERPLATE(OmpSimpleStandaloneDirective, llvm::omp::Directive);
4939-
CharBlock source;
4940-
};
4941-
49424937
struct OpenMPSimpleStandaloneConstruct {
4943-
TUPLE_CLASS_BOILERPLATE(OpenMPSimpleStandaloneConstruct);
4938+
WRAPPER_CLASS_BOILERPLATE(
4939+
OpenMPSimpleStandaloneConstruct, OmpDirectiveSpecification);
49444940
CharBlock source;
4945-
std::tuple<OmpSimpleStandaloneDirective, OmpClauseList> t;
49464941
};
49474942

49484943
struct OpenMPStandaloneConstruct {

flang/lib/Lower/OpenMP/OpenMP.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -408,8 +408,7 @@ extractOmpDirective(const parser::OpenMPConstruct &ompConstruct) {
408408
return common::visit(
409409
common::visitors{
410410
[](const parser::OpenMPSimpleStandaloneConstruct &c) {
411-
return std::get<parser::OmpSimpleStandaloneDirective>(c.t)
412-
.v;
411+
return c.v.DirId();
413412
},
414413
[](const parser::OpenMPFlushConstruct &c) {
415414
return llvm::omp::OMPD_flush;
@@ -3286,14 +3285,12 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
32863285
// OpenMPStandaloneConstruct visitors
32873286
//===----------------------------------------------------------------------===//
32883287

3289-
static void genOMP(
3290-
lower::AbstractConverter &converter, lower::SymMap &symTable,
3291-
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval,
3292-
const parser::OpenMPSimpleStandaloneConstruct &simpleStandaloneConstruct) {
3293-
const auto &directive = std::get<parser::OmpSimpleStandaloneDirective>(
3294-
simpleStandaloneConstruct.t);
3295-
List<Clause> clauses = makeClauses(
3296-
std::get<parser::OmpClauseList>(simpleStandaloneConstruct.t), semaCtx);
3288+
static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
3289+
semantics::SemanticsContext &semaCtx,
3290+
lower::pft::Evaluation &eval,
3291+
const parser::OpenMPSimpleStandaloneConstruct &construct) {
3292+
const auto &directive = std::get<parser::OmpDirectiveName>(construct.v.t);
3293+
List<Clause> clauses = makeClauses(construct.v.Clauses(), semaCtx);
32973294
mlir::Location currentLocation = converter.genLocation(directive.source);
32983295

32993296
ConstructQueue queue{

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,29 @@ constexpr auto operator>=(PA checker, PB parser) {
6464
return lookAhead(checker) >> parser;
6565
}
6666

67+
template <typename PA, typename CF> struct PredicatedParser {
68+
using resultType = typename PA::resultType;
69+
70+
constexpr PredicatedParser(PA parser, CF condition)
71+
: parser_(parser), condition_(condition) {}
72+
73+
std::optional<resultType> Parse(ParseState &state) const {
74+
if (auto result{parser_.Parse(state)}; result && condition_(*result)) {
75+
return result;
76+
}
77+
return std::nullopt;
78+
}
79+
80+
private:
81+
const PA parser_;
82+
const CF condition_;
83+
};
84+
85+
template <typename PA, typename CF>
86+
constexpr auto predicated(PA parser, CF condition) {
87+
return PredicatedParser(parser, condition);
88+
}
89+
6790
/// Parse OpenMP directive name (this includes compound directives).
6891
struct OmpDirectiveNameParser {
6992
using resultType = OmpDirectiveName;
@@ -1027,6 +1050,8 @@ TYPE_PARSER(sourced(construct<OmpErrorDirective>(
10271050

10281051
// --- Parsers for directives and constructs --------------------------
10291052

1053+
TYPE_PARSER(sourced(construct<OmpDirectiveName>(OmpDirectiveNameParser{})))
1054+
10301055
OmpDirectiveSpecification static makeFlushFromOldSyntax1(Verbatim &&text,
10311056
std::optional<OmpClauseList> &&clauses,
10321057
std::optional<std::list<OmpArgument>> &&args,
@@ -1198,24 +1223,32 @@ TYPE_PARSER(sourced( //
11981223
verbatim("FLUSH"_tok), maybe(parenthesized(Parser<OmpObjectList>{})),
11991224
Parser<OmpClauseList>{}, pure(/*TrailingClauses=*/true))))
12001225

1201-
// Simple Standalone Directives
1202-
TYPE_PARSER(sourced(construct<OmpSimpleStandaloneDirective>(first(
1203-
"BARRIER" >> pure(llvm::omp::Directive::OMPD_barrier),
1204-
"ORDERED" >> pure(llvm::omp::Directive::OMPD_ordered),
1205-
"SCAN" >> pure(llvm::omp::Directive::OMPD_scan),
1206-
"TARGET ENTER DATA" >> pure(llvm::omp::Directive::OMPD_target_enter_data),
1207-
"TARGET EXIT DATA" >> pure(llvm::omp::Directive::OMPD_target_exit_data),
1208-
"TARGET UPDATE" >> pure(llvm::omp::Directive::OMPD_target_update),
1209-
"TASKWAIT" >> pure(llvm::omp::Directive::OMPD_taskwait),
1210-
"TASKYIELD" >> pure(llvm::omp::Directive::OMPD_taskyield)))))
1226+
static bool IsSimpleStandalone(const OmpDirectiveName &name) {
1227+
switch (name.v) {
1228+
case llvm::omp::Directive::OMPD_barrier:
1229+
case llvm::omp::Directive::OMPD_ordered:
1230+
case llvm::omp::Directive::OMPD_scan:
1231+
case llvm::omp::Directive::OMPD_target_enter_data:
1232+
case llvm::omp::Directive::OMPD_target_exit_data:
1233+
case llvm::omp::Directive::OMPD_target_update:
1234+
case llvm::omp::Directive::OMPD_taskwait:
1235+
case llvm::omp::Directive::OMPD_taskyield:
1236+
return true;
1237+
default:
1238+
return false;
1239+
}
1240+
}
12111241

1212-
TYPE_PARSER(sourced(construct<OpenMPSimpleStandaloneConstruct>(
1213-
Parser<OmpSimpleStandaloneDirective>{}, Parser<OmpClauseList>{})))
1242+
TYPE_PARSER(sourced( //
1243+
construct<OpenMPSimpleStandaloneConstruct>(
1244+
predicated(OmpDirectiveNameParser{}, IsSimpleStandalone) >=
1245+
Parser<OmpDirectiveSpecification>{})))
12141246

12151247
// Standalone Constructs
12161248
TYPE_PARSER(
1217-
sourced(construct<OpenMPStandaloneConstruct>(
1218-
Parser<OpenMPSimpleStandaloneConstruct>{}) ||
1249+
sourced( //
1250+
construct<OpenMPStandaloneConstruct>(
1251+
Parser<OpenMPSimpleStandaloneConstruct>{}) ||
12191252
construct<OpenMPStandaloneConstruct>(Parser<OpenMPFlushConstruct>{}) ||
12201253
// Try CANCELLATION POINT before CANCEL.
12211254
construct<OpenMPStandaloneConstruct>(

flang/lib/Parser/unparse.cpp

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2465,37 +2465,6 @@ class UnparseVisitor {
24652465
}
24662466
}
24672467
void Unparse(const OmpObjectList &x) { Walk(x.v, ","); }
2468-
void Unparse(const OmpSimpleStandaloneDirective &x) {
2469-
switch (x.v) {
2470-
case llvm::omp::Directive::OMPD_barrier:
2471-
Word("BARRIER ");
2472-
break;
2473-
case llvm::omp::Directive::OMPD_scan:
2474-
Word("SCAN ");
2475-
break;
2476-
case llvm::omp::Directive::OMPD_taskwait:
2477-
Word("TASKWAIT ");
2478-
break;
2479-
case llvm::omp::Directive::OMPD_taskyield:
2480-
Word("TASKYIELD ");
2481-
break;
2482-
case llvm::omp::Directive::OMPD_target_enter_data:
2483-
Word("TARGET ENTER DATA ");
2484-
break;
2485-
case llvm::omp::Directive::OMPD_target_exit_data:
2486-
Word("TARGET EXIT DATA ");
2487-
break;
2488-
case llvm::omp::Directive::OMPD_target_update:
2489-
Word("TARGET UPDATE ");
2490-
break;
2491-
case llvm::omp::Directive::OMPD_ordered:
2492-
Word("ORDERED ");
2493-
break;
2494-
default:
2495-
// Nothing to be done
2496-
break;
2497-
}
2498-
}
24992468
void Unparse(const OmpBlockDirective &x) {
25002469
switch (x.v) {
25012470
case llvm::omp::Directive::OMPD_masked:
@@ -2924,8 +2893,7 @@ class UnparseVisitor {
29242893
void Unparse(const OpenMPSimpleStandaloneConstruct &x) {
29252894
BeginOpenMP();
29262895
Word("!$OMP ");
2927-
Walk(std::get<OmpSimpleStandaloneDirective>(x.t));
2928-
Walk(std::get<OmpClauseList>(x.t));
2896+
Walk(x.v);
29292897
Put("\n");
29302898
EndOpenMP();
29312899
}

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

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -878,21 +878,17 @@ void OmpStructureChecker::CheckSIMDNest(const parser::OpenMPConstruct &c) {
878878
}
879879
},
880880
[&](const parser::OpenMPStandaloneConstruct &c) {
881-
if (const auto &simpleConstruct =
882-
std::get_if<parser::OpenMPSimpleStandaloneConstruct>(
883-
&c.u)) {
884-
const auto &dir{std::get<parser::OmpSimpleStandaloneDirective>(
885-
simpleConstruct->t)};
886-
if (dir.v == llvm::omp::Directive::OMPD_ordered) {
887-
const auto &clauses{
888-
std::get<parser::OmpClauseList>(simpleConstruct->t)};
889-
for (const auto &clause : clauses.v) {
890-
if (std::get_if<parser::OmpClause::Simd>(&clause.u)) {
881+
if (auto *ssc{std::get_if<parser::OpenMPSimpleStandaloneConstruct>(
882+
&c.u)}) {
883+
llvm::omp::Directive dirId{ssc->v.DirId()};
884+
if (dirId == llvm::omp::Directive::OMPD_ordered) {
885+
for (const parser::OmpClause &x : ssc->v.Clauses().v) {
886+
if (x.Id() == llvm::omp::Clause::OMPC_simd) {
891887
eligibleSIMD = true;
892888
break;
893889
}
894890
}
895-
} else if (dir.v == llvm::omp::Directive::OMPD_scan) {
891+
} else if (dirId == llvm::omp::Directive::OMPD_scan) {
896892
eligibleSIMD = true;
897893
}
898894
}
@@ -944,15 +940,15 @@ void OmpStructureChecker::CheckTargetNest(const parser::OpenMPConstruct &c) {
944940
common::visit(
945941
common::visitors{
946942
[&](const parser::OpenMPSimpleStandaloneConstruct &c) {
947-
const auto &dir{
948-
std::get<parser::OmpSimpleStandaloneDirective>(c.t)};
949-
if (dir.v == llvm::omp::Directive::OMPD_target_update ||
950-
dir.v ==
951-
llvm::omp::Directive::OMPD_target_enter_data ||
952-
dir.v ==
953-
llvm::omp::Directive::OMPD_target_exit_data) {
943+
switch (llvm::omp::Directive dirId{c.v.DirId()}) {
944+
case llvm::omp::Directive::OMPD_target_update:
945+
case llvm::omp::Directive::OMPD_target_enter_data:
946+
case llvm::omp::Directive::OMPD_target_exit_data:
954947
eligibleTarget = false;
955-
ineligibleTargetDir = dir.v;
948+
ineligibleTargetDir = dirId;
949+
break;
950+
default:
951+
break;
956952
}
957953
},
958954
[&](const auto &c) {},
@@ -1978,7 +1974,7 @@ void OmpStructureChecker::Leave(const parser::OpenMPAllocatorsConstruct &x) {
19781974

19791975
void OmpStructureChecker::CheckScan(
19801976
const parser::OpenMPSimpleStandaloneConstruct &x) {
1981-
if (std::get<parser::OmpClauseList>(x.t).v.size() != 1) {
1977+
if (x.v.Clauses().v.size() != 1) {
19821978
context_.Say(x.source,
19831979
"Exactly one of EXCLUSIVE or INCLUSIVE clause is expected"_err_en_US);
19841980
}
@@ -2183,7 +2179,7 @@ void OmpStructureChecker::CheckDependenceType(
21832179

21842180
void OmpStructureChecker::Enter(
21852181
const parser::OpenMPSimpleStandaloneConstruct &x) {
2186-
const auto &dir{std::get<parser::OmpSimpleStandaloneDirective>(x.t)};
2182+
const auto &dir{std::get<parser::OmpDirectiveName>(x.v.t)};
21872183
PushContextAndClauseSets(dir.source, dir.v);
21882184
switch (dir.v) {
21892185
case llvm::omp::Directive::OMPD_barrier:

flang/lib/Semantics/resolve-directives.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
356356
return true;
357357
}
358358
void Post(const parser::OmpDirectiveSpecification &) { PopContext(); }
359+
359360
bool Pre(const parser::OmpMetadirectiveDirective &x) {
360361
PushContext(x.source, llvm::omp::Directive::OMPD_metadirective);
361362
return true;
@@ -1652,8 +1653,7 @@ void OmpAttributeVisitor::Post(const parser::OpenMPBlockConstruct &x) {
16521653

16531654
bool OmpAttributeVisitor::Pre(
16541655
const parser::OpenMPSimpleStandaloneConstruct &x) {
1655-
const auto &standaloneDir{
1656-
std::get<parser::OmpSimpleStandaloneDirective>(x.t)};
1656+
const auto &standaloneDir{std::get<parser::OmpDirectiveName>(x.v.t)};
16571657
switch (standaloneDir.v) {
16581658
case llvm::omp::Directive::OMPD_barrier:
16591659
case llvm::omp::Directive::OMPD_ordered:

flang/lib/Semantics/resolve-names.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,11 +1440,13 @@ class OmpVisitor : public virtual DeclarationVisitor {
14401440
static bool NeedsScope(const parser::OpenMPBlockConstruct &);
14411441
static bool NeedsScope(const parser::OmpClause &);
14421442

1443-
bool Pre(const parser::OpenMPRequiresConstruct &x) {
1444-
AddOmpSourceRange(x.source);
1443+
bool Pre(const parser::OmpMetadirectiveDirective &) {
1444+
++metaLevel_;
14451445
return true;
14461446
}
1447-
bool Pre(const parser::OmpSimpleStandaloneDirective &x) {
1447+
void Post(const parser::OmpMetadirectiveDirective &) { --metaLevel_; }
1448+
1449+
bool Pre(const parser::OpenMPRequiresConstruct &x) {
14481450
AddOmpSourceRange(x.source);
14491451
return true;
14501452
}
@@ -1656,6 +1658,7 @@ class OmpVisitor : public virtual DeclarationVisitor {
16561658
const parser::OmpClauseList &clauses);
16571659
void ProcessReductionSpecifier(const parser::OmpReductionSpecifier &spec,
16581660
const std::optional<parser::OmpClauseList> &clauses);
1661+
int metaLevel_{0};
16591662
};
16601663

16611664
bool OmpVisitor::NeedsScope(const parser::OpenMPBlockConstruct &x) {
@@ -1801,12 +1804,16 @@ void OmpVisitor::ProcessReductionSpecifier(
18011804
}
18021805

18031806
bool OmpVisitor::Pre(const parser::OmpDirectiveSpecification &x) {
1804-
// OmpDirectiveSpecification is only used in METADIRECTIVE at the moment.
1805-
// Since it contains directives and clauses, some semantic checks may
1806-
// not be applicable.
1807-
// Disable the semantic analysis for it for now to allow the compiler to
1808-
// parse METADIRECTIVE without flagging errors.
18091807
AddOmpSourceRange(x.source);
1808+
if (metaLevel_ == 0) {
1809+
// Not in METADIRECTIVE.
1810+
return true;
1811+
}
1812+
1813+
// If OmpDirectiveSpecification (which contains clauses) is a part of
1814+
// METADIRECTIVE, some semantic checks may not be applicable.
1815+
// Disable the semantic analysis for it in such cases to allow the compiler
1816+
// to parse METADIRECTIVE without flagging errors.
18101817
auto &maybeArgs{std::get<std::optional<std::list<parser::OmpArgument>>>(x.t)};
18111818
auto &maybeClauses{std::get<std::optional<parser::OmpClauseList>>(x.t)};
18121819

flang/test/Parser/OpenMP/doacross-clause.f90

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ subroutine f00(x)
3131
!PARSE-TREE: | OmpClauseList -> OmpClause -> Ordered -> Scalar -> Integer -> Constant -> Expr = '2_4'
3232
!PARSE-TREE: | | LiteralConstant -> IntLiteralConstant = '2'
3333
![...]
34-
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPSimpleStandaloneConstruct
35-
!PARSE-TREE: | OmpSimpleStandaloneDirective -> llvm::omp::Directive = ordered
34+
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPSimpleStandaloneConstruct -> OmpDirectiveSpecification
35+
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = ordered
3636
!PARSE-TREE: | OmpClauseList -> OmpClause -> Doacross -> OmpDoacrossClause -> OmpDoacross -> Source
3737

3838
subroutine f01(x)
@@ -65,8 +65,8 @@ subroutine f01(x)
6565
!PARSE-TREE: | OmpClauseList -> OmpClause -> Ordered -> Scalar -> Integer -> Constant -> Expr = '2_4'
6666
!PARSE-TREE: | | LiteralConstant -> IntLiteralConstant = '2'
6767
![...]
68-
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPSimpleStandaloneConstruct
69-
!PARSE-TREE: | OmpSimpleStandaloneDirective -> llvm::omp::Directive = ordered
68+
!PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPStandaloneConstruct -> OpenMPSimpleStandaloneConstruct -> OmpDirectiveSpecification
69+
!PARSE-TREE: | OmpDirectiveName -> llvm::omp::Directive = ordered
7070
!PARSE-TREE: | OmpClauseList -> OmpClause -> Doacross -> OmpDoacrossClause -> OmpDoacross -> Sink -> OmpIterationVector -> OmpIteration
7171
!PARSE-TREE: | | Name = 'i'
7272
!PARSE-TREE: | | OmpIterationOffset

0 commit comments

Comments
 (0)