summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2016-02-25 05:25:57 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2016-02-25 05:25:57 +0000
commit005248ac8adf63d4a6a46b1f6cdb9fea686a2f9d (patch)
treeae4d8331e3ca9ecea9de2420509ab715a87e80d2 /clang/lib/Sema
parent640dc752a9445f67f3955475433b9fa2bbf9de98 (diff)
downloadbcm5719-llvm-005248ac8adf63d4a6a46b1f6cdb9fea686a2f9d.tar.gz
bcm5719-llvm-005248ac8adf63d4a6a46b1f6cdb9fea686a2f9d.zip
[OPENMP 4.5] Codegen for member decls in 'lastprivate' clause.
OpenMP 4.5 allows to privatize non-static member decls in non-static member functions. Patch captures such decls by reference in general (for bitfields, by value) and then operates with this capture. For bitfields, at the end of codegen for lastprivates original bitfield is updated with the value of captured copy. llvm-svn: 261824
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp84
1 files changed, 62 insertions, 22 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index d4196b87e2b..2463c373a2d 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -990,21 +990,10 @@ void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
PrivateCopies.push_back(nullptr);
continue;
}
- VarDecl *VD = nullptr;
- FieldDecl *FD = nullptr;
- ValueDecl *D;
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;
- }
- QualType Type = D->getType().getNonReferenceType();
- auto DVar = DSAStack->getTopDSA(D, false);
+ VarDecl *VD = cast<VarDecl>(DRE->getDecl());
+ QualType Type = VD->getType().getNonReferenceType();
+ auto DVar = DSAStack->getTopDSA(VD, false);
if (DVar.CKind == OMPC_lastprivate) {
// Generate helper private variable and initialize it with the
// default value. The address of the original variable is replaced
@@ -1013,7 +1002,7 @@ void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
// region uses original variable for proper diagnostics.
auto *VDPrivate = buildVarDecl(
*this, DE->getExprLoc(), Type.getUnqualifiedType(),
- D->getName(), D->hasAttrs() ? &D->getAttrs() : nullptr);
+ VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr);
ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false);
if (VDPrivate->isInvalidDecl())
continue;
@@ -1786,11 +1775,15 @@ StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
// Required for proper codegen of combined directives.
// TODO: add processing for other clauses.
if (auto *C = OMPClauseWithPreInit::get(Clause)) {
- if (auto *S = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
- for (auto *D : S->decls())
+ if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
+ for (auto *D : DS->decls())
MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
}
}
+ if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
+ if (auto *E = C->getPostUpdateExpr())
+ MarkDeclarationsReferencedInExpr(E);
+ }
}
if (Clause->getClauseKind() == OMPC_schedule)
SC = cast<OMPScheduleClause>(Clause);
@@ -7289,8 +7282,10 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
auto ElemType = Context.getBaseElementType(Type).getNonReferenceType();
// If an implicit firstprivate variable found it was checked already.
+ DSAStackTy::DSAVarData TopDVar;
if (!IsImplicitClause) {
DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
+ TopDVar = DVar;
bool IsConstant = ElemType.isConstant(Context);
// OpenMP [2.4.13, Data-sharing Attribute Clauses]
// A list item that specifies a given variable may not appear in more
@@ -7485,8 +7480,13 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
RefExpr->getExprLoc());
DeclRefExpr *Ref = nullptr;
if (!VD) {
- Ref = buildCapture(*this, D, RefExpr);
- ExprCaptures.push_back(Ref->getDecl());
+ if (TopDVar.CKind == OMPC_lastprivate)
+ Ref = TopDVar.PrivateCopy;
+ else {
+ Ref = buildCapture(*this, D, RefExpr);
+ if (!IsOpenMPCapturedDecl(D))
+ ExprCaptures.push_back(Ref->getDecl());
+ }
}
DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref);
@@ -7516,6 +7516,8 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
SmallVector<Expr *, 8> SrcExprs;
SmallVector<Expr *, 8> DstExprs;
SmallVector<Expr *, 8> AssignmentOps;
+ SmallVector<Decl *, 4> ExprCaptures;
+ SmallVector<Expr *, 4> ExprPostUpdates;
for (auto &RefExpr : VarList) {
assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
auto Res = getPrivateItem(*this, RefExpr);
@@ -7620,8 +7622,28 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
continue;
DeclRefExpr *Ref = nullptr;
- if (!VD)
- Ref = buildCapture(*this, D, RefExpr);
+ if (!VD) {
+ if (TopDVar.CKind == OMPC_firstprivate)
+ Ref = TopDVar.PrivateCopy;
+ else {
+ Ref = buildCapture(*this, D, RefExpr);
+ if (!IsOpenMPCapturedDecl(D))
+ ExprCaptures.push_back(Ref->getDecl());
+ }
+ if (TopDVar.CKind == OMPC_firstprivate ||
+ (!IsOpenMPCapturedDecl(D) &&
+ !Ref->getDecl()->getType()->isReferenceType())) {
+ ExprResult RefRes = DefaultLvalueConversion(Ref);
+ if (!RefRes.isUsable())
+ continue;
+ ExprResult PostUpdateRes =
+ BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
+ RefExpr->IgnoreParenLValueCasts(), RefRes.get());
+ if (!PostUpdateRes.isUsable())
+ continue;
+ ExprPostUpdates.push_back(PostUpdateRes.get());
+ }
+ }
if (TopDVar.CKind != OMPC_firstprivate)
DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref);
@@ -7632,9 +7654,27 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
if (Vars.empty())
return nullptr;
+ Stmt *PreInit = nullptr;
+ if (!ExprCaptures.empty()) {
+ PreInit = new (Context)
+ DeclStmt(DeclGroupRef::Create(Context, ExprCaptures.begin(),
+ ExprCaptures.size()),
+ SourceLocation(), SourceLocation());
+ }
+ Expr *PostUpdate = nullptr;
+ if (!ExprPostUpdates.empty()) {
+ for (auto *E : ExprPostUpdates) {
+ ExprResult PostUpdateRes =
+ PostUpdate
+ ? CreateBuiltinBinOp(SourceLocation(), BO_Comma, PostUpdate, E)
+ : E;
+ PostUpdate = PostUpdateRes.get();
+ }
+ }
return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
- Vars, SrcExprs, DstExprs, AssignmentOps);
+ Vars, SrcExprs, DstExprs, AssignmentOps,
+ PreInit, PostUpdate);
}
OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
OpenPOWER on IntegriCloud