r261412 - [OPENMP 4.5] Initial support for data members in 'lastprivate' clause.

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 19 20:09:36 PST 2016


Author: abataev
Date: Fri Feb 19 22:09:36 2016
New Revision: 261412

URL: http://llvm.org/viewvc/llvm-project?rev=261412&view=rev
Log:
[OPENMP 4.5] Initial support for data members in 'lastprivate' clause.

OpenMP 4.5 allows to privatize non-static data members of current class
in non-static member functions. Patch adds initial support for data
members.

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

Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=261412&r1=261411&r2=261412&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Fri Feb 19 22:09:36 2016
@@ -990,17 +990,18 @@ void Sema::EndOpenMPDSABlock(Stmt *CurDi
             PrivateCopies.push_back(nullptr);
             continue;
           }
-          DE = DE->IgnoreParens();
           VarDecl *VD = nullptr;
           FieldDecl *FD = nullptr;
           ValueDecl *D;
-          if (auto *DRE = dyn_cast<DeclRefExpr>(DE)) {
+          auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
+          if (auto *OCE = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) {
+            FD = cast<FieldDecl>(
+                cast<MemberExpr>(OCE->getInit()->IgnoreImpCasts())
+                    ->getMemberDecl());
+            D = FD;
+          } else {
             VD = cast<VarDecl>(DRE->getDecl());
             D = VD;
-          } else {
-            assert(isa<MemberExpr>(DE));
-            FD = cast<FieldDecl>(cast<MemberExpr>(DE)->getMemberDecl());
-            D = FD;
           }
           QualType Type = D->getType().getNonReferenceType();
           auto DVar = DSAStack->getTopDSA(D, false);
@@ -7514,47 +7515,28 @@ OMPClause *Sema::ActOnOpenMPLastprivateC
   SmallVector<Expr *, 8> AssignmentOps;
   for (auto &RefExpr : VarList) {
     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
-    if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
+    auto Res = getPrivateItem(*this, RefExpr);
+    if (Res.second) {
       // It will be analyzed later.
       Vars.push_back(RefExpr);
       SrcExprs.push_back(nullptr);
       DstExprs.push_back(nullptr);
       AssignmentOps.push_back(nullptr);
-      continue;
     }
-
-    SourceLocation ELoc = RefExpr->getExprLoc();
-    // OpenMP [2.1, C/C++]
-    //  A list item is a variable name.
-    // OpenMP  [2.14.3.5, Restrictions, p.1]
-    //  A variable that is part of another variable (as an array or structure
-    //  element) cannot appear in a lastprivate clause.
-    DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
-    if (!DE || !isa<VarDecl>(DE->getDecl())) {
-      Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
-          << 0 << RefExpr->getSourceRange();
+    ValueDecl *D = Res.first;
+    if (!D)
       continue;
-    }
-    Decl *D = DE->getDecl();
-    VarDecl *VD = cast<VarDecl>(D);
 
-    QualType Type = VD->getType();
-    if (Type->isDependentType() || Type->isInstantiationDependentType()) {
-      // It will be analyzed later.
-      Vars.push_back(DE);
-      SrcExprs.push_back(nullptr);
-      DstExprs.push_back(nullptr);
-      AssignmentOps.push_back(nullptr);
-      continue;
-    }
+    SourceLocation ELoc = RefExpr->getExprLoc();
+    QualType Type = D->getType();
+    auto *VD = dyn_cast<VarDecl>(D);
 
     // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
     //  A variable that appears in a lastprivate clause must not have an
     //  incomplete type or a reference type.
     if (RequireCompleteType(ELoc, Type,
-                            diag::err_omp_lastprivate_incomplete_type)) {
+                            diag::err_omp_lastprivate_incomplete_type))
       continue;
-    }
     Type = Type.getNonReferenceType();
 
     // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
@@ -7562,14 +7544,14 @@ OMPClause *Sema::ActOnOpenMPLastprivateC
     //  Variables with the predetermined data-sharing attributes may not be
     //  listed in data-sharing attributes clauses, except for the cases
     //  listed below.
