From 78849fb464ce63bd701e07d607d4c70ceec897f4 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Wed, 9 Mar 2016 09:49:00 +0000 Subject: [PATCH] [OPENMP 4.5] Codegen for data members in 'linear' clause. OpenMP 4.5 allows to use data members in private clauses. Patch adds codegen support for 'linear' clause. llvm-svn: 263002 --- clang/include/clang/AST/OpenMPClause.h | 14 ++++++-- clang/include/clang/AST/RecursiveASTVisitor.h | 1 + clang/lib/AST/OpenMPClause.cpp | 11 ++++-- clang/lib/AST/StmtProfile.cpp | 1 + clang/lib/CodeGen/CGStmtOpenMP.cpp | 17 ++-------- clang/lib/Sema/SemaOpenMP.cpp | 49 +++++++++++++++++++++++---- clang/lib/Serialization/ASTReaderStmt.cpp | 1 + clang/lib/Serialization/ASTWriterStmt.cpp | 1 + clang/tools/libclang/CIndex.cpp | 1 + 9 files changed, 69 insertions(+), 27 deletions(-) diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index baf2d89..48a03b1 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -1877,6 +1877,7 @@ public: /// class OMPLinearClause final : public OMPVarListClause, + public OMPClauseWithPostUpdate, private llvm::TrailingObjects { friend TrailingObjects; friend OMPVarListClause; @@ -1908,7 +1909,8 @@ class OMPLinearClause final unsigned NumVars) : OMPVarListClause(OMPC_linear, StartLoc, LParenLoc, EndLoc, NumVars), - Modifier(Modifier), ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {} + OMPClauseWithPostUpdate(this), Modifier(Modifier), + ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {} /// \brief Build an empty clause. /// @@ -1918,7 +1920,8 @@ class OMPLinearClause final : OMPVarListClause(OMPC_linear, SourceLocation(), SourceLocation(), SourceLocation(), NumVars), - Modifier(OMPC_LINEAR_val), ModifierLoc(), ColonLoc() {} + OMPClauseWithPostUpdate(this), Modifier(OMPC_LINEAR_val), ModifierLoc(), + ColonLoc() {} /// \brief Gets the list of initial values for linear variables. /// @@ -1987,11 +1990,16 @@ public: /// \param IL List of initial values for the variables. /// \param Step Linear step. /// \param CalcStep Calculation of the linear step. + /// \param PreInit Statement that must be executed before entering the OpenMP + /// region with this clause. + /// \param PostUpdate Expression that must be executed after exit from the + /// OpenMP region with this clause. static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef VL, - ArrayRef PL, ArrayRef IL, Expr *Step, Expr *CalcStep); + ArrayRef PL, ArrayRef IL, Expr *Step, Expr *CalcStep, + Stmt *PreInit, Expr *PostUpdate); /// \brief Creates an empty clause with the place for \a NumVars variables. /// diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 1426e3f..6d86727 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2719,6 +2719,7 @@ bool RecursiveASTVisitor::VisitOMPLinearClause(OMPLinearClause *C) { TRY_TO(TraverseStmt(C->getStep())); TRY_TO(TraverseStmt(C->getCalcStep())); TRY_TO(VisitOMPClauseList(C)); + TRY_TO(VisitOMPClauseWithPostUpdate(C)); for (auto *E : C->privates()) { TRY_TO(TraverseStmt(E)); } diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp index 3c0952be..8843ded 100644 --- a/clang/lib/AST/OpenMPClause.cpp +++ b/clang/lib/AST/OpenMPClause.cpp @@ -46,6 +46,8 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) { return static_cast(C); case OMPC_reduction: return static_cast(C); + case OMPC_linear: + return static_cast(C); case OMPC_default: case OMPC_proc_bind: case OMPC_if: @@ -56,7 +58,6 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) { case OMPC_collapse: case OMPC_private: case OMPC_shared: - case OMPC_linear: case OMPC_aligned: case OMPC_copyin: case OMPC_copyprivate: @@ -102,6 +103,8 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C) return static_cast(C); case OMPC_reduction: return static_cast(C); + case OMPC_linear: + return static_cast(C); case OMPC_schedule: case OMPC_dist_schedule: case OMPC_firstprivate: @@ -115,7 +118,6 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C) case OMPC_collapse: case OMPC_private: case OMPC_shared: - case OMPC_linear: case OMPC_aligned: case OMPC_copyin: case OMPC_copyprivate: @@ -304,7 +306,8 @@ OMPLinearClause *OMPLinearClause::Create( const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef VL, - ArrayRef PL, ArrayRef IL, Expr *Step, Expr *CalcStep) { + ArrayRef PL, ArrayRef IL, Expr *Step, Expr *CalcStep, + Stmt *PreInit, Expr *PostUpdate) { // Allocate space for 4 lists (Vars, Inits, Updates, Finals) and 2 expressions // (Step and CalcStep). void *Mem = C.Allocate(totalSizeToAlloc(5 * VL.size() + 2)); @@ -321,6 +324,8 @@ OMPLinearClause *OMPLinearClause::Create( nullptr); Clause->setStep(Step); Clause->setCalcStep(CalcStep); + Clause->setPreInitStmt(PreInit); + Clause->setPostUpdateExpr(PostUpdate); return Clause; } diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 442e32a..327b4c0 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -415,6 +415,7 @@ void OMPClauseProfiler::VisitOMPReductionClause( } void OMPClauseProfiler::VisitOMPLinearClause(const OMPLinearClause *C) { VisitOMPClauseList(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 dfa3b91..211155e 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -45,25 +45,10 @@ class OMPLexicalScope { } } - class PostUpdateCleanup final : public EHScopeStack::Cleanup { - const OMPExecutableDirective &S; - - public: - PostUpdateCleanup(const OMPExecutableDirective &S) : S(S) {} - - void Emit(CodeGenFunction &CGF, Flags /*flags*/) override { - if (!CGF.HaveInsertPoint()) - return; - (void)S; - // TODO: add cleanups for clauses that require post update. - } - }; - public: OMPLexicalScope(CodeGenFunction &CGF, const OMPExecutableDirective &S) : Scope(CGF, S.getSourceRange()) { emitPreInitStmt(CGF, S); - CGF.EHStack.pushCleanup(NormalAndEHCleanup, S); } }; } // namespace @@ -1172,6 +1157,8 @@ static void emitLinearClauseFinal(CodeGenFunction &CGF, CGF.EmitIgnoredExpr(F); ++IC; } + if (auto *PostUpdate = C->getPostUpdateExpr()) + EmitIgnoredExpr(PostUpdate); } } diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index ffac56b..0af38fb 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -7688,7 +7688,8 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef VarList, RefRes.get()); if (!PostUpdateRes.isUsable()) continue; - ExprPostUpdates.push_back(PostUpdateRes.get()); + ExprPostUpdates.push_back( + IgnoredValueConversions(PostUpdateRes.get()).get()); } } if (TopDVar.CKind != OMPC_firstprivate) @@ -8289,7 +8290,8 @@ OMPClause *Sema::ActOnOpenMPReductionClause( SimpleRefExpr, RefRes.get()); if (!PostUpdateRes.isUsable()) continue; - ExprPostUpdates.push_back(PostUpdateRes.get()); + ExprPostUpdates.push_back( + IgnoredValueConversions(PostUpdateRes.get()).get()); } } } @@ -8322,7 +8324,6 @@ OMPClause *Sema::ActOnOpenMPReductionClause( } } - return OMPReductionClause::Create( Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, Privates, @@ -8336,6 +8337,8 @@ OMPClause *Sema::ActOnOpenMPLinearClause( SmallVector Vars; SmallVector Privates; SmallVector Inits; + SmallVector ExprCaptures; + SmallVector ExprPostUpdates; if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || LinKind == OMPC_LINEAR_unknown) { Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; @@ -8421,8 +8424,24 @@ OMPClause *Sema::ActOnOpenMPLinearClause( VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); Expr *InitExpr; DeclRefExpr *Ref = nullptr; - if (!VD) - Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); + if (!VD) { + Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); + if (!IsOpenMPCapturedDecl(D)) { + ExprCaptures.push_back(Ref->getDecl()); + if (Ref->getDecl()->hasAttr()) { + 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( + IgnoredValueConversions(PostUpdateRes.get()).get()); + } + } + } if (LinKind == OMPC_LINEAR_uval) InitExpr = VD ? VD->getInit() : SimpleRefExpr; else @@ -8474,9 +8493,27 @@ OMPClause *Sema::ActOnOpenMPLinearClause( } } + 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 OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, ColonLoc, EndLoc, Vars, Privates, Inits, - StepExpr, CalcStepExpr); + StepExpr, CalcStepExpr, PreInit, PostUpdate); } static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index e5791d8..ab44c96 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -2098,6 +2098,7 @@ void OMPClauseReader::VisitOMPReductionClause(OMPReductionClause *C) { } void OMPClauseReader::VisitOMPLinearClause(OMPLinearClause *C) { + VisitOMPClauseWithPostUpdate(C); C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx)); C->setColonLoc(Reader->ReadSourceLocation(Record, Idx)); C->setModifier(static_cast(Record[Idx++])); diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 02d7a60..ea3b804 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -1930,6 +1930,7 @@ void OMPClauseWriter::VisitOMPReductionClause(OMPReductionClause *C) { void OMPClauseWriter::VisitOMPLinearClause(OMPLinearClause *C) { Record.push_back(C->varlist_size()); + VisitOMPClauseWithPostUpdate(C); Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record); Writer->Writer.AddSourceLocation(C->getColonLoc(), Record); Record.push_back(C->getModifier()); diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index 5a7af9d..5dca6f9 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -2194,6 +2194,7 @@ void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) { } void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) { VisitOMPClauseList(C); + VisitOMPClauseWithPostUpdate(C); for (const auto *E : C->privates()) { Visitor->AddStmt(E); } -- 2.7.4