[flang][OpenMP] Add semantic checks for strict nesting inside `teams` construct.

This commit is contained in:
Arnamoy Bhattacharyya 2021-04-29 08:29:58 -04:00 committed by Arnamoy Bhattacharyya
parent 28ab7ff2d7
commit 79f7d3b7b1
5 changed files with 231 additions and 2 deletions

View File

@ -182,7 +182,62 @@ bool OmpStructureChecker::HasInvalidWorksharingNesting(
return false;
}
void OmpStructureChecker::Enter(const parser::OpenMPConstruct &) {
void OmpStructureChecker::HasInvalidDistributeNesting(
const parser::OpenMPLoopConstruct &x) {
bool violation{false};
OmpDirectiveSet distributeSet{llvm::omp::Directive::OMPD_distribute,
llvm::omp::Directive::OMPD_distribute_parallel_do,
llvm::omp::Directive::OMPD_distribute_parallel_do_simd,
llvm::omp::Directive::OMPD_distribute_parallel_for,
llvm::omp::Directive::OMPD_distribute_parallel_for_simd,
llvm::omp::Directive::OMPD_distribute_simd};
const auto &beginLoopDir{std::get<parser::OmpBeginLoopDirective>(x.t)};
const auto &beginDir{std::get<parser::OmpLoopDirective>(beginLoopDir.t)};
if (distributeSet.test(beginDir.v)) {
// `distribute` region has to be nested
if (!CurrentDirectiveIsNested()) {
violation = true;
} else {
// `distribute` region has to be strictly nested inside `teams`
if (!llvm::omp::teamSet.test(GetContextParent().directive)) {
violation = true;
}
}
}
if (violation) {
context_.Say(beginDir.source,
"`DISTRIBUTE` region has to be strictly nested inside `TEAMS` region."_err_en_US);
}
}
void OmpStructureChecker::HasInvalidTeamsNesting(
const llvm::omp::Directive &dir, const parser::CharBlock &source) {
OmpDirectiveSet allowedSet{llvm::omp::Directive::OMPD_parallel,
llvm::omp::Directive::OMPD_parallel_do,
llvm::omp::Directive::OMPD_parallel_do_simd,
llvm::omp::Directive::OMPD_parallel_for,
llvm::omp::Directive::OMPD_parallel_for_simd,
llvm::omp::Directive::OMPD_parallel_master,
llvm::omp::Directive::OMPD_parallel_master_taskloop,
llvm::omp::Directive::OMPD_parallel_master_taskloop_simd,
llvm::omp::Directive::OMPD_parallel_sections,
llvm::omp::Directive::OMPD_parallel_workshare,
llvm::omp::Directive::OMPD_distribute,
llvm::omp::Directive::OMPD_distribute_parallel_do,
llvm::omp::Directive::OMPD_distribute_parallel_do_simd,
llvm::omp::Directive::OMPD_distribute_parallel_for,
llvm::omp::Directive::OMPD_distribute_parallel_for_simd,
llvm::omp::Directive::OMPD_distribute_simd};
if (!allowedSet.test(dir)) {
context_.Say(source,
"Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly nested inside `TEAMS` region."_err_en_US);
}
}
void OmpStructureChecker::Enter(const parser::OpenMPConstruct &x) {
// 2.8.1 TODO: Simd Construct with Ordered Construct Nesting check
}
@ -233,6 +288,11 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
CheckDoWhile(x);
CheckLoopItrVariableIsInt(x);
CheckCycleConstraints(x);
HasInvalidDistributeNesting(x);
if (CurrentDirectiveIsNested() &&
llvm::omp::teamSet.test(GetContextParent().directive)) {
HasInvalidTeamsNesting(beginDir.v, beginDir.source);
}
}
const parser::Name OmpStructureChecker::GetLoopIndex(
const parser::DoConstruct *x) {
@ -366,8 +426,12 @@ void OmpStructureChecker::Enter(const parser::OpenMPBlockConstruct &x) {
HasInvalidWorksharingNesting(
beginDir.source, {llvm::omp::Directive::OMPD_do});
}
if (CurrentDirectiveIsNested())
if (CurrentDirectiveIsNested()) {
CheckIfDoOrderedClause(beginDir);
if (llvm::omp::teamSet.test(GetContextParent().directive)) {
HasInvalidTeamsNesting(beginDir.v, beginDir.source);
}
}
CheckNoBranching(block, beginDir.v, beginDir.source);

View File

@ -71,6 +71,13 @@ static OmpDirectiveSet simdSet{Directive::OMPD_distribute_parallel_do_simd,
Directive::OMPD_taskloop_simd,
Directive::OMPD_teams_distribute_parallel_do_simd,
Directive::OMPD_teams_distribute_simd};
static OmpDirectiveSet teamSet{Directive::OMPD_teams,
Directive::OMPD_teams_distribute,
Directive::OMPD_teams_distribute_parallel_do,
Directive::OMPD_teams_distribute_parallel_do_simd,
Directive::OMPD_teams_distribute_parallel_for,
Directive::OMPD_teams_distribute_parallel_for_simd,
Directive::OMPD_teams_distribute_simd};
static OmpDirectiveSet taskGeneratingSet{
OmpDirectiveSet{Directive::OMPD_task} | taskloopSet};
static OmpDirectiveSet nestedOrderedErrSet{Directive::OMPD_critical,
@ -167,6 +174,9 @@ private:
bool HasInvalidWorksharingNesting(
const parser::CharBlock &, const OmpDirectiveSet &);
bool IsCloselyNestedRegion(const OmpDirectiveSet &set);
void HasInvalidTeamsNesting(
const llvm::omp::Directive &dir, const parser::CharBlock &source);
void HasInvalidDistributeNesting(const parser::OpenMPLoopConstruct &x);
// specific clause related
bool ScheduleModifierHasType(const parser::OmpScheduleClause &,
const parser::OmpScheduleModifierType::ModType &);

View File

@ -7,6 +7,7 @@ program main
real(8) :: a(256), b(256)
N = 256
!ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
!$omp distribute simd
do i = 1, N
a(i) = 3.14

View File

@ -144,6 +144,7 @@ program main
!$omp target exit data map(to:a)
!$omp target
!ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
!$omp distribute
do i = 1, N
a = 3.14
@ -152,6 +153,17 @@ program main
!$omp end target
!$omp target
!$omp teams
!$omp distribute
do i = 1, N
a = 3.14
enddo
!$omp end distribute
!$omp end teams
!$omp end target
!$omp target
!ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
!ERROR: At most one COLLAPSE clause can appear on the DISTRIBUTE directive
!$omp distribute collapse(2) collapse(3)
do i = 1, N
@ -165,6 +177,22 @@ program main
!$omp end target
!$omp target
!$omp teams
!ERROR: At most one COLLAPSE clause can appear on the DISTRIBUTE directive
!$omp distribute collapse(2) collapse(3)
do i = 1, N
do j = 1, N
do k = 1, N
a = 3.14
enddo
enddo
enddo
!$omp end distribute
!$omp end teams
!$omp end target
!$omp target
!ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
!$omp distribute dist_schedule(static, 2)
do i = 1, N
a = 3.14
@ -173,6 +201,17 @@ program main
!$omp end target
!$omp target
!$omp teams
!$omp distribute dist_schedule(static, 2)
do i = 1, N
a = 3.14
enddo
!$omp end distribute
!$omp end teams
!$omp end target
!$omp target
!ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
!ERROR: At most one DIST_SCHEDULE clause can appear on the DISTRIBUTE directive
!$omp distribute dist_schedule(static, 2) dist_schedule(static, 3)
do i = 1, N
@ -181,4 +220,15 @@ program main
!$omp end distribute
!$omp end target
!$omp target
!$omp teams
!ERROR: At most one DIST_SCHEDULE clause can appear on the DISTRIBUTE directive
!$omp distribute dist_schedule(static, 2) dist_schedule(static, 3)
do i = 1, N
a = 3.14
enddo
!$omp end distribute
!$omp end teams
!$omp end target
end program main

View File

@ -0,0 +1,104 @@
! RUN: %S/test_errors.sh %s %t %flang -fopenmp
! Check OpenMP clause validity for the following directives:
! 2.10 Device constructs
program main
real(8) :: arrayA(256), arrayB(256)
integer :: N
arrayA = 1.414
arrayB = 3.14
N = 256
!$omp task
!ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
!$omp distribute
do i = 1, N
a = 3.14
enddo
!$omp end distribute
!$omp end task
!$omp teams
do i = 1, N
!ERROR: Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly nested inside `TEAMS` region.
!$omp task
do k = 1, N
a = 3.14
enddo
!$omp end task
enddo
!$omp end teams
!$omp teams
do i = 1, N
!$omp parallel
do k = 1, N
a = 3.14
enddo
!$omp end parallel
enddo
!$omp end teams
!$omp parallel
!ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
!$omp distribute
do i = 1, N
a = 3.14
enddo
!$omp end distribute
!$omp end parallel
!$omp teams
!ERROR: Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly nested inside `TEAMS` region.
!$omp target
!ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
!$omp distribute
do i = 1, 10
j = j + 1
end do
!$omp end distribute
!$omp end target
!$omp end teams
!$omp teams
!$omp parallel
do k = 1,10
print *, "hello"
end do
!$omp end parallel
!$omp distribute firstprivate(a)
do i = 1, 10
j = j + 1
end do
!$omp end distribute
!$omp end teams
!$omp teams
!ERROR: Only `DISTRIBUTE` or `PARALLEL` regions are allowed to be strictly nested inside `TEAMS` region.
!$omp task
do k = 1,10
print *, "hello"
end do
!$omp end task
!$omp distribute firstprivate(a)
do i = 1, 10
j = j + 1
end do
!$omp end distribute
!$omp end teams
!$omp task
!$omp parallel
do k = 1,10
print *, "hello"
end do
!$omp end parallel
!ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region.
!$omp distribute firstprivate(a)
do i = 1, 10
j = j + 1
end do
!$omp end distribute
!$omp end task
end program main