Skip to content

Commit a546224

Browse files
committed
[flang][OpenMP] Parase bind clause for loop direcitve.
Adds parsing for the `bind` clause. The clause was already part of the `loop` direcitve's definition but parsing was still missing.
1 parent 6588073 commit a546224

File tree

12 files changed

+111
-8
lines changed

12 files changed

+111
-8
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,8 @@ class ParseTreeDumper {
551551
NODE_ENUM(OmpGrainsizeClause, Prescriptiveness)
552552
NODE(parser, OmpNumTasksClause)
553553
NODE_ENUM(OmpNumTasksClause, Prescriptiveness)
554+
NODE(parser, OmpBindClause)
555+
NODE_ENUM(OmpBindClause, Type)
554556
NODE(parser, OmpProcBindClause)
555557
NODE_ENUM(OmpProcBindClause, Type)
556558
NODE_ENUM(OmpReductionClause, ReductionModifier)

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3714,6 +3714,13 @@ struct OmpNumTasksClause {
37143714
std::tuple<std::optional<Prescriptiveness>, ScalarIntExpr> t;
37153715
};
37163716

3717+
// OMP 5.2 11.7.1 bind-clause ->
3718+
// BIND( PARALLEL | TEAMS | THREAD )
3719+
struct OmpBindClause {
3720+
ENUM_CLASS(Type, Parallel, Teams, Thread)
3721+
WRAPPER_CLASS_BOILERPLATE(OmpBindClause, Type);
3722+
};
3723+
37173724
// OpenMP Clauses
37183725
struct OmpClause {
37193726
UNION_CLASS_BOILERPLATE(OmpClause);

flang/include/flang/Semantics/openmp-directive-sets.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ static const OmpDirectiveSet topTeamsSet{
169169
Directive::OMPD_teams_distribute_parallel_do,
170170
Directive::OMPD_teams_distribute_parallel_do_simd,
171171
Directive::OMPD_teams_distribute_simd,
172+
Directive::OMPD_teams_loop,
172173
};
173174

174175
static const OmpDirectiveSet allTeamsSet{
@@ -365,6 +366,7 @@ static const OmpDirectiveSet nestedTeamsAllowedSet{
365366
Directive::OMPD_distribute_parallel_do,
366367
Directive::OMPD_distribute_parallel_do_simd,
367368
Directive::OMPD_distribute_simd,
369+
Directive::OMPD_loop,
368370
Directive::OMPD_parallel,
369371
Directive::OMPD_parallel_do,
370372
Directive::OMPD_parallel_do_simd,

flang/lib/Parser/openmp-parsers.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,12 @@ TYPE_PARSER(construct<OmpLastprivateClause>(
427427
pure(OmpLastprivateClause::LastprivateModifier::Conditional) / ":"),
428428
Parser<OmpObjectList>{}))
429429

430+
// OMP 5.2 11.7.1 BIND ( PARALLEL | TEAMS | THREAD )
431+
TYPE_PARSER(construct<OmpBindClause>(
432+
"PARALLEL" >> pure(OmpBindClause::Type::Parallel) ||
433+
"TEAMS" >> pure(OmpBindClause::Type::Teams) ||
434+
"THREAD" >> pure(OmpBindClause::Type::Thread)))
435+
430436
TYPE_PARSER(
431437
"ACQUIRE" >> construct<OmpClause>(construct<OmpClause::Acquire>()) ||
432438
"ACQ_REL" >> construct<OmpClause>(construct<OmpClause::AcqRel>()) ||
@@ -441,6 +447,8 @@ TYPE_PARSER(
441447
"ATOMIC_DEFAULT_MEM_ORDER" >>
442448
construct<OmpClause>(construct<OmpClause::AtomicDefaultMemOrder>(
443449
parenthesized(Parser<OmpAtomicDefaultMemOrderClause>{}))) ||
450+
"BIND" >> construct<OmpClause>(construct<OmpClause::Bind>(
451+
parenthesized(Parser<OmpBindClause>{}))) ||
444452
"COLLAPSE" >> construct<OmpClause>(construct<OmpClause::Collapse>(
445453
parenthesized(scalarIntConstantExpr))) ||
446454
"COPYIN" >> construct<OmpClause>(construct<OmpClause::Copyin>(
@@ -615,6 +623,7 @@ TYPE_PARSER(sourced(construct<OmpLoopDirective>(first(
615623
"TEAMS DISTRIBUTE SIMD" >>
616624
pure(llvm::omp::Directive::OMPD_teams_distribute_simd),
617625
"TEAMS DISTRIBUTE" >> pure(llvm::omp::Directive::OMPD_teams_distribute),
626+
"TEAMS LOOP" >> pure(llvm::omp::Directive::OMPD_teams_loop),
618627
"TILE" >> pure(llvm::omp::Directive::OMPD_tile),
619628
"UNROLL" >> pure(llvm::omp::Directive::OMPD_unroll)))))
620629

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

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,13 +363,47 @@ void OmpStructureChecker::HasInvalidDistributeNesting(
363363
"region."_err_en_US);
364364
}
365365
}
366+
void OmpStructureChecker::HasInvalidLoopBinding(
367+
const parser::OpenMPLoopConstruct &x) {
368+
const auto &beginLoopDir{std::get<parser::OmpBeginLoopDirective>(x.t)};
369+
const auto &beginDir{std::get<parser::OmpLoopDirective>(beginLoopDir.t)};
370+
371+
auto teamsBindingChecker = [&](parser::MessageFixedText msg) {
372+
const auto &clauseList{std::get<parser::OmpClauseList>(beginLoopDir.t)};
373+
for (const auto &clause : clauseList.v) {
374+
if (const auto *bindClause{
375+
std::get_if<parser::OmpClause::Bind>(&clause.u)}) {
376+
if (bindClause->v.v != parser::OmpBindClause::Type::Teams) {
377+
context_.Say(beginDir.source, msg);
378+
}
379+
}
380+
}
381+
};
382+
383+
if (llvm::omp::Directive::OMPD_loop == beginDir.v &&
384+
CurrentDirectiveIsNested() &&
385+
OmpDirectiveSet{llvm::omp::OMPD_teams, llvm::omp::OMPD_target_teams}.test(
386+
GetContextParent().directive)) {
387+
teamsBindingChecker(
388+
"`BIND(TEAMS)` must be specified since the `LOOP` region is "
389+
"strictly nested inside a `TEAMS` region."_err_en_US);
390+
}
391+
392+
if (OmpDirectiveSet{
393+
llvm::omp::OMPD_teams_loop, llvm::omp::OMPD_target_teams_loop}
394+
.test(beginDir.v)) {
395+
teamsBindingChecker(
396+
"`BIND(TEAMS)` must be specified since the `LOOP` directive is "
397+
"combined with a `TEAMS` construct."_err_en_US);
398+
}
399+
}
366400

367401
void OmpStructureChecker::HasInvalidTeamsNesting(
368402
const llvm::omp::Directive &dir, const parser::CharBlock &source) {
369403
if (!llvm::omp::nestedTeamsAllowedSet.test(dir)) {
370404
context_.Say(source,
371-
"Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly "
372-
"nested inside `TEAMS` region."_err_en_US);
405+
"Only `DISTRIBUTE`, `PARALLEL`, or `LOOP` regions are allowed to be "
406+
"strictly nested inside `TEAMS` region."_err_en_US);
373407
}
374408
}
375409

@@ -532,6 +566,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
532566
CheckLoopItrVariableIsInt(x);
533567
CheckAssociatedLoopConstraints(x);
534568
HasInvalidDistributeNesting(x);
569+
HasInvalidLoopBinding(x);
535570
if (CurrentDirectiveIsNested() &&
536571
llvm::omp::topTeamsSet.test(GetContextParent().directive)) {
537572
HasInvalidTeamsNesting(beginDir.v, beginDir.source);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ class OmpStructureChecker
148148
void HasInvalidTeamsNesting(
149149
const llvm::omp::Directive &dir, const parser::CharBlock &source);
150150
void HasInvalidDistributeNesting(const parser::OpenMPLoopConstruct &x);
151+
void HasInvalidLoopBinding(const parser::OpenMPLoopConstruct &x);
151152
// specific clause related
152153
bool ScheduleModifierHasType(const parser::OmpScheduleClause &,
153154
const parser::OmpScheduleModifierType::ModType &);

flang/lib/Semantics/resolve-directives.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1655,6 +1655,7 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPLoopConstruct &x) {
16551655
case llvm::omp::Directive::OMPD_teams_distribute_parallel_do:
16561656
case llvm::omp::Directive::OMPD_teams_distribute_parallel_do_simd:
16571657
case llvm::omp::Directive::OMPD_teams_distribute_simd:
1658+
case llvm::omp::Directive::OMPD_teams_loop:
16581659
case llvm::omp::Directive::OMPD_tile:
16591660
case llvm::omp::Directive::OMPD_unroll:
16601661
PushContext(beginDir.source, beginDir.v);

flang/test/Parser/OpenMP/target-loop-unparse.f90

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
! RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=50 %s | \
2+
! RUN: FileCheck --ignore-case %s
13

2-
! RUN: %flang_fc1 -fdebug-unparse -fopenmp %s | FileCheck --ignore-case %s
3-
! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp %s | FileCheck --check-prefix="PARSE-TREE" %s
4+
! RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=50 %s | \
5+
! RUN: FileCheck --check-prefix="PARSE-TREE" %s
46

57
! Check for parsing of loop directive
68

@@ -14,6 +16,16 @@ subroutine test_loop
1416
j = j + 1
1517
end do
1618
!$omp end loop
19+
20+
!PARSE-TREE: OmpBeginLoopDirective
21+
!PARSE-TREE-NEXT: OmpLoopDirective -> llvm::omp::Directive = loop
22+
!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> Bind -> OmpBindClause -> Type = Thread
23+
!CHECK: !$omp loop
24+
!$omp loop bind(thread)
25+
do i=1,10
26+
j = j + 1
27+
end do
28+
!$omp end loop
1729
end subroutine
1830

1931
subroutine test_target_loop
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=50
2+
3+
! OpenMP Version 5.0
4+
! Check OpenMP construct validity for the following directives:
5+
! 11.7 Loop directive
6+
7+
program main
8+
integer :: i, x
9+
10+
!$omp teams
11+
!ERROR: `BIND(TEAMS)` must be specified since the `LOOP` region is strictly nested inside a `TEAMS` region.
12+
!$omp loop bind(thread)
13+
do i = 1, 10
14+
x = x + 1
15+
end do
16+
!$omp end loop
17+
!$omp end teams
18+
19+
!ERROR: `BIND(TEAMS)` must be specified since the `LOOP` directive is combined with a `TEAMS` construct.
20+
!$omp target teams loop bind(thread)
21+
do i = 1, 10
22+
x = x + 1
23+
end do
24+
!$omp end target teams loop
25+
26+
!ERROR: `BIND(TEAMS)` must be specified since the `LOOP` directive is combined with a `TEAMS` construct.
27+
!$omp teams loop bind(thread)
28+
do i = 1, 10
29+
x = x + 1
30+
end do
31+
!$omp end teams loop
32+
33+
end program main

flang/test/Semantics/OpenMP/nested-distribute.f90

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ program main
2121

2222
!$omp teams
2323
do i = 1, N
24-
!ERROR: Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly nested inside `TEAMS` region.
24+
!ERROR: Only `DISTRIBUTE`, `PARALLEL`, or `LOOP` regions are allowed to be strictly nested inside `TEAMS` region.
2525
!$omp task
2626
do k = 1, N
2727
a = 3.14
@@ -50,7 +50,7 @@ program main
5050
!$omp end parallel
5151

5252
!$omp teams
53-
!ERROR: Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly nested inside `TEAMS` region.
53+
!ERROR: Only `DISTRIBUTE`, `PARALLEL`, or `LOOP` regions are allowed to be strictly nested inside `TEAMS` region.
5454
!$omp target
5555
!ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
5656
!$omp distribute
@@ -82,7 +82,7 @@ program main
8282
!$omp end target teams
8383

8484
!$omp teams
85-
!ERROR: Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly nested inside `TEAMS` region.
85+
!ERROR: Only `DISTRIBUTE`, `PARALLEL`, or `LOOP` regions are allowed to be strictly nested inside `TEAMS` region.
8686
!$omp task
8787
do k = 1,10
8888
print *, "hello"

0 commit comments

Comments
 (0)