1818#include "flang/Parser/openmp-utils.h"
1919#include "flang/Parser/parse-tree.h"
2020#include "llvm/ADT/ArrayRef.h"
21+ #include "llvm/ADT/Bitset.h"
2122#include "llvm/ADT/STLExtras.h"
2223#include "llvm/ADT/StringRef.h"
2324#include "llvm/ADT/StringSet.h"
2425#include "llvm/Frontend/OpenMP/OMP.h"
26+ #include "llvm/Support/MathExtras.h"
27+
28+ #include <algorithm>
29+ #include <cctype>
30+ #include <iterator>
31+ #include <list>
32+ #include <optional>
33+ #include <string>
34+ #include <tuple>
35+ #include <type_traits>
36+ #include <utility>
37+ #include <variant>
38+ #include <vector>
2539
2640// OpenMP Directives and Clauses
2741namespace Fortran::parser {
2842using namespace Fortran::parser::omp;
2943
44+ using DirectiveSet =
45+ llvm::Bitset<llvm::NextPowerOf2(llvm::omp::Directive_enumSize)>;
46+
3047// Helper function to print the buffer contents starting at the current point.
3148[[maybe_unused]] static std::string ahead(const ParseState &state) {
3249 return std::string(
@@ -1349,95 +1366,46 @@ TYPE_PARSER(sourced(construct<OpenMPUtilityConstruct>(
13491366TYPE_PARSER(sourced(construct<OmpMetadirectiveDirective>(
13501367 verbatim("METADIRECTIVE"_tok), Parser<OmpClauseList>{})))
13511368
1352- // Omp directives enclosing do loop
1353- TYPE_PARSER(sourced(construct<OmpLoopDirective>(first(
1354- "DISTRIBUTE PARALLEL DO SIMD" >>
1355- pure(llvm::omp::Directive::OMPD_distribute_parallel_do_simd),
1356- "DISTRIBUTE PARALLEL DO" >>
1357- pure(llvm::omp::Directive::OMPD_distribute_parallel_do),
1358- "DISTRIBUTE SIMD" >> pure(llvm::omp::Directive::OMPD_distribute_simd),
1359- "DISTRIBUTE" >> pure(llvm::omp::Directive::OMPD_distribute),
1360- "DO SIMD" >> pure(llvm::omp::Directive::OMPD_do_simd),
1361- "DO" >> pure(llvm::omp::Directive::OMPD_do),
1362- "LOOP" >> pure(llvm::omp::Directive::OMPD_loop),
1363- "MASKED TASKLOOP SIMD" >>
1364- pure(llvm::omp::Directive::OMPD_masked_taskloop_simd),
1365- "MASKED TASKLOOP" >> pure(llvm::omp::Directive::OMPD_masked_taskloop),
1366- "MASTER TASKLOOP SIMD" >>
1367- pure(llvm::omp::Directive::OMPD_master_taskloop_simd),
1368- "MASTER TASKLOOP" >> pure(llvm::omp::Directive::OMPD_master_taskloop),
1369- "PARALLEL DO SIMD" >> pure(llvm::omp::Directive::OMPD_parallel_do_simd),
1370- "PARALLEL DO" >> pure(llvm::omp::Directive::OMPD_parallel_do),
1371- "PARALLEL MASKED TASKLOOP SIMD" >>
1372- pure(llvm::omp::Directive::OMPD_parallel_masked_taskloop_simd),
1373- "PARALLEL MASKED TASKLOOP" >>
1374- pure(llvm::omp::Directive::OMPD_parallel_masked_taskloop),
1375- "PARALLEL MASTER TASKLOOP SIMD" >>
1376- pure(llvm::omp::Directive::OMPD_parallel_master_taskloop_simd),
1377- "PARALLEL MASTER TASKLOOP" >>
1378- pure(llvm::omp::Directive::OMPD_parallel_master_taskloop),
1379- "SIMD" >> pure(llvm::omp::Directive::OMPD_simd),
1380- "TARGET LOOP" >> pure(llvm::omp::Directive::OMPD_target_loop),
1381- "TARGET PARALLEL DO SIMD" >>
1382- pure(llvm::omp::Directive::OMPD_target_parallel_do_simd),
1383- "TARGET PARALLEL DO" >> pure(llvm::omp::Directive::OMPD_target_parallel_do),
1384- "TARGET PARALLEL LOOP" >>
1385- pure(llvm::omp::Directive::OMPD_target_parallel_loop),
1386- "TARGET SIMD" >> pure(llvm::omp::Directive::OMPD_target_simd),
1387- "TARGET TEAMS DISTRIBUTE PARALLEL DO SIMD" >>
1388- pure(llvm::omp::Directive::
1389- OMPD_target_teams_distribute_parallel_do_simd),
1390- "TARGET TEAMS DISTRIBUTE PARALLEL DO" >>
1391- pure(llvm::omp::Directive::OMPD_target_teams_distribute_parallel_do),
1392- "TARGET TEAMS DISTRIBUTE SIMD" >>
1393- pure(llvm::omp::Directive::OMPD_target_teams_distribute_simd),
1394- "TARGET TEAMS DISTRIBUTE" >>
1395- pure(llvm::omp::Directive::OMPD_target_teams_distribute),
1396- "TARGET TEAMS LOOP" >> pure(llvm::omp::Directive::OMPD_target_teams_loop),
1397- "TASKLOOP SIMD" >> pure(llvm::omp::Directive::OMPD_taskloop_simd),
1398- "TASKLOOP" >> pure(llvm::omp::Directive::OMPD_taskloop),
1399- "TEAMS DISTRIBUTE PARALLEL DO SIMD" >>
1400- pure(llvm::omp::Directive::OMPD_teams_distribute_parallel_do_simd),
1401- "TEAMS DISTRIBUTE PARALLEL DO" >>
1402- pure(llvm::omp::Directive::OMPD_teams_distribute_parallel_do),
1403- "TEAMS DISTRIBUTE SIMD" >>
1404- pure(llvm::omp::Directive::OMPD_teams_distribute_simd),
1405- "TEAMS DISTRIBUTE" >> pure(llvm::omp::Directive::OMPD_teams_distribute),
1406- "TEAMS LOOP" >> pure(llvm::omp::Directive::OMPD_teams_loop),
1407- "TILE" >> pure(llvm::omp::Directive::OMPD_tile),
1408- "UNROLL" >> pure(llvm::omp::Directive::OMPD_unroll)))))
1409-
1410- TYPE_PARSER(sourced(construct<OmpBeginLoopDirective>(
1411- sourced(Parser<OmpLoopDirective>{}), Parser<OmpClauseList>{})))
1412-
14131369static inline constexpr auto IsDirective(llvm::omp::Directive dir) {
14141370 return [dir](const OmpDirectiveName &name) -> bool { return dir == name.v; };
14151371}
14161372
1373+ static inline constexpr auto IsMemberOf(const DirectiveSet &dirs) {
1374+ return [&dirs](const OmpDirectiveName &name) -> bool {
1375+ return dirs.test(llvm::to_underlying(name.v));
1376+ };
1377+ }
1378+
14171379struct OmpBeginDirectiveParser {
14181380 using resultType = OmpDirectiveSpecification;
14191381
1420- constexpr OmpBeginDirectiveParser(llvm::omp::Directive dir) : dir_(dir) {}
1382+ constexpr OmpBeginDirectiveParser(DirectiveSet dirs) : dirs_(dirs) {}
1383+ constexpr OmpBeginDirectiveParser(llvm::omp::Directive dir) {
1384+ dirs_.set(llvm::to_underlying(dir));
1385+ }
14211386
14221387 std::optional<resultType> Parse(ParseState &state) const {
1423- auto &&p{predicated(Parser<OmpDirectiveName>{}, IsDirective(dir_ )) >=
1388+ auto &&p{predicated(Parser<OmpDirectiveName>{}, IsMemberOf(dirs_ )) >=
14241389 Parser<OmpDirectiveSpecification>{}};
14251390 return p.Parse(state);
14261391 }
14271392
14281393private:
1429- llvm::omp::Directive dir_ ;
1394+ DirectiveSet dirs_ ;
14301395};
14311396
14321397struct OmpEndDirectiveParser {
14331398 using resultType = OmpDirectiveSpecification;
14341399
1435- constexpr OmpEndDirectiveParser(llvm::omp::Directive dir) : dir_(dir) {}
1400+ constexpr OmpEndDirectiveParser(DirectiveSet dirs) : dirs_(dirs) {}
1401+ constexpr OmpEndDirectiveParser(llvm::omp::Directive dir) {
1402+ dirs_.set(llvm::to_underlying(dir));
1403+ }
14361404
14371405 std::optional<resultType> Parse(ParseState &state) const {
14381406 if (startOmpLine.Parse(state)) {
14391407 if (auto endToken{verbatim("END"_sptok).Parse(state)}) {
1440- if (auto &&dirSpec{OmpBeginDirectiveParser(dir_ ).Parse(state)}) {
1408+ if (auto &&dirSpec{OmpBeginDirectiveParser(dirs_ ).Parse(state)}) {
14411409 // Extend the "source" on both the OmpDirectiveName and the
14421410 // OmpDirectiveNameSpecification.
14431411 CharBlock &nameSource{std::get<OmpDirectiveName>(dirSpec->t).source};
@@ -1451,7 +1419,7 @@ struct OmpEndDirectiveParser {
14511419 }
14521420
14531421private:
1454- llvm::omp::Directive dir_ ;
1422+ DirectiveSet dirs_ ;
14551423};
14561424
14571425struct OmpStatementConstructParser {
@@ -1946,11 +1914,56 @@ TYPE_CONTEXT_PARSER("OpenMP construct"_en_US,
19461914 construct<OpenMPConstruct>(Parser<OpenMPAssumeConstruct>{}),
19471915 construct<OpenMPConstruct>(Parser<OpenMPCriticalConstruct>{}))))
19481916
1917+ static constexpr DirectiveSet GetLoopDirectives() {
1918+ using Directive = llvm::omp::Directive;
1919+ constexpr DirectiveSet loopDirectives{
1920+ unsigned(Directive::OMPD_distribute),
1921+ unsigned(Directive::OMPD_distribute_parallel_do),
1922+ unsigned(Directive::OMPD_distribute_parallel_do_simd),
1923+ unsigned(Directive::OMPD_distribute_simd),
1924+ unsigned(Directive::OMPD_do),
1925+ unsigned(Directive::OMPD_do_simd),
1926+ unsigned(Directive::OMPD_loop),
1927+ unsigned(Directive::OMPD_masked_taskloop),
1928+ unsigned(Directive::OMPD_masked_taskloop_simd),
1929+ unsigned(Directive::OMPD_master_taskloop),
1930+ unsigned(Directive::OMPD_master_taskloop_simd),
1931+ unsigned(Directive::OMPD_parallel_do),
1932+ unsigned(Directive::OMPD_parallel_do_simd),
1933+ unsigned(Directive::OMPD_parallel_masked_taskloop),
1934+ unsigned(Directive::OMPD_parallel_masked_taskloop_simd),
1935+ unsigned(Directive::OMPD_parallel_master_taskloop),
1936+ unsigned(Directive::OMPD_parallel_master_taskloop_simd),
1937+ unsigned(Directive::OMPD_simd),
1938+ unsigned(Directive::OMPD_target_loop),
1939+ unsigned(Directive::OMPD_target_parallel_do),
1940+ unsigned(Directive::OMPD_target_parallel_do_simd),
1941+ unsigned(Directive::OMPD_target_parallel_loop),
1942+ unsigned(Directive::OMPD_target_simd),
1943+ unsigned(Directive::OMPD_target_teams_distribute),
1944+ unsigned(Directive::OMPD_target_teams_distribute_parallel_do),
1945+ unsigned(Directive::OMPD_target_teams_distribute_parallel_do_simd),
1946+ unsigned(Directive::OMPD_target_teams_distribute_simd),
1947+ unsigned(Directive::OMPD_target_teams_loop),
1948+ unsigned(Directive::OMPD_taskloop),
1949+ unsigned(Directive::OMPD_taskloop_simd),
1950+ unsigned(Directive::OMPD_teams_distribute),
1951+ unsigned(Directive::OMPD_teams_distribute_parallel_do),
1952+ unsigned(Directive::OMPD_teams_distribute_parallel_do_simd),
1953+ unsigned(Directive::OMPD_teams_distribute_simd),
1954+ unsigned(Directive::OMPD_teams_loop),
1955+ unsigned(Directive::OMPD_tile),
1956+ unsigned(Directive::OMPD_unroll),
1957+ };
1958+ return loopDirectives;
1959+ }
1960+
1961+ TYPE_PARSER(sourced(construct<OmpBeginLoopDirective>(
1962+ sourced(OmpBeginDirectiveParser(GetLoopDirectives())))))
1963+
19491964// END OMP Loop directives
1950- TYPE_PARSER(
1951- startOmpLine >> sourced(construct<OmpEndLoopDirective>(
1952- sourced("END"_tok >> Parser<OmpLoopDirective>{}),
1953- Parser<OmpClauseList>{})))
1965+ TYPE_PARSER(sourced(construct<OmpEndLoopDirective>(
1966+ sourced(OmpEndDirectiveParser(GetLoopDirectives())))))
19541967
19551968TYPE_PARSER(construct<OpenMPLoopConstruct>(
19561969 Parser<OmpBeginLoopDirective>{} / endOmpLine))
0 commit comments