r211566 - [OPENMP] Added initial checking of nesting of OpenMP regions.
Alexey Bataev
a.bataev at hotmail.com
Mon Jun 23 21:39:47 PDT 2014
Author: abataev
Date: Mon Jun 23 23:39:47 2014
New Revision: 211566
URL: http://llvm.org/viewvc/llvm-project?rev=211566&view=rev
Log:
[OPENMP] Added initial checking of nesting of OpenMP regions.
Added:
cfe/trunk/test/OpenMP/nesting_of_regions.cpp (with props)
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaOpenMP.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=211566&r1=211565&r2=211566&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Jun 23 23:39:47 2014
@@ -7096,6 +7096,11 @@ def err_omp_reduction_in_task : Error<
"reduction variables may not be accessed in an explicit task">;
def err_omp_reduction_id_not_compatible : Error<
"variable of type %0 is not valid for specified reduction operation">;
+def err_omp_prohibited_region : Error<
+ "region cannot be%select{| closely}0 nested inside '%1' region"
+ "%select{|; perhaps you forget to enclose 'omp %3' directive into a parallel region?}2">;
+def err_omp_prohibited_region_simd : Error<
+ "OpenMP constructs may not be nested inside a simd region">;
} // end of OpenMP category
let CategoryName = "Related Result Type Issue" in {
Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=211566&r1=211565&r2=211566&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Mon Jun 23 23:39:47 2014
@@ -152,6 +152,12 @@ public:
OpenMPDirectiveKind getCurrentDirective() const {
return Stack.back().Directive;
}
+ /// \brief Returns parent directive.
+ OpenMPDirectiveKind getParentDirective() const {
+ if (Stack.size() > 2)
+ return Stack[Stack.size() - 2].Directive;
+ return OMPD_unknown;
+ }
/// \brief Set default data sharing attribute to none.
void setDefaultDSANone() { Stack.back().DefaultAttr = DSA_none; }
@@ -912,6 +918,41 @@ void Sema::ActOnOpenMPRegionStart(OpenMP
}
}
+bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
+ OpenMPDirectiveKind CurrentRegion,
+ SourceLocation StartLoc) {
+ if (Stack->getCurScope()) {
+ auto ParentRegion = Stack->getParentDirective();
+ bool NestingProhibited = false;
+ bool CloseNesting = true;
+ bool ShouldBeInParallelRegion = false;
+ if (isOpenMPSimdDirective(ParentRegion)) {
+ // OpenMP [2.16, Nesting of Regions]
+ // OpenMP constructs may not be nested inside a simd region.
+ SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_simd);
+ return true;
+ }
+ if (isOpenMPWorksharingDirective(CurrentRegion) &&
+ !isOpenMPParallelDirective(CurrentRegion) &&
+ !isOpenMPSimdDirective(CurrentRegion)) {
+ // OpenMP [2.16, Nesting of Regions]
+ // A worksharing region may not be closely nested inside a worksharing,
+ // explicit task, critical, ordered, atomic, or master region.
+ // TODO
+ NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) &&
+ !isOpenMPSimdDirective(ParentRegion);
+ ShouldBeInParallelRegion = true;
+ }
+ if (NestingProhibited) {
+ SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
+ << CloseNesting << getOpenMPDirectiveName(ParentRegion) << true
+ << getOpenMPDirectiveName(CurrentRegion) << ShouldBeInParallelRegion;
+ return true;
+ }
+ }
+ return false;
+}
+
StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
ArrayRef<OMPClause *> Clauses,
Stmt *AStmt,
@@ -920,6 +961,8 @@ StmtResult Sema::ActOnOpenMPExecutableDi
assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
StmtResult Res = StmtError();
+ if (CheckNestingOfRegions(*this, DSAStack, Kind, StartLoc))
+ return StmtError();
// Check default data sharing attributes for referenced variables.
DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
@@ -2246,7 +2289,8 @@ OMPClause *Sema::ActOnOpenMPFirstprivate
// in a firstprivate clause on a worksharing construct if any of the
// worksharing regions arising from the worksharing construct ever bind
// to any of the parallel regions arising from the parallel construct.
- if (isOpenMPWorksharingDirective(CurrDir)) {
+ if (isOpenMPWorksharingDirective(CurrDir) &&
+ !isOpenMPParallelDirective(CurrDir)) {
DVar = DSAStack->getImplicitDSA(VD);
if (DVar.CKind != OMPC_shared) {
Diag(ELoc, diag::err_omp_required_access)
@@ -2357,7 +2401,8 @@ OMPClause *Sema::ActOnOpenMPLastprivateC
// lastprivate clause on a worksharing construct if any of the corresponding
// worksharing regions ever binds to any of the corresponding parallel
// regions.
- if (isOpenMPWorksharingDirective(CurrDir)) {
+ if (isOpenMPWorksharingDirective(CurrDir) &&
+ !isOpenMPParallelDirective(CurrDir)) {
DVar = DSAStack->getImplicitDSA(VD);
if (DVar.CKind != OMPC_shared) {
Diag(ELoc, diag::err_omp_required_access)
@@ -2748,7 +2793,8 @@ OMPClause *Sema::ActOnOpenMPReductionCla
// construct must be shared in the parallel regions to which any of the
// worksharing regions arising from the worksharing construct bind.
OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
- if (isOpenMPWorksharingDirective(CurrDir)) {
+ if (isOpenMPWorksharingDirective(CurrDir) &&
+ !isOpenMPParallelDirective(CurrDir)) {
DVar = DSAStack->getImplicitDSA(VD);
if (DVar.CKind != OMPC_shared) {
Diag(ELoc, diag::err_omp_required_access)
Added: cfe/trunk/test/OpenMP/nesting_of_regions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/nesting_of_regions.cpp?rev=211566&view=auto
==============================================================================
--- cfe/trunk/test/OpenMP/nesting_of_regions.cpp (added)
+++ cfe/trunk/test/OpenMP/nesting_of_regions.cpp Mon Jun 23 23:39:47 2014
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -fsyntax-only -fopenmp=libiomp5 -verify %s
+
+template <class T>
+void foo() {
+#pragma omp parallel
+#pragma omp for
+ for (int i = 0; i < 10; ++i);
+#pragma omp parallel
+#pragma omp simd
+ for (int i = 0; i < 10; ++i);
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i);
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i);
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i);
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+ for (int i = 0; i < 10; ++i);
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp simd
+ for (int i = 0; i < 10; ++i);
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+ for (int i = 0; i < 10; ++i);
+ }
+}
+
+void foo() {
+#pragma omp parallel
+#pragma omp for
+ for (int i = 0; i < 10; ++i);
+#pragma omp parallel
+#pragma omp simd
+ for (int i = 0; i < 10; ++i);
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i);
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp simd // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i);
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ for (int i = 0; i < 10; ++i);
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp for // expected-error {{region cannot be closely nested inside 'for' region; perhaps you forget to enclose 'omp for' directive into a parallel region?}}
+ for (int i = 0; i < 10; ++i);
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp simd
+ for (int i = 0; i < 10; ++i);
+ }
+#pragma omp for
+ for (int i = 0; i < 10; ++i) {
+#pragma omp parallel
+ for (int i = 0; i < 10; ++i);
+ }
+ return foo<int>();
+}
+
Propchange: cfe/trunk/test/OpenMP/nesting_of_regions.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/OpenMP/nesting_of_regions.cpp
------------------------------------------------------------------------------
svn:keywords = Author Date Id Rev URL
Propchange: cfe/trunk/test/OpenMP/nesting_of_regions.cpp
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the cfe-commits
mailing list