diff options
author | Arpith Chacko Jacob <acjacob@us.ibm.com> | 2016-02-02 04:00:47 +0000 |
---|---|---|
committer | Arpith Chacko Jacob <acjacob@us.ibm.com> | 2016-02-02 04:00:47 +0000 |
commit | 3d58f26929fa1c45bfeeba5230a83cf366f9d010 (patch) | |
tree | c58db2955f588efd88321e6e3a758fade619acfe /clang/lib/Sema/SemaOpenMP.cpp | |
parent | a4499e9f73f10b2f29dc2d104ab6b3dc0df16d8c (diff) | |
download | bcm5719-llvm-3d58f26929fa1c45bfeeba5230a83cf366f9d010.tar.gz bcm5719-llvm-3d58f26929fa1c45bfeeba5230a83cf366f9d010.zip |
[OpenMP] Prevent nesting of target constructs within target code execution regions.
Summary:
This patch enhances Sema to check for the following restriction:
OpenMP 4.5 [2.17 Nesting of Regions]
If a target, target update, target data, target enter data, or
target exit data construct is encountered during execution of a
target region, the behavior is unspecified.
Reviewers: ABataev
Differential Revision: http://reviews.llvm.org/D16758
llvm-svn: 259464
Diffstat (limited to 'clang/lib/Sema/SemaOpenMP.cpp')
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 48 |
1 files changed, 35 insertions, 13 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 577772301f0..1300de10b29 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -809,7 +809,7 @@ bool Sema::IsOpenMPCapturedByRef(ValueDecl *D, auto DKind = DSAStack->getDirectiveForScope(RSI->TheScope); auto Ty = D->getType(); - if (isOpenMPTargetDirective(DKind)) { + if (isOpenMPTargetExecutionDirective(DKind)) { // This table summarizes how a given variable should be passed to the device // given its type and the clauses where it appears. This table is based on // the description in OpenMP 4.5 [2.10.4, target Construct] and @@ -907,7 +907,7 @@ bool Sema::IsOpenMPCapturedDecl(ValueDecl *D) { DSAStack->hasDirective( [](OpenMPDirectiveKind K, const DeclarationNameInfo &DNI, SourceLocation Loc) -> bool { - return isOpenMPTargetDirective(K); + return isOpenMPTargetExecutionDirective(K); }, false)) { return true; @@ -944,7 +944,8 @@ bool Sema::isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level) { auto *VD = dyn_cast<VarDecl>(D); return VD && !VD->hasLocalStorage() && - DSAStack->hasExplicitDirective(isOpenMPTargetDirective, Level); + DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, + Level); } void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } @@ -2313,11 +2314,11 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | target | flush | * | // | target | ordered | * | // | target | atomic | * | - // | target | target | * | - // | target | target parallel | * | - // | target | target enter | * | + // | target | target | | + // | target | target parallel | | + // | target | target enter | | // | | data | | - // | target | target exit | * | + // | target | target exit | | // | | data | | // | target | teams | * | // | target | cancellation | | @@ -2347,11 +2348,11 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // | target parallel | flush | * | // | target parallel | ordered | * | // | target parallel | atomic | * | - // | target parallel | target | * | - // | target parallel | target parallel | * | - // | target parallel | target enter | * | + // | target parallel | target | | + // | target parallel | target parallel | | + // | target parallel | target enter | | // | | data | | - // | target parallel | target exit | * | + // | target parallel | target exit | | // | | data | | // | target parallel | teams | | // | target parallel | cancellation | | @@ -2498,6 +2499,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, // +------------------+-----------------+------------------------------------+ if (Stack->getCurScope()) { auto ParentRegion = Stack->getParentDirective(); + auto OffendingRegion = ParentRegion; bool NestingProhibited = false; bool CloseNesting = true; enum { @@ -2658,10 +2660,30 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, NestingProhibited = !isOpenMPTeamsDirective(ParentRegion); Recommend = ShouldBeInTeamsRegion; } + if (!NestingProhibited && + (isOpenMPTargetExecutionDirective(CurrentRegion) || + isOpenMPTargetDataManagementDirective(CurrentRegion))) { + // OpenMP 4.5 [2.17 Nesting of Regions] + // If a target, target update, target data, target enter data, or + // target exit data construct is encountered during execution of a + // target region, the behavior is unspecified. + NestingProhibited = Stack->hasDirective( + [&OffendingRegion](OpenMPDirectiveKind K, + const DeclarationNameInfo &DNI, + SourceLocation Loc) -> bool { + if (isOpenMPTargetExecutionDirective(K)) { + OffendingRegion = K; + return true; + } else + return false; + }, + false /* don't skip top directive */); + CloseNesting = false; + } if (NestingProhibited) { SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) - << CloseNesting << getOpenMPDirectiveName(ParentRegion) << Recommend - << getOpenMPDirectiveName(CurrentRegion); + << CloseNesting << getOpenMPDirectiveName(OffendingRegion) + << Recommend << getOpenMPDirectiveName(CurrentRegion); return true; } } |