18
18
#include "flang/Parser/openmp-utils.h"
19
19
#include "flang/Parser/parse-tree.h"
20
20
#include "llvm/ADT/ArrayRef.h"
21
+ #include "llvm/ADT/Bitset.h"
21
22
#include "llvm/ADT/STLExtras.h"
22
23
#include "llvm/ADT/StringRef.h"
23
24
#include "llvm/ADT/StringSet.h"
24
25
#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>
25
39
26
40
// OpenMP Directives and Clauses
27
41
namespace Fortran::parser {
28
42
using namespace Fortran::parser::omp;
29
43
44
+ using DirectiveSet =
45
+ llvm::Bitset<llvm::NextPowerOf2(llvm::omp::Directive_enumSize)>;
46
+
30
47
// Helper function to print the buffer contents starting at the current point.
31
48
[[maybe_unused]] static std::string ahead(const ParseState &state) {
32
49
return std::string(
@@ -1349,95 +1366,46 @@ TYPE_PARSER(sourced(construct<OpenMPUtilityConstruct>(
1349
1366
TYPE_PARSER(sourced(construct<OmpMetadirectiveDirective>(
1350
1367
verbatim("METADIRECTIVE"_tok), Parser<OmpClauseList>{})))
1351
1368
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
-
1413
1369
static inline constexpr auto IsDirective(llvm::omp::Directive dir) {
1414
1370
return [dir](const OmpDirectiveName &name) -> bool { return dir == name.v; };
1415
1371
}
1416
1372
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
+
1417
1379
struct OmpBeginDirectiveParser {
1418
1380
using resultType = OmpDirectiveSpecification;
1419
1381
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
+ }
1421
1386
1422
1387
std::optional<resultType> Parse(ParseState &state) const {
1423
- auto &&p{predicated(Parser<OmpDirectiveName>{}, IsDirective(dir_ )) >=
1388
+ auto &&p{predicated(Parser<OmpDirectiveName>{}, IsMemberOf(dirs_ )) >=
1424
1389
Parser<OmpDirectiveSpecification>{}};
1425
1390
return p.Parse(state);
1426
1391
}
1427
1392
1428
1393
private:
1429
- llvm::omp::Directive dir_ ;
1394
+ DirectiveSet dirs_ ;
1430
1395
};
1431
1396
1432
1397
struct OmpEndDirectiveParser {
1433
1398
using resultType = OmpDirectiveSpecification;
1434
1399
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
+ }
1436
1404
1437
1405
std::optional<resultType> Parse(ParseState &state) const {
1438
1406
if (startOmpLine.Parse(state)) {
1439
1407
if (auto endToken{verbatim("END"_sptok).Parse(state)}) {
1440
- if (auto &&dirSpec{OmpBeginDirectiveParser(dir_ ).Parse(state)}) {
1408
+ if (auto &&dirSpec{OmpBeginDirectiveParser(dirs_ ).Parse(state)}) {
1441
1409
// Extend the "source" on both the OmpDirectiveName and the
1442
1410
// OmpDirectiveNameSpecification.
1443
1411
CharBlock &nameSource{std::get<OmpDirectiveName>(dirSpec->t).source};
@@ -1451,7 +1419,7 @@ struct OmpEndDirectiveParser {
1451
1419
}
1452
1420
1453
1421
private:
1454
- llvm::omp::Directive dir_ ;
1422
+ DirectiveSet dirs_ ;
1455
1423
};
1456
1424
1457
1425
struct OmpStatementConstructParser {
@@ -1946,11 +1914,56 @@ TYPE_CONTEXT_PARSER("OpenMP construct"_en_US,
1946
1914
construct<OpenMPConstruct>(Parser<OpenMPAssumeConstruct>{}),
1947
1915
construct<OpenMPConstruct>(Parser<OpenMPCriticalConstruct>{}))))
1948
1916
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
+
1949
1964
// 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())))))
1954
1967
1955
1968
TYPE_PARSER(construct<OpenMPLoopConstruct>(
1956
1969
Parser<OmpBeginLoopDirective>{} / endOmpLine))
0 commit comments