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