summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2016-03-02 04:57:40 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2016-03-02 04:57:40 +0000
commit61205070c457653961bdd5ce513f31f29a73e068 (patch)
tree708f0b1e98d9c0db7a74e9ef6315224edf5de759 /clang/lib
parentdcd3a88e29413af8a41b09ea0dcaeabec2a3a440 (diff)
downloadbcm5719-llvm-61205070c457653961bdd5ce513f31f29a73e068.tar.gz
bcm5719-llvm-61205070c457653961bdd5ce513f31f29a73e068.zip
[OPENMP 4.5] Codegen for data members in 'reduction' clause.
OpenMP 4.5 allows to privatize non-static data members of current class in non-static member functions. Patch supports codegen for non-static data members in 'reduction' clauses. llvm-svn: 262460
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/OpenMPClause.cpp11
-rw-r--r--clang/lib/AST/StmtProfile.cpp2
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp41
-rw-r--r--clang/lib/Sema/SemaExprMember.cpp2
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp77
-rw-r--r--clang/lib/Serialization/ASTReaderStmt.cpp2
-rw-r--r--clang/lib/Serialization/ASTWriterStmt.cpp2
7 files changed, 115 insertions, 22 deletions
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index 0a2b87410b0..3c0952be556 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -44,6 +44,8 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
return static_cast<const OMPFirstprivateClause *>(C);
case OMPC_lastprivate:
return static_cast<const OMPLastprivateClause *>(C);
+ case OMPC_reduction:
+ return static_cast<const OMPReductionClause *>(C);
case OMPC_default:
case OMPC_proc_bind:
case OMPC_if:
@@ -54,7 +56,6 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
case OMPC_collapse:
case OMPC_private:
case OMPC_shared:
- case OMPC_reduction:
case OMPC_linear:
case OMPC_aligned:
case OMPC_copyin:
@@ -99,6 +100,8 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
switch (C->getClauseKind()) {
case OMPC_lastprivate:
return static_cast<const OMPLastprivateClause *>(C);
+ case OMPC_reduction:
+ return static_cast<const OMPReductionClause *>(C);
case OMPC_schedule:
case OMPC_dist_schedule:
case OMPC_firstprivate:
@@ -112,7 +115,6 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
case OMPC_collapse:
case OMPC_private:
case OMPC_shared:
- case OMPC_reduction:
case OMPC_linear:
case OMPC_aligned:
case OMPC_copyin:
@@ -463,7 +465,8 @@ OMPReductionClause *OMPReductionClause::Create(
SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
- ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps) {
+ ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps, Stmt *PreInit,
+ Expr *PostUpdate) {
void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));
OMPReductionClause *Clause = new (Mem) OMPReductionClause(
StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
@@ -472,6 +475,8 @@ OMPReductionClause *OMPReductionClause::Create(
Clause->setLHSExprs(LHSExprs);
Clause->setRHSExprs(RHSExprs);
Clause->setReductionOps(ReductionOps);
+ Clause->setPreInitStmt(PreInit);
+ Clause->setPostUpdateExpr(PostUpdate);
return Clause;
}
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 4686483871d..c0da73d2962 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -399,6 +399,8 @@ void OMPClauseProfiler::VisitOMPReductionClause(
C->getQualifierLoc().getNestedNameSpecifier());
Profiler->VisitName(C->getNameInfo().getName());
VisitOMPClauseList(C);
+ VistOMPClauseWithPreInit(C);
+ VistOMPClauseWithPostUpdate(C);
for (auto *E : C->privates()) {
Profiler->VisitStmt(E);
}
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 457d21e3dc2..90d6a829e14 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -943,6 +943,31 @@ void CodeGenFunction::EmitOMPReductionClauseFinal(
}
}
+static void emitPostUpdateForReductionClause(
+ CodeGenFunction &CGF, const OMPExecutableDirective &D,
+ const llvm::function_ref<llvm::Value *(CodeGenFunction &)> &CondGen) {
+ if (!CGF.HaveInsertPoint())
+ return;
+ llvm::BasicBlock *DoneBB = nullptr;
+ for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
+ if (auto *PostUpdate = C->getPostUpdateExpr()) {
+ if (!DoneBB) {
+ if (auto *Cond = CondGen(CGF)) {
+ // If the first post-update expression is found, emit conditional
+ // block if it was requested.
+ auto *ThenBB = CGF.createBasicBlock(".omp.reduction.pu");
+ DoneBB = CGF.createBasicBlock(".omp.reduction.pu.done");
+ CGF.Builder.CreateCondBr(Cond, ThenBB, DoneBB);
+ CGF.EmitBlock(ThenBB);
+ }
+ }
+ CGF.EmitIgnoredExpr(PostUpdate);
+ }
+ }
+ if (DoneBB)
+ CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
+}
+
static void emitCommonOMPParallelDirective(CodeGenFunction &CGF,
const OMPExecutableDirective &S,
OpenMPDirectiveKind InnermostKind,
@@ -998,6 +1023,8 @@ void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) {
CGF.EmitOMPReductionClauseFinal(S);
};
emitCommonOMPParallelDirective(*this, S, OMPD_parallel, CodeGen);
+ emitPostUpdateForReductionClause(
+ *this, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; });
}
void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &D,
@@ -1346,6 +1373,8 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
CGF.EmitOMPLastprivateClauseFinal(S);
}
CGF.EmitOMPReductionClauseFinal(S);
+ emitPostUpdateForReductionClause(
+ CGF, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; });
}
CGF.EmitOMPSimdFinal(S);
// Emit: if (PreCond) - end.
@@ -1669,6 +1698,12 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) {
IL.getAddress(), Chunk);
}
EmitOMPReductionClauseFinal(S);
+ // Emit post-update of the reduction variables if IsLastIter != 0.
+ emitPostUpdateForReductionClause(
+ *this, S, [&](CodeGenFunction &CGF) -> llvm::Value * {
+ return CGF.Builder.CreateIsNotNull(
+ CGF.EmitLoadOfScalar(IL, S.getLocStart()));
+ });
// Emit final copy of the lastprivate variables if IsLastIter != 0.
if (HasLastprivateClause)
EmitOMPLastprivateClauseFinal(
@@ -1827,6 +1862,12 @@ void CodeGenFunction::EmitSections(const OMPExecutableDirective &S) {
// Tell the runtime we are done.
CGF.CGM.getOpenMPRuntime().emitForStaticFinish(CGF, S.getLocStart());
CGF.EmitOMPReductionClauseFinal(S);
+ // Emit post-update of the reduction variables if IsLastIter != 0.
+ emitPostUpdateForReductionClause(
+ CGF, S, [&](CodeGenFunction &CGF) -> llvm::Value * {
+ return CGF.Builder.CreateIsNotNull(
+ CGF.EmitLoadOfScalar(IL, S.getLocStart()));
+ });
// Emit final copy of the lastprivate variables if IsLastIter != 0.
if (HasLastprivates)
diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp
index dfe63a86d28..0ce3974e51c 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -1794,7 +1794,7 @@ BuildFieldReferenceExpr(Sema &S, Expr *BaseExpr, bool IsArrow,
if (S.getLangOpts().OpenMP && IsArrow &&
isa<CXXThisExpr>(Base.get()->IgnoreParenImpCasts())) {
if (auto *PrivateCopy = S.IsOpenMPCapturedDecl(Field))
- return S.getOpenMPCapturedExpr(PrivateCopy, VK, OK);
+ return S.getOpenMPCapturedExpr(PrivateCopy, VK, OK, OpLoc);
}
return ME;
}
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index e115a2ffd47..86ad66f4a62 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -1705,7 +1705,7 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
}
static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
- Expr *CaptureExpr) {
+ Expr *CaptureExpr, bool WithInit) {
ASTContext &C = S.getASTContext();
Expr *Init = CaptureExpr->IgnoreImpCasts();
QualType Ty = Init->getType();
@@ -1720,27 +1720,33 @@ static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
return nullptr;
Init = Res.get();
}
+ WithInit = true;
}
auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty);
S.CurContext->addHiddenDecl(CED);
- S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false,
- /*TypeMayContainAuto=*/true);
+ if (WithInit)
+ S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false,
+ /*TypeMayContainAuto=*/true);
+ else
+ S.ActOnUninitializedDecl(CED, /*TypeMayContainAuto=*/true);
return CED;
}
-static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr) {
+static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
+ bool WithInit) {
OMPCapturedExprDecl *CD;
if (auto *VD = S.IsOpenMPCapturedDecl(D))
CD = cast<OMPCapturedExprDecl>(VD);
else
- CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr);
+ CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit);
return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
SourceLocation());
}
static DeclRefExpr *buildCapture(Sema &S, Expr *CaptureExpr) {
- auto *CD = buildCaptureDecl(
- S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr);
+ auto *CD =
+ buildCaptureDecl(S, &S.getASTContext().Idents.get(".capture_expr."),
+ CaptureExpr, /*WithInit=*/true);
return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
SourceLocation());
}
@@ -7077,8 +7083,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
}
ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
- ExprObjectKind OK) {
- SourceLocation Loc = Capture->getInit()->getExprLoc();
+ ExprObjectKind OK, SourceLocation Loc) {
ExprResult Res = BuildDeclRefExpr(
Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
if (!Res.isUsable())
@@ -7236,7 +7241,7 @@ OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
DeclRefExpr *Ref = nullptr;
if (!VD)
- Ref = buildCapture(*this, D, SimpleRefExpr);
+ Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref);
PrivateCopies.push_back(VDPrivateRefExpr);
@@ -7520,7 +7525,7 @@ OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
if (TopDVar.CKind == OMPC_lastprivate)
Ref = TopDVar.PrivateCopy;
else {
- Ref = buildCapture(*this, D, SimpleRefExpr);
+ Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
if (!IsOpenMPCapturedDecl(D))
ExprCaptures.push_back(Ref->getDecl());
}
@@ -7665,13 +7670,13 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList,
if (TopDVar.CKind == OMPC_firstprivate)
Ref = TopDVar.PrivateCopy;
else {
- Ref = buildCapture(*this, D, SimpleRefExpr);
+ Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
if (!IsOpenMPCapturedDecl(D))
ExprCaptures.push_back(Ref->getDecl());
}
if (TopDVar.CKind == OMPC_firstprivate ||
(!IsOpenMPCapturedDecl(D) &&
- !Ref->getDecl()->getType()->isReferenceType())) {
+ !cast<OMPCapturedExprDecl>(Ref->getDecl())->getInit())) {
ExprResult RefRes = DefaultLvalueConversion(Ref);
if (!RefRes.isUsable())
continue;
@@ -7754,7 +7759,7 @@ OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
DeclRefExpr *Ref = nullptr;
if (!VD)
- Ref = buildCapture(*this, D, SimpleRefExpr);
+ Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref);
}
@@ -7811,7 +7816,7 @@ public:
ExprResult TransformMemberExpr(MemberExpr *E) {
if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
E->getMemberDecl() == Field) {
- CapturedExpr = buildCapture(SemaRef, Field, E);
+ CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
return CapturedExpr;
}
return BaseTransform::TransformMemberExpr(E);
@@ -7929,6 +7934,8 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
SmallVector<Expr *, 8> LHSs;
SmallVector<Expr *, 8> RHSs;
SmallVector<Expr *, 8> ReductionOps;
+ SmallVector<Decl *, 4> ExprCaptures;
+ SmallVector<Expr *, 4> ExprPostUpdates;
for (auto RefExpr : VarList) {
assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
// OpenMP [2.1, C/C++]
@@ -8265,8 +8272,24 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
VarsExpr =
RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
Ref = RebuildToCapture.getCapturedExpr();
- } else
- VarsExpr = Ref = buildCapture(*this, D, SimpleRefExpr);
+ } else {
+ VarsExpr = Ref =
+ buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
+ if (!IsOpenMPCapturedDecl(D)) {
+ ExprCaptures.push_back(Ref->getDecl());
+ if (!cast<OMPCapturedExprDecl>(Ref->getDecl())->getInit()) {
+ ExprResult RefRes = DefaultLvalueConversion(Ref);
+ if (!RefRes.isUsable())
+ continue;
+ ExprResult PostUpdateRes =
+ BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
+ SimpleRefExpr, RefRes.get());
+ if (!PostUpdateRes.isUsable())
+ continue;
+ ExprPostUpdates.push_back(PostUpdateRes.get());
+ }
+ }
+ }
}
DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
Vars.push_back(VarsExpr);
@@ -8278,11 +8301,29 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
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 OMPReductionClause::Create(
Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars,
ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, Privates,
- LHSs, RHSs, ReductionOps);
+ LHSs, RHSs, ReductionOps, PreInit, PostUpdate);
}
OMPClause *Sema::ActOnOpenMPLinearClause(
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index e699889106b..7eaeccf0fc4 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -2063,6 +2063,8 @@ void OMPClauseReader::VisitOMPSharedClause(OMPSharedClause *C) {
}
void OMPClauseReader::VisitOMPReductionClause(OMPReductionClause *C) {
+ VisitOMPClauseWithPreInit(C);
+ VisitOMPClauseWithPostUpdate(C);
C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
C->setColonLoc(Reader->ReadSourceLocation(Record, Idx));
NestedNameSpecifierLoc NNSL =
diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index 43a4f36d1de..0cebc1d977c 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -1911,6 +1911,8 @@ void OMPClauseWriter::VisitOMPSharedClause(OMPSharedClause *C) {
void OMPClauseWriter::VisitOMPReductionClause(OMPReductionClause *C) {
Record.push_back(C->varlist_size());
+ VisitOMPClauseWithPreInit(C);
+ VisitOMPClauseWithPostUpdate(C);
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
Writer->Writer.AddSourceLocation(C->getColonLoc(), Record);
Writer->Writer.AddNestedNameSpecifierLoc(C->getQualifierLoc(), Record);
OpenPOWER on IntegriCloud