diff options
| author | Alexey Bataev <a.bataev@hotmail.com> | 2016-03-02 04:57:40 +0000 |
|---|---|---|
| committer | Alexey Bataev <a.bataev@hotmail.com> | 2016-03-02 04:57:40 +0000 |
| commit | 61205070c457653961bdd5ce513f31f29a73e068 (patch) | |
| tree | 708f0b1e98d9c0db7a74e9ef6315224edf5de759 /clang/lib | |
| parent | dcd3a88e29413af8a41b09ea0dcaeabec2a3a440 (diff) | |
| download | bcm5719-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.cpp | 11 | ||||
| -rw-r--r-- | clang/lib/AST/StmtProfile.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGStmtOpenMP.cpp | 41 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExprMember.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 77 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReaderStmt.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTWriterStmt.cpp | 2 |
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); |

