Skip to content

Commit e9dae87

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 fdc7812 commit e9dae87

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
@@ -552,6 +552,8 @@ class ParseTreeDumper {
552552
NODE_ENUM(OmpGrainsizeClause, Prescriptiveness)
553553
NODE(parser, OmpNumTasksClause)
554554
NODE_ENUM(OmpNumTasksClause, Prescriptiveness)
555+
NODE(parser, OmpBindClause)
556+
NODE_ENUM(OmpBindClause, Type)
555557
NODE(parser, OmpProcBindClause)
556558
NODE_ENUM(OmpProcBindClause, Type)
557559
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
@@ -3730,6 +3730,13 @@ struct OmpNumTasksClause {
37303730
// update-clause -> UPDATE(task-dependence-type) // since 5.0
37313731
WRAPPER_CLASS(OmpUpdateClause, OmpTaskDependenceType);
37323732

3733+
// OMP 5.2 11.7.1 bind-clause ->
3734+
// BIND( PARALLEL | TEAMS | THREAD )
3735+
struct OmpBindClause {
3736+
ENUM_CLASS(Type, Parallel, Teams, Thread)
3737+
WRAPPER_CLASS_BOILERPLATE(OmpBindClause, Type);
3738+
};
3739+
37333740
// OpenMP Clauses
37343741
struct OmpClause {
37353742
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{
@@ -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

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

434+
// OMP 5.2 11.7.1 BIND ( PARALLEL | TEAMS | THREAD )
435+
TYPE_PARSER(construct<OmpBindClause>(
436+
"PARALLEL" >> pure(OmpBindClause::Type::Parallel) ||
437+
"TEAMS" >> pure(OmpBindClause::Type::Teams) ||
438+
"THREAD" >> pure(OmpBindClause::Type::Thread)))
439+
434440
TYPE_PARSER(
435441
"ACQUIRE" >> construct<OmpClause>(construct<OmpClause::Acquire>()) ||
436442
"ACQ_REL" >> construct<OmpClause>(construct<OmpClause::AcqRel>()) ||
@@ -445,6 +451,8 @@ TYPE_PARSER(
445451
"ATOMIC_DEFAULT_MEM_ORDER" >>
446452
construct<OmpClause>(construct<OmpClause::AtomicDefaultMemOrder>(
447453
parenthesized(Parser<OmpAtomicDefaultMemOrderClause>{}))) ||
454+
"BIND" >> construct<OmpClause>(construct<OmpClause::Bind>(
455+
parenthesized(Parser<OmpBindClause>{}))) ||
448456
"COLLAPSE" >> construct<OmpClause>(construct<OmpClause::Collapse>(
449457
parenthesized(scalarIntConstantExpr))) ||
450458
"COPYIN" >> construct<OmpClause>(construct<OmpClause::Copyin>(
@@ -631,6 +639,7 @@ TYPE_PARSER(sourced(construct<OmpLoopDirective>(first(
631639
"TEAMS DISTRIBUTE SIMD" >>
632640
pure(llvm::omp::Directive::OMPD_teams_distribute_simd),
633641
"TEAMS DISTRIBUTE" >> pure(llvm::omp::Directive::OMPD_teams_distribute),
642+
"TEAMS LOOP" >> pure(llvm::omp::Directive::OMPD_teams_loop),
634643
"TILE" >> pure(llvm::omp::Directive::OMPD_tile),
635644
"UNROLL" >> pure(llvm::omp::Directive::OMPD_unroll)))))
636645

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

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

373407
void OmpStructureChecker::HasInvalidTeamsNesting(
374408
const llvm::omp::Directive &dir, const parser::CharBlock &source) {
375409
if (!llvm::omp::nestedTeamsAllowedSet.test(dir)) {
376410
context_.Say(source,
377-
"Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly "
378-
"nested inside `TEAMS` region."_err_en_US);
411+
"Only `DISTRIBUTE`, `PARALLEL`, or `LOOP` regions are allowed to be "
412+
"strictly nested inside `TEAMS` region."_err_en_US);
379413
}
380414
}
381415

@@ -538,6 +572,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
538572
CheckLoopItrVariableIsInt(x);
539573
CheckAssociatedLoopConstraints(x);
540574
HasInvalidDistributeNesting(x);
575+
HasInvalidLoopBinding(x);
541576
if (CurrentDirectiveIsNested() &&
542577
llvm::omp::topTeamsSet.test(GetContextParent().directive)) {
543578
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
@@ -150,6 +150,7 @@ class OmpStructureChecker
150150
void HasInvalidTeamsNesting(
151151
const llvm::omp::Directive &dir, const parser::CharBlock &source);
152152
void HasInvalidDistributeNesting(const parser::OpenMPLoopConstruct &x);
153+
void HasInvalidLoopBinding(const parser::OpenMPLoopConstruct &x);
153154
// specific clause related
154155
bool ScheduleModifierHasType(const parser::OmpScheduleClause &,
155156
const parser::OmpScheduleModifierType::ModType &);

flang/lib/Semantics/resolve-directives.cpp

Lines changed: 1 addition & 0 deletions
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

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"

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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 1 addition & 0 deletions
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)