-    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
+    DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
         DVar.CKind != OMPC_firstprivate &&
         (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
       Diag(ELoc, diag::err_omp_wrong_dsa)
           << getOpenMPClauseName(DVar.CKind)
           << getOpenMPClauseName(OMPC_lastprivate);
-      ReportOriginalDSA(*this, DSAStack, VD, DVar);
+      ReportOriginalDSA(*this, DSAStack, D, DVar);
       continue;
     }
 
@@ -7583,15 +7565,28 @@ OMPClause *Sema::ActOnOpenMPLastprivateC
     DSAStackTy::DSAVarData TopDVar = DVar;
     if (isOpenMPWorksharingDirective(CurrDir) &&
         !isOpenMPParallelDirective(CurrDir)) {
-      DVar = DSAStack->getImplicitDSA(VD, true);
+      DVar = DSAStack->getImplicitDSA(D, true);
       if (DVar.CKind != OMPC_shared) {
         Diag(ELoc, diag::err_omp_required_access)
             << getOpenMPClauseName(OMPC_lastprivate)
             << getOpenMPClauseName(OMPC_shared);
-        ReportOriginalDSA(*this, DSAStack, VD, DVar);
+        ReportOriginalDSA(*this, DSAStack, D, DVar);
         continue;
       }
     }
+
+    // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
+    // A list item may appear in a firstprivate or lastprivate clause but not
+    // both.
+    if (CurrDir == OMPD_distribute) {
+      DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
+      if (DVar.CKind == OMPC_firstprivate) {
+        Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute);
+        ReportOriginalDSA(*this, DSAStack, D, DVar);
+        continue;
+      }
+    }
+
     // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
     //  A variable of class type (or array thereof) that appears in a
     //  lastprivate clause requires an accessible, unambiguous default
@@ -7601,42 +7596,32 @@ OMPClause *Sema::ActOnOpenMPLastprivateC
     //  lastprivate clause requires an accessible, unambiguous copy assignment
     //  operator for the class type.
     Type = Context.getBaseElementType(Type).getNonReferenceType();
-    auto *SrcVD = buildVarDecl(*this, DE->getLocStart(),
+    auto *SrcVD = buildVarDecl(*this, RefExpr->getLocStart(),
                                Type.getUnqualifiedType(), ".lastprivate.src",
-                               VD->hasAttrs() ? &VD->getAttrs() : nullptr);
-    auto *PseudoSrcExpr = buildDeclRefExpr(
-        *this, SrcVD, Type.getUnqualifiedType(), DE->getExprLoc());
+                               D->hasAttrs() ? &D->getAttrs() : nullptr);
+    auto *PseudoSrcExpr =
+        buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
     auto *DstVD =
-        buildVarDecl(*this, DE->getLocStart(), Type, ".lastprivate.dst",
-                     VD->hasAttrs() ? &VD->getAttrs() : nullptr);
-    auto *PseudoDstExpr =
-        buildDeclRefExpr(*this, DstVD, Type, DE->getExprLoc());
+        buildVarDecl(*this, RefExpr->getLocStart(), Type, ".lastprivate.dst",
+                     D->hasAttrs() ? &D->getAttrs() : nullptr);
+    auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
     // For arrays generate assignment operation for single element and replace
     // it by the original array element in CodeGen.
-    auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign,
+    auto AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
                                    PseudoDstExpr, PseudoSrcExpr);
     if (AssignmentOp.isInvalid())
       continue;
-    AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
+    AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
                                        /*DiscardedValue=*/true);
     if (AssignmentOp.isInvalid())
       continue;
 
