r350734 - Incorrect implicit data-sharing for nested tasks

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 9 07:58:05 PST 2019


Author: abataev
Date: Wed Jan  9 07:58:05 2019
New Revision: 350734

URL: http://llvm.org/viewvc/llvm-project?rev=350734&view=rev
Log:
Incorrect implicit data-sharing for nested tasks

Summary:
There is a minor issue in how the implicit data-sharings for nested tasks are computed.

For the following example:
```
int x;
#pragma omp task shared(x)
#pragma omp task
x++;
```
We compute an implicit data-sharing of shared for `x` in the second task although I think that it should be firstprivate. Below you can find the part of the OpenMP spec that covers this example:
- // In a task generating construct, if no default clause is present, a variable for which the data-sharing attribute is not determined by the rules above and that in the enclosing context is determined to be shared by all implicit tasks bound to the current team is shared.//
- //In a task generating construct, if no default clause is present, a variable for which the data-sharing attribute is not determined by the rules above is firstprivate.//

Since each implicit-task has its own copy of `x`, we shouldn't apply the first rule.

Reviewers: ABataev

Reviewed By: ABataev

Subscribers: cfe-commits, rogfer01

Tags: #openmp

Differential Revision: https://reviews.llvm.org/D56430

Modified:
    cfe/trunk/lib/Sema/SemaOpenMP.cpp
    cfe/trunk/test/OpenMP/task_messages.cpp

Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=350734&r1=350733&r2=350734&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Wed Jan  9 07:58:05 2019
@@ -676,9 +676,13 @@ public:
   }
 
 };
-bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) {
-  return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) ||
-         isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown;
+
+bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
+  return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
+}
+
+bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
+  return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || DKind == OMPD_unknown;
 }
 
 } // namespace
@@ -819,7 +823,7 @@ DSAStackTy::DSAVarData DSAStackTy::getDS
           DVar.CKind = OMPC_firstprivate;
           return DVar;
         }
-      } while (I != E && !isParallelOrTaskRegion(I->Directive));
+      } while (I != E && !isImplicitTaskingRegion(I->Directive));
       DVar.CKind =
           (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
       return DVar;
@@ -1066,7 +1070,7 @@ bool DSAStackTy::isOpenMPLocal(VarDecl *
   if (!isStackEmpty()) {
     iterator I = Iter, E = Stack.back().first.rend();
     Scope *TopScope = nullptr;
-    while (I != E && !isParallelOrTaskRegion(I->Directive) &&
+    while (I != E && !isImplicitOrExplicitTaskingRegion(I->Directive) &&
            !isOpenMPTargetExecutionDirective(I->Directive))
       ++I;
     if (I == E)
@@ -1292,7 +1296,7 @@ DSAStackTy::hasDSA(ValueDecl *D,
   if (FromParent && I != EndI)
     std::advance(I, 1);
   for (; I != EndI; std::advance(I, 1)) {
-    if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive))
+    if (!DPred(I->Directive) && !isImplicitOrExplicitTaskingRegion(I->Directive))
       continue;
     iterator NewI = I;
     DSAVarData DVar = getDSA(NewI, D);
@@ -1636,7 +1640,7 @@ VarDecl *Sema::isOpenMPCapturedDecl(Valu
     auto &&Info = DSAStack->isLoopControlVariable(D);
     if (Info.first ||
         (VD && VD->hasLocalStorage() &&
-         isParallelOrTaskRegion(DSAStack->getCurrentDirective())) ||
+         isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
         (VD && DSAStack->isForceVarCapturing()))
       return VD ? VD : Info.second;
     DSAStackTy::DSAVarData DVarPrivate =
@@ -2244,7 +2248,7 @@ public:
       // attribute, must have its data-sharing attribute explicitly determined
       // by being listed in a data-sharing attribute clause.
       if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
-          isParallelOrTaskRegion(DKind) &&
+          isImplicitOrExplicitTaskingRegion(DKind) &&
           VarsWithInheritedDSA.count(VD) == 0) {
         VarsWithInheritedDSA[VD] = E;
         return;

Modified: cfe/trunk/test/OpenMP/task_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/task_messages.cpp?rev=350734&r1=350733&r2=350734&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/task_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/task_messages.cpp Wed Jan  9 07:58:05 2019
@@ -8,7 +8,7 @@ void foo() {
 #pragma omp task // expected-error {{unexpected OpenMP directive '#pragma omp task'}}
 
 class S {
-  S(const S &s) { a = s.a + 12; } // expected-note 14 {{implicitly declared private here}}
+  S(const S &s) { a = s.a + 12; } // expected-note 16 {{implicitly declared private here}}
   int a;
 
 public:
@@ -51,6 +51,15 @@ int foo() {
   ++a; // expected-error {{calling a private constructor of class 'S'}}
 #pragma omp task default(shared)
 #pragma omp task
+  // expected-error at +1 {{calling a private constructor of class 'S'}}
+  ++a;
+#pragma omp parallel shared(a)
+#pragma omp task
+#pragma omp task
+  ++a;
+#pragma omp parallel shared(a)
+#pragma omp task default(shared)
+#pragma omp task
   ++a;
 #pragma omp task
 #pragma omp parallel
@@ -205,6 +214,15 @@ L2:
   ++sa; // expected-error {{calling a private constructor of class 'S'}}
 #pragma omp task default(shared)
 #pragma omp task
+  // expected-error at +1 {{calling a private constructor of class 'S'}}
+  ++sa;
+#pragma omp parallel shared(sa)
+#pragma omp task
+#pragma omp task
+  ++sa;
+#pragma omp parallel shared(sa)
+#pragma omp task default(shared)
+#pragma omp task
   ++sa;
 #pragma omp task
 #pragma omp parallel




More information about the cfe-commits mailing list