forked from OSchip/llvm-project
[flang][OpenMP] Add semantic checks for strict nesting inside `teams` construct.
This commit is contained in:
parent
28ab7ff2d7
commit
79f7d3b7b1
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 &);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue