Skip to content

Commit

Permalink
[clang][OpenMP] Remove compound directives from `checkNestingOfRegion…
Browse files Browse the repository at this point in the history
…s` (#98387)

Express the constraints via constituent directives.
  • Loading branch information
kparzysz authored Jul 15, 2024
1 parent a972a39 commit 861a8ed
Showing 1 changed file with 42 additions and 54 deletions.
96 changes: 42 additions & 54 deletions clang/lib/Sema/SemaOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4797,6 +4797,12 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
ShouldBeInTeamsRegion,
ShouldBeInLoopSimdRegion,
} Recommend = NoRecommend;

SmallVector<OpenMPDirectiveKind, 4> LeafOrComposite;
ArrayRef<OpenMPDirectiveKind> ParentLOC =
getLeafOrCompositeConstructs(ParentRegion, LeafOrComposite);
OpenMPDirectiveKind EnclosingConstruct = ParentLOC.back();

if (SemaRef.LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() &&
CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop &&
CurrentRegion != OMPD_parallel &&
Expand Down Expand Up @@ -4828,7 +4834,7 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
<< (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
return CurrentRegion != OMPD_simd;
}
if (ParentRegion == OMPD_atomic) {
if (EnclosingConstruct == OMPD_atomic) {
// OpenMP [2.16, Nesting of Regions]
// OpenMP constructs may not be nested inside an atomic region.
SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
Expand All @@ -4839,8 +4845,7 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
// Orphaned section directives are prohibited. That is, the section
// directives must appear within the sections construct and must not be
// encountered elsewhere in the sections region.
if (ParentRegion != OMPD_sections &&
ParentRegion != OMPD_parallel_sections) {
if (EnclosingConstruct != OMPD_sections) {
SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
<< (ParentRegion != OMPD_unknown)
<< getOpenMPDirectiveName(ParentRegion);
Expand All @@ -4861,7 +4866,7 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
if (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion == OMPD_loop &&
(BindKind == OMPC_BIND_parallel || BindKind == OMPC_BIND_teams) &&
(isOpenMPWorksharingDirective(ParentRegion) ||
ParentRegion == OMPD_loop)) {
EnclosingConstruct == OMPD_loop)) {
int ErrorMsgNumber = (BindKind == OMPC_BIND_parallel) ? 1 : 4;
SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
<< true << getOpenMPDirectiveName(ParentRegion) << ErrorMsgNumber
Expand All @@ -4881,27 +4886,17 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
// construct-type-clause is not taskgroup must be closely nested inside an
// OpenMP construct that matches the type specified in
// construct-type-clause.
NestingProhibited =
!((CancelRegion == OMPD_parallel &&
(ParentRegion == OMPD_parallel ||
ParentRegion == OMPD_target_parallel)) ||
(CancelRegion == OMPD_for &&
(ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
ParentRegion == OMPD_target_parallel_for ||
ParentRegion == OMPD_distribute_parallel_for ||
ParentRegion == OMPD_teams_distribute_parallel_for ||
ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
(CancelRegion == OMPD_taskgroup &&
(ParentRegion == OMPD_task ||
(SemaRef.getLangOpts().OpenMP >= 50 &&
(ParentRegion == OMPD_taskloop ||
ParentRegion == OMPD_master_taskloop ||
ParentRegion == OMPD_masked_taskloop ||
ParentRegion == OMPD_parallel_masked_taskloop ||
ParentRegion == OMPD_parallel_master_taskloop)))) ||
(CancelRegion == OMPD_sections &&
(ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
ParentRegion == OMPD_parallel_sections)));
ArrayRef<OpenMPDirectiveKind> Leafs = getLeafConstructsOrSelf(ParentRegion);
if (CancelRegion == OMPD_taskgroup) {
NestingProhibited = EnclosingConstruct != OMPD_task &&
(SemaRef.getLangOpts().OpenMP < 50 ||
EnclosingConstruct != OMPD_taskloop);
} else if (CancelRegion == OMPD_sections) {
NestingProhibited = EnclosingConstruct != OMPD_section &&
EnclosingConstruct != OMPD_sections;
} else {
NestingProhibited = CancelRegion != Leafs.back();
}
OrphanSeen = ParentRegion == OMPD_unknown;
} else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
// OpenMP 5.1 [2.22, Nesting of Regions]
Expand Down Expand Up @@ -4942,27 +4937,25 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
// OpenMP 5.1 [2.22, Nesting of Regions]
// A barrier region may not be closely nested inside a worksharing, loop,
// task, taskloop, critical, ordered, atomic, or masked region.
NestingProhibited =
isOpenMPWorksharingDirective(ParentRegion) ||
isOpenMPGenericLoopDirective(ParentRegion) ||
isOpenMPTaskingDirective(ParentRegion) || ParentRegion == OMPD_master ||
ParentRegion == OMPD_masked || ParentRegion == OMPD_parallel_master ||
ParentRegion == OMPD_parallel_masked || ParentRegion == OMPD_critical ||
ParentRegion == OMPD_ordered;
NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
isOpenMPGenericLoopDirective(ParentRegion) ||
isOpenMPTaskingDirective(ParentRegion) ||
llvm::is_contained({OMPD_masked, OMPD_master,
OMPD_critical, OMPD_ordered},
EnclosingConstruct);
} else if (isOpenMPWorksharingDirective(CurrentRegion) &&
!isOpenMPParallelDirective(CurrentRegion) &&
!isOpenMPTeamsDirective(CurrentRegion)) {
// OpenMP 5.1 [2.22, Nesting of Regions]
// A loop region that binds to a parallel region or a worksharing region
// may not be closely nested inside a worksharing, loop, task, taskloop,
// critical, ordered, atomic, or masked region.
NestingProhibited =
isOpenMPWorksharingDirective(ParentRegion) ||
isOpenMPGenericLoopDirective(ParentRegion) ||
isOpenMPTaskingDirective(ParentRegion) || ParentRegion == OMPD_master ||
ParentRegion == OMPD_masked || ParentRegion == OMPD_parallel_master ||
ParentRegion == OMPD_parallel_masked || ParentRegion == OMPD_critical ||
ParentRegion == OMPD_ordered;
NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
isOpenMPGenericLoopDirective(ParentRegion) ||
isOpenMPTaskingDirective(ParentRegion) ||
llvm::is_contained({OMPD_masked, OMPD_master,
OMPD_critical, OMPD_ordered},
EnclosingConstruct);
Recommend = ShouldBeInParallelRegion;
} else if (CurrentRegion == OMPD_ordered) {
// OpenMP [2.16, Nesting of Regions]
Expand All @@ -4973,7 +4966,7 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
// OpenMP [2.8.1,simd Construct, Restrictions]
// An ordered construct with the simd clause is the only OpenMP construct
// that can appear in the simd region.
NestingProhibited = ParentRegion == OMPD_critical ||
NestingProhibited = EnclosingConstruct == OMPD_critical ||
isOpenMPTaskingDirective(ParentRegion) ||
!(isOpenMPSimdDirective(ParentRegion) ||
Stack->isParentOrderedRegion());
Expand All @@ -4983,22 +4976,19 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
// If specified, a teams construct must be contained within a target
// construct.
NestingProhibited =
(SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
(SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
ParentRegion != OMPD_target);
(SemaRef.LangOpts.OpenMP <= 45 && EnclosingConstruct != OMPD_target) ||
(SemaRef.LangOpts.OpenMP >= 50 && EnclosingConstruct != OMPD_unknown &&
EnclosingConstruct != OMPD_target);
OrphanSeen = ParentRegion == OMPD_unknown;
Recommend = ShouldBeInTargetRegion;
} else if (CurrentRegion == OMPD_scan) {
if (SemaRef.LangOpts.OpenMP >= 50) {
SmallVector<OpenMPDirectiveKind, 4> LeafOrComposite;
std::ignore = getLeafOrCompositeConstructs(ParentRegion, LeafOrComposite);
// OpenMP spec 5.0 and 5.1 require scan to be directly enclosed by for,
// simd, or for simd. This has to take into account combined directives.
// In 5.2 this seems to be implied by the fact that the specified
// separated constructs are do, for, and simd.
OpenMPDirectiveKind Enclosing = LeafOrComposite.back();
NestingProhibited = Enclosing != OMPD_for && Enclosing != OMPD_simd &&
Enclosing != OMPD_for_simd;
NestingProhibited = !llvm::is_contained(
{OMPD_for, OMPD_simd, OMPD_for_simd}, EnclosingConstruct);
} else {
NestingProhibited = true;
}
Expand All @@ -5007,7 +4997,7 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
}
if (!NestingProhibited && !isOpenMPTargetExecutionDirective(CurrentRegion) &&
!isOpenMPTargetDataManagementDirective(CurrentRegion) &&
(ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
EnclosingConstruct == OMPD_teams) {
// OpenMP [5.1, 2.22, Nesting of Regions]
// distribute, distribute simd, distribute parallel worksharing-loop,
// distribute parallel worksharing-loop SIMD, loop, parallel regions,
Expand All @@ -5029,17 +5019,15 @@ static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
// If the bind clause is present on the loop construct and binding is
// teams then the corresponding loop region must be strictly nested inside
// a teams region.
NestingProhibited = BindKind == OMPC_BIND_teams &&
ParentRegion != OMPD_teams &&
ParentRegion != OMPD_target_teams;
NestingProhibited =
BindKind == OMPC_BIND_teams && EnclosingConstruct != OMPD_teams;
Recommend = ShouldBeInTeamsRegion;
}
if (!NestingProhibited && isOpenMPNestingDistributeDirective(CurrentRegion)) {
// OpenMP 4.5 [2.17 Nesting of Regions]
// The region associated with the distribute construct must be strictly
// nested inside a teams region
NestingProhibited =
(ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
NestingProhibited = EnclosingConstruct != OMPD_teams;
Recommend = ShouldBeInTeamsRegion;
}
if (!NestingProhibited &&
Expand Down

0 comments on commit 861a8ed

Please sign in to comment.