-    // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
-    // A list item may appear in a firstprivate or lastprivate clause but not
-    // both.
-    if (CurrDir == OMPD_distribute) {
-      DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false);
-      if (DVar.CKind == OMPC_firstprivate) {
-        Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute);
-        ReportOriginalDSA(*this, DSAStack, VD, DVar);
-        continue;
-      }
-    }
-
+    DeclRefExpr *Ref = nullptr;
+    if (!VD)
+      Ref = buildCapture(*this, D->getIdentifier(), RefExpr);
     if (TopDVar.CKind != OMPC_firstprivate)
-      DSAStack->addDSA(VD, DE, OMPC_lastprivate);
-    Vars.push_back(DE);
+      DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
+    Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref);
     SrcExprs.push_back(PseudoSrcExpr);
     DstExprs.push_back(PseudoDstExpr);
     AssignmentOps.push_back(AssignmentOp.get());

Modified: cfe/trunk/test/OpenMP/for_ast_print.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_ast_print.cpp?rev=261412&r1=261411&r2=261412&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/for_ast_print.cpp (original)
+++ cfe/trunk/test/OpenMP/for_ast_print.cpp Fri Feb 19 22:09:36 2016
@@ -26,25 +26,37 @@ public:
 #pragma omp for private(a) private(this->a) private(T::a)
     for (int k = 0; k < a.a; ++k)
       ++this->a.a;
+#pragma omp for lastprivate(a) lastprivate(this->a) lastprivate(T::a)
+    for (int k = 0; k < a.a; ++k)
+      ++this->a.a;
   }
   S7 &operator=(S7 &s) {
 #pragma omp for private(a) private(this->a)
     for (int k = 0; k < s.a.a; ++k)
       ++s.a.a;
+#pragma omp for lastprivate(a) lastprivate(this->a)
+    for (int k = 0; k < s.a.a; ++k)
+      ++s.a.a;
     return *this;
   }
 };
 
 // CHECK: #pragma omp for private(this->a) private(this->a) private(this->S::a)
+// CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a) lastprivate(this->S::a)
 // CHECK: #pragma omp for private(this->a) private(this->a) private(T::a)
+// CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a) lastprivate(T::a)
 // CHECK: #pragma omp for private(this->a) private(this->a)
+// CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a)
 
 class S8 : public S7<S> {
   S8() {}
 
 public:
   S8(int v) : S7<S>(v){
-#pragma omp for private(a) private(this->a) private(S7<S>::a) 
+#pragma omp for private(a) private(this->a) private(S7<S>::a)
+    for (int k = 0; k < a.a; ++k)
+      ++this->a.a;
+#pragma omp for lastprivate(a) lastprivate(this->a) lastprivate(S7<S>::a)
     for (int k = 0; k < a.a; ++k)
       ++this->a.a;
   }
@@ -52,12 +64,17 @@ public:
 #pragma omp for private(a) private(this->a)
     for (int k = 0; k < s.a.a; ++k)
       ++s.a.a;
+#pragma omp for lastprivate(a) lastprivate(this->a)
+    for (int k = 0; k < s.a.a; ++k)
+      ++s.a.a;
     return *this;
   }
 };
 
 // CHECK: #pragma omp for private(this->a) private(this->a) private(this->S7<S>::a)
+// CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a) lastprivate(this->S7<S>::a)
 // CHECK: #pragma omp for private(this->a) private(this->a)
+// CHECK: #pragma omp for lastprivate(this->a) lastprivate(this->a)
 
 template <class T, int N>
 T tmain(T argc) {

Modified: cfe/trunk/test/OpenMP/simd_lastprivate_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/simd_lastprivate_messages.cpp?rev=261412&r1=261411&r2=261412&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/simd_lastprivate_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/simd_lastprivate_messages.cpp Fri Feb 19 22:09:36 2016
@@ -217,5 +217,5 @@ int main(int argc, char **argv) {
 #pragma omp simd lastprivate(t) // OK
   for (i = 0; i < argc; ++i)
     foo();
-  return 0;
+  return foomain(argc, argv); // expected-note {{in instantiation of function template specialization 'foomain<int, char>' requested here}}
 }




More information about the cfe-commits mailing list