Skip to content

Commit 50e73ae

Browse files
authoredNov 8, 2024··
[flang][OpenMP] Parse bind clause for loop direcitve. (#113662)
Adds parsing for the `bind` clause. The clause was already part of the `loop` direcitve's definition but parsing was still missing.
1 parent ee1608d commit 50e73ae

File tree

12 files changed

+111
-8
lines changed

12 files changed

+111
-8
lines changed
 

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

+2
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,8 @@ class ParseTreeDumper {
555555
NODE_ENUM(OmpGrainsizeClause, Prescriptiveness)
556556
NODE(parser, OmpNumTasksClause)
557557
NODE_ENUM(OmpNumTasksClause, Prescriptiveness)
558+
NODE(parser, OmpBindClause)
559+
NODE_ENUM(OmpBindClause, Type)
558560
NODE(parser, OmpProcBindClause)
559561
NODE_ENUM(OmpProcBindClause, Type)
560562
NODE_ENUM(OmpReductionClause, ReductionModifier)

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

+7
Original file line numberDiff line numberDiff line change
@@ -3778,6 +3778,13 @@ struct OmpNumTasksClause {
37783778
// update-clause -> UPDATE(task-dependence-type) // since 5.0
37793779
WRAPPER_CLASS(OmpUpdateClause, OmpTaskDependenceType);
37803780

3781+
// OMP 5.2 11.7.1 bind-clause ->
3782+
// BIND( PARALLEL | TEAMS | THREAD )
3783+
struct OmpBindClause {
3784+
ENUM_CLASS(Type, Parallel, Teams, Thread)
3785+
WRAPPER_CLASS_BOILERPLATE(OmpBindClause, Type);
3786+
};
3787+
37813788
// OpenMP Clauses
37823789
struct OmpClause {
37833790
UNION_CLASS_BOILERPLATE(OmpClause);

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

+2
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{
@@ -366,6 +367,7 @@ static const OmpDirectiveSet nestedTeamsAllowedSet{
366367
Directive::OMPD_distribute_parallel_do,
367368
Directive::OMPD_distribute_parallel_do_simd,
368369
Directive::OMPD_distribute_simd,
370+
Directive::OMPD_loop,
369371
Directive::OMPD_parallel,
370372
Directive::OMPD_parallel_do,
371373
Directive::OMPD_parallel_do_simd,

‎flang/lib/Parser/openmp-parsers.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,12 @@ TYPE_PARSER(construct<OmpLastprivateClause>(
495495
pure(OmpLastprivateClause::LastprivateModifier::Conditional) / ":"),
496496
Parser<OmpObjectList>{}))
497497

498+
// OMP 5.2 11.7.1 BIND ( PARALLEL | TEAMS | THREAD )
499+
TYPE_PARSER(construct<OmpBindClause>(
500+
"PARALLEL" >> pure(OmpBindClause::Type::Parallel) ||
501+
"TEAMS" >> pure(OmpBindClause::Type::Teams) ||
502+
"THREAD" >> pure(OmpBindClause::Type::Thread)))
503+
498504
TYPE_PARSER(
499505
"ACQUIRE" >> construct<OmpClause>(construct<OmpClause::Acquire>()) ||
500506
"ACQ_REL" >> construct<OmpClause>(construct<OmpClause::AcqRel>()) ||
@@ -509,6 +515,8 @@ TYPE_PARSER(
509515
"ATOMIC_DEFAULT_MEM_ORDER" >>
510516
construct<OmpClause>(construct<OmpClause::AtomicDefaultMemOrder>(
511517
parenthesized(Parser<OmpAtomicDefaultMemOrderClause>{}))) ||
518+
"BIND" >> construct<OmpClause>(construct<OmpClause::Bind>(
519+
parenthesized(Parser<OmpBindClause>{}))) ||
512520
"COLLAPSE" >> construct<OmpClause>(construct<OmpClause::Collapse>(
513521
parenthesized(scalarIntConstantExpr))) ||
514522
"COPYIN" >> construct<OmpClause>(construct<OmpClause::Copyin>(
@@ -697,6 +705,7 @@ TYPE_PARSER(sourced(construct<OmpLoopDirective>(first(
697705
"TEAMS DISTRIBUTE SIMD" >>
698706
pure(llvm::omp::Directive::OMPD_teams_distribute_simd),
699707
"TEAMS DISTRIBUTE" >> pure(llvm::omp::Directive::OMPD_teams_distribute),
708+
"TEAMS LOOP" >> pure(llvm::omp::Directive::OMPD_teams_loop),
700709
"TILE" >> pure(llvm::omp::Directive::OMPD_tile),
701710
"UNROLL" >> pure(llvm::omp::Directive::OMPD_unroll)))))
702711

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

+37-2
Original file line numberDiff line numberDiff line change
@@ -420,13 +420,47 @@ void OmpStructureChecker::HasInvalidDistributeNesting(
420420
"region."_err_en_US);
421421
}
422422
}
423+
void OmpStructureChecker::HasInvalidLoopBinding(
424+
const parser::OpenMPLoopConstruct &x) {
425+
const auto &beginLoopDir{std::get<parser::OmpBeginLoopDirective>(x.t)};
426+
const auto &beginDir{std::get<parser::OmpLoopDirective>(beginLoopDir.t)};
427+
428+
auto teamsBindingChecker = [&](parser::MessageFixedText msg) {
429+
const auto &clauseList{std::get<parser::OmpClauseList>(beginLoopDir.t)};
430+
for (const auto &clause : clauseList.v) {
431+
if (const auto *bindClause{
432+
std::get_if<parser::OmpClause::Bind>(&clause.u)}) {
433+
if (bindClause->v.v != parser::OmpBindClause::Type::Teams) {
434+
context_.Say(beginDir.source, msg);
435+
}
436+
}
437+
}
438+
};
439+
440+
if (llvm::omp::Directive::OMPD_loop == beginDir.v &&
441+
CurrentDirectiveIsNested() &&
442+
OmpDirectiveSet{llvm::omp::OMPD_teams, llvm::omp::OMPD_target_teams}.test(
443+
GetContextParent().directive)) {
444+
teamsBindingChecker(
445+
"`BIND(TEAMS)` must be specified since the `LOOP` region is "
446+
"strictly nested inside a `TEAMS` region."_err_en_US);
447+
}
448+
449+
if (OmpDirectiveSet{
450+
llvm::omp::OMPD_teams_loop, llvm::omp::OMPD_target_teams_loop}
451+
.test(beginDir.v)) {
452+
teamsBindingChecker(
453+
"`BIND(TEAMS)` must be specified since the `LOOP` directive is "
454+
"combined with a `TEAMS` construct."_err_en_US);
455+
}
456+
}
423457

424458
void OmpStructureChecker::HasInvalidTeamsNesting(
425459
const llvm::omp::Directive &dir, const parser::CharBlock &source) {
426460
if (!llvm::omp::nestedTeamsAllowedSet.test(dir)) {
427461
context_.Say(source,
428-
"Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly "
429-
"nested inside `TEAMS` region."_err_en_US);
462+
"Only `DISTRIBUTE`, `PARALLEL`, or `LOOP` regions are allowed to be "
463+
"strictly nested inside `TEAMS` region."_err_en_US);
430464
}
431465
}
432466

@@ -589,6 +623,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
589623
CheckLoopItrVariableIsInt(x);
590624
CheckAssociatedLoopConstraints(x);
591625
HasInvalidDistributeNesting(x);
626+
HasInvalidLoopBinding(x);
592627
if (CurrentDirectiveIsNested() &&
593628
llvm::omp::topTeamsSet.test(GetContextParent().directive)) {
594629
HasInvalidTeamsNesting(beginDir.v, beginDir.source);

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

+1
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ class OmpStructureChecker
151151
void HasInvalidTeamsNesting(
152152
const llvm::omp::Directive &dir, const parser::CharBlock &source);
153153
void HasInvalidDistributeNesting(const parser::OpenMPLoopConstruct &x);
154+
void HasInvalidLoopBinding(const parser::OpenMPLoopConstruct &x);
154155
// specific clause related
155156
bool ScheduleModifierHasType(const parser::OmpScheduleClause &,
156157
const parser::OmpScheduleModifierType::ModType &);

‎flang/lib/Semantics/resolve-directives.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1671,6 +1671,7 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPLoopConstruct &x) {
16711671
case llvm::omp::Directive::OMPD_teams_distribute_parallel_do:
16721672
case llvm::omp::Directive::OMPD_teams_distribute_parallel_do_simd:
16731673
case llvm::omp::Directive::OMPD_teams_distribute_simd:
1674+
case llvm::omp::Directive::OMPD_teams_loop:
16741675
case llvm::omp::Directive::OMPD_tile:
16751676
case llvm::omp::Directive::OMPD_unroll:
16761677
PushContext(beginDir.source, beginDir.v);

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

+14-2
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
+33
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

+3-3
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"

‎flang/test/Semantics/OpenMP/nested-teams.f90

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ program main
5959

6060
!$omp target
6161
!$omp teams
62-
!ERROR: Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly nested inside `TEAMS` region.
62+
!ERROR: Only `DISTRIBUTE`, `PARALLEL`, or `LOOP` regions are allowed to be strictly nested inside `TEAMS` region.
6363
!ERROR: TEAMS region can only be strictly nested within the implicit parallel region or TARGET region
6464
!$omp teams
6565
a = 3.14

‎llvm/include/llvm/Frontend/OpenMP/OMP.td

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ def OMPC_AtomicDefaultMemOrder : Clause<"atomic_default_mem_order"> {
7373
}
7474
def OMPC_Bind : Clause<"bind"> {
7575
let clangClass = "OMPBindClause";
76+
let flangClass = "OmpBindClause";
7677
}
7778
def OMP_CANCELLATION_CONSTRUCT_Parallel : ClauseVal<"parallel", 1, 1> {}
7879
def OMP_CANCELLATION_CONSTRUCT_Loop : ClauseVal<"loop", 2, 1> {}

0 commit comments

Comments
 (0)
Please sign in to comment.