diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2017-07-18 20:17:46 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2017-07-18 20:17:46 +0000 |
commit | c874b4b3b131a32aeab924ae30b4568dd453346a (patch) | |
tree | 97327c8c8362132aee821a5a08e17f1bfde8b4c2 /lib | |
parent | 04cbc70306ef33aad7ae29a2cfd648e8b73d9fef (diff) | |
download | clang-c874b4b3b131a32aeab924ae30b4568dd453346a.tar.gz |
[OPENMP] Initial support for 'task_reduction' clause.
Parsing/sema analysis of the 'task_reduction' clause.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@308352 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/OpenMPClause.cpp | 57 | ||||
-rw-r--r-- | lib/AST/StmtOpenMP.cpp | 21 | ||||
-rw-r--r-- | lib/AST/StmtPrinter.cpp | 25 | ||||
-rw-r--r-- | lib/AST/StmtProfile.cpp | 24 | ||||
-rw-r--r-- | lib/Basic/OpenMPKinds.cpp | 16 | ||||
-rw-r--r-- | lib/CodeGen/CGStmtOpenMP.cpp | 1 | ||||
-rw-r--r-- | lib/Parse/ParseOpenMP.cpp | 23 | ||||
-rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 72 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 60 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderStmt.cpp | 42 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterStmt.cpp | 20 |
11 files changed, 321 insertions, 40 deletions
diff --git a/lib/AST/OpenMPClause.cpp b/lib/AST/OpenMPClause.cpp index 77470a9b76..2c4d159a1b 100644 --- a/lib/AST/OpenMPClause.cpp +++ b/lib/AST/OpenMPClause.cpp @@ -46,6 +46,8 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) { return static_cast<const OMPLastprivateClause *>(C); case OMPC_reduction: return static_cast<const OMPReductionClause *>(C); + case OMPC_task_reduction: + return static_cast<const OMPTaskReductionClause *>(C); case OMPC_linear: return static_cast<const OMPLinearClause *>(C); case OMPC_if: @@ -112,6 +114,8 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C) return static_cast<const OMPLastprivateClause *>(C); case OMPC_reduction: return static_cast<const OMPReductionClause *>(C); + case OMPC_task_reduction: + return static_cast<const OMPTaskReductionClause *>(C); case OMPC_linear: return static_cast<const OMPLinearClause *>(C); case OMPC_schedule: @@ -505,6 +509,59 @@ OMPReductionClause *OMPReductionClause::CreateEmpty(const ASTContext &C, return new (Mem) OMPReductionClause(N); } +void OMPTaskReductionClause::setPrivates(ArrayRef<Expr *> Privates) { + assert(Privates.size() == varlist_size() && + "Number of private copies is not the same as the preallocated buffer"); + std::copy(Privates.begin(), Privates.end(), varlist_end()); +} + +void OMPTaskReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) { + assert( + LHSExprs.size() == varlist_size() && + "Number of LHS expressions is not the same as the preallocated buffer"); + std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end()); +} + +void OMPTaskReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) { + assert( + RHSExprs.size() == varlist_size() && + "Number of RHS expressions is not the same as the preallocated buffer"); + std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end()); +} + +void OMPTaskReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) { + assert(ReductionOps.size() == varlist_size() && "Number of task reduction " + "expressions is not the same " + "as the preallocated buffer"); + std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end()); +} + +OMPTaskReductionClause *OMPTaskReductionClause::Create( + const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL, + NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, + ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs, + ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps, Stmt *PreInit, + Expr *PostUpdate) { + void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size())); + OMPTaskReductionClause *Clause = new (Mem) OMPTaskReductionClause( + StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo); + Clause->setVarRefs(VL); + Clause->setPrivates(Privates); + Clause->setLHSExprs(LHSExprs); + Clause->setRHSExprs(RHSExprs); + Clause->setReductionOps(ReductionOps); + Clause->setPreInitStmt(PreInit); + Clause->setPostUpdateExpr(PostUpdate); + return Clause; +} + +OMPTaskReductionClause *OMPTaskReductionClause::CreateEmpty(const ASTContext &C, + unsigned N) { + void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N)); + return new (Mem) OMPTaskReductionClause(N); +} + OMPFlushClause *OMPFlushClause::Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, diff --git a/lib/AST/StmtOpenMP.cpp b/lib/AST/StmtOpenMP.cpp index cccb2f075b..1dcb4fd519 100644 --- a/lib/AST/StmtOpenMP.cpp +++ b/lib/AST/StmtOpenMP.cpp @@ -522,23 +522,28 @@ OMPTaskwaitDirective *OMPTaskwaitDirective::CreateEmpty(const ASTContext &C, return new (Mem) OMPTaskwaitDirective(); } -OMPTaskgroupDirective *OMPTaskgroupDirective::Create(const ASTContext &C, - SourceLocation StartLoc, - SourceLocation EndLoc, - Stmt *AssociatedStmt) { - unsigned Size = llvm::alignTo(sizeof(OMPTaskgroupDirective), alignof(Stmt *)); +OMPTaskgroupDirective *OMPTaskgroupDirective::Create( + const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) { + unsigned Size = llvm::alignTo(sizeof(OMPTaskgroupDirective) + + sizeof(OMPClause *) * Clauses.size(), + alignof(Stmt *)); void *Mem = C.Allocate(Size + sizeof(Stmt *)); OMPTaskgroupDirective *Dir = - new (Mem) OMPTaskgroupDirective(StartLoc, EndLoc); + new (Mem) OMPTaskgroupDirective(StartLoc, EndLoc, Clauses.size()); Dir->setAssociatedStmt(AssociatedStmt); + Dir->setClauses(Clauses); return Dir; } OMPTaskgroupDirective *OMPTaskgroupDirective::CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell) { - unsigned Size = llvm::alignTo(sizeof(OMPTaskgroupDirective), alignof(Stmt *)); + unsigned Size = llvm::alignTo(sizeof(OMPTaskgroupDirective) + + sizeof(OMPClause *) * NumClauses, + alignof(Stmt *)); void *Mem = C.Allocate(Size + sizeof(Stmt *)); - return new (Mem) OMPTaskgroupDirective(); + return new (Mem) OMPTaskgroupDirective(NumClauses); } OMPCancellationPointDirective *OMPCancellationPointDirective::Create( diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 21f5259c3c..5ebaa32b49 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -836,6 +836,29 @@ void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause *Node) { } } +void OMPClausePrinter::VisitOMPTaskReductionClause( + OMPTaskReductionClause *Node) { + if (!Node->varlist_empty()) { + OS << "task_reduction("; + NestedNameSpecifier *QualifierLoc = + Node->getQualifierLoc().getNestedNameSpecifier(); + OverloadedOperatorKind OOK = + Node->getNameInfo().getName().getCXXOverloadedOperator(); + if (QualifierLoc == nullptr && OOK != OO_None) { + // Print reduction identifier in C format + OS << getOperatorSpelling(OOK); + } else { + // Use C++ format + if (QualifierLoc != nullptr) + QualifierLoc->print(OS, Policy); + OS << Node->getNameInfo(); + } + OS << ":"; + VisitOMPClauseList(Node, ' '); + OS << ")"; + } +} + void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) { if (!Node->varlist_empty()) { OS << "linear"; @@ -1081,7 +1104,7 @@ void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) { } void StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) { - Indent() << "#pragma omp taskgroup"; + Indent() << "#pragma omp taskgroup "; PrintOMPExecutableDirective(Node); } diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp index f1fbe2806b..e06386018d 100644 --- a/lib/AST/StmtProfile.cpp +++ b/lib/AST/StmtProfile.cpp @@ -549,6 +549,30 @@ void OMPClauseProfiler::VisitOMPReductionClause( Profiler->VisitStmt(E); } } +void OMPClauseProfiler::VisitOMPTaskReductionClause( + const OMPTaskReductionClause *C) { + Profiler->VisitNestedNameSpecifier( + C->getQualifierLoc().getNestedNameSpecifier()); + Profiler->VisitName(C->getNameInfo().getName()); + VisitOMPClauseList(C); + VistOMPClauseWithPostUpdate(C); + for (auto *E : C->privates()) { + if (E) + Profiler->VisitStmt(E); + } + for (auto *E : C->lhs_exprs()) { + if (E) + Profiler->VisitStmt(E); + } + for (auto *E : C->rhs_exprs()) { + if (E) + Profiler->VisitStmt(E); + } + for (auto *E : C->reduction_ops()) { + if (E) + Profiler->VisitStmt(E); + } +} void OMPClauseProfiler::VisitOMPLinearClause(const OMPLinearClause *C) { VisitOMPClauseList(C); VistOMPClauseWithPostUpdate(C); diff --git a/lib/Basic/OpenMPKinds.cpp b/lib/Basic/OpenMPKinds.cpp index 76a0e18c2d..050c0cc466 100644 --- a/lib/Basic/OpenMPKinds.cpp +++ b/lib/Basic/OpenMPKinds.cpp @@ -138,6 +138,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind, case OMPC_lastprivate: case OMPC_shared: case OMPC_reduction: + case OMPC_task_reduction: case OMPC_aligned: case OMPC_copyin: case OMPC_copyprivate: @@ -277,6 +278,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, case OMPC_lastprivate: case OMPC_shared: case OMPC_reduction: + case OMPC_task_reduction: case OMPC_aligned: case OMPC_copyin: case OMPC_copyprivate: @@ -710,6 +712,16 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, break; } break; + case OMPD_taskgroup: + switch (CKind) { +#define OPENMP_TASKGROUP_CLAUSE(Name) \ + case OMPC_##Name: \ + return true; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + break; case OMPD_declare_target: case OMPD_end_declare_target: case OMPD_unknown: @@ -719,7 +731,6 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind, case OMPD_taskyield: case OMPD_barrier: case OMPD_taskwait: - case OMPD_taskgroup: case OMPD_cancellation_point: case OMPD_declare_reduction: break; @@ -840,7 +851,8 @@ bool clang::isOpenMPDistributeDirective(OpenMPDirectiveKind Kind) { bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) { return Kind == OMPC_private || Kind == OMPC_firstprivate || Kind == OMPC_lastprivate || Kind == OMPC_linear || - Kind == OMPC_reduction; // TODO add next clauses like 'reduction'. + Kind == OMPC_reduction || + Kind == OMPC_task_reduction; // TODO add next clauses like 'reduction'. } bool clang::isOpenMPThreadPrivate(OpenMPClauseKind Kind) { diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp index ad4b6e5e11..6135cf31d1 100644 --- a/lib/CodeGen/CGStmtOpenMP.cpp +++ b/lib/CodeGen/CGStmtOpenMP.cpp @@ -3466,6 +3466,7 @@ static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind, case OMPC_firstprivate: case OMPC_lastprivate: case OMPC_reduction: + case OMPC_task_reduction: case OMPC_safelen: case OMPC_simdlen: case OMPC_collapse: diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp index 2e5e36242e..d9a088595a 100644 --- a/lib/Parse/ParseOpenMP.cpp +++ b/lib/Parse/ParseOpenMP.cpp @@ -1102,7 +1102,7 @@ bool Parser::ParseOpenMPSimpleVarList( /// simdlen-clause | threads-clause | simd-clause | num_teams-clause | /// thread_limit-clause | priority-clause | grainsize-clause | /// nogroup-clause | num_tasks-clause | hint-clause | to-clause | -/// from-clause | is_device_ptr-clause +/// from-clause | is_device_ptr-clause | task_reduction-clause /// OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, bool FirstClause) { @@ -1220,6 +1220,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, case OMPC_lastprivate: case OMPC_shared: case OMPC_reduction: + case OMPC_task_reduction: case OMPC_linear: case OMPC_aligned: case OMPC_copyin: @@ -1585,7 +1586,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, BalancedDelimiterTracker LinearT(*this, tok::l_paren, tok::annot_pragma_openmp_end); // Handle reduction-identifier for reduction clause. - if (Kind == OMPC_reduction) { + if (Kind == OMPC_reduction || Kind == OMPC_task_reduction) { ColonProtectionRAIIObject ColonRAII(*this); if (getLangOpts().CPlusPlus) ParseOptionalCXXScopeSpecifier(Data.ReductionIdScopeSpec, @@ -1733,13 +1734,13 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, Diag(Tok, diag::warn_pragma_expected_colon) << "map type"; } - bool IsComma = - (Kind != OMPC_reduction && Kind != OMPC_depend && Kind != OMPC_map) || - (Kind == OMPC_reduction && !InvalidReductionId) || - (Kind == OMPC_map && Data.MapType != OMPC_MAP_unknown && - (!MapTypeModifierSpecified || - Data.MapTypeModifier == OMPC_MAP_always)) || - (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown); + bool IsComma = (Kind != OMPC_reduction && Kind != OMPC_task_reduction && + Kind != OMPC_depend && Kind != OMPC_map) || + (Kind == OMPC_reduction && !InvalidReductionId) || + (Kind == OMPC_map && Data.MapType != OMPC_MAP_unknown && + (!MapTypeModifierSpecified || + Data.MapTypeModifier == OMPC_MAP_always)) || + (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown); const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned); while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) && Tok.isNot(tok::annot_pragma_openmp_end))) { @@ -1795,7 +1796,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, } /// \brief Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate', -/// 'shared', 'copyin', 'copyprivate', 'flush' or 'reduction'. +/// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction' or 'task_reduction'. /// /// private-clause: /// 'private' '(' list ')' @@ -1811,6 +1812,8 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, /// 'aligned' '(' list [ ':' alignment ] ')' /// reduction-clause: /// 'reduction' '(' reduction-identifier ':' list ')' +/// task_reduction-clause: +/// 'task_reduction' '(' reduction-identifier ':' list ')' /// copyprivate-clause: /// 'copyprivate' '(' list ')' /// flush-clause: diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index fda63f4c2e..01f574b6ae 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -2500,9 +2500,8 @@ StmtResult Sema::ActOnOpenMPExecutableDirective( Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); break; case OMPD_taskgroup: - assert(ClausesWithImplicit.empty() && - "No clauses are allowed for 'omp taskgroup' directive"); - Res = ActOnOpenMPTaskgroupDirective(AStmt, StartLoc, EndLoc); + Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, + EndLoc); break; case OMPD_flush: assert(AStmt == nullptr && @@ -5069,7 +5068,8 @@ StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); } -StmtResult Sema::ActOnOpenMPTaskgroupDirective(Stmt *AStmt, +StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, + Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { if (!AStmt) @@ -5079,7 +5079,8 @@ StmtResult Sema::ActOnOpenMPTaskgroupDirective(Stmt *AStmt, getCurFunction()->setHasBranchProtectedScope(); - return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, AStmt); + return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, + AStmt); } StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, @@ -6851,6 +6852,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, case OMPC_lastprivate: case OMPC_shared: case OMPC_reduction: + case OMPC_task_reduction: case OMPC_linear: case OMPC_aligned: case OMPC_copyin: @@ -7154,6 +7156,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( case OMPC_firstprivate: case OMPC_lastprivate: case OMPC_reduction: + case OMPC_task_reduction: case OMPC_linear: case OMPC_default: case OMPC_proc_bind: @@ -7469,6 +7472,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause( case OMPC_lastprivate: case OMPC_shared: case OMPC_reduction: + case OMPC_task_reduction: case OMPC_linear: case OMPC_aligned: case OMPC_copyin: @@ -7626,6 +7630,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( case OMPC_lastprivate: case OMPC_shared: case OMPC_reduction: + case OMPC_task_reduction: case OMPC_linear: case OMPC_aligned: case OMPC_copyin: @@ -7823,6 +7828,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, case OMPC_lastprivate: case OMPC_shared: case OMPC_reduction: + case OMPC_task_reduction: case OMPC_linear: case OMPC_aligned: case OMPC_copyin: @@ -7935,6 +7941,11 @@ OMPClause *Sema::ActOnOpenMPVarListClause( Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec, ReductionId); break; + case OMPC_task_reduction: + Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, + EndLoc, ReductionIdScopeSpec, + ReductionId); + break; case OMPC_linear: Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, LinKind, DepLinMapLoc, ColonLoc, EndLoc); @@ -8953,10 +8964,10 @@ struct ReductionData { } // namespace static bool ActOnOMPReductionKindClause( - Sema &S, DSAStackTy *Stack, ArrayRef<Expr *> VarList, - SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, - SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, - const DeclarationNameInfo &ReductionId, + Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, + ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation ColonLoc, SourceLocation EndLoc, + CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { auto DN = ReductionId.getName(); auto OOK = DN.getCXXOverloadedOperator(); @@ -9111,8 +9122,7 @@ static bool ActOnOMPReductionKindClause( // A list item that appears in a reduction clause must not be // const-qualified. if (Type.getNonReferenceType().isConstant(Context)) { - S.Diag(ELoc, diag::err_omp_const_reduction_list_item) - << getOpenMPClauseName(OMPC_reduction) << Type << ERange; + S.Diag(ELoc, diag::err_omp_const_reduction_list_item) << ERange; if (!ASE && !OASE) { bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; @@ -9130,7 +9140,8 @@ static bool ActOnOMPReductionKindClause( if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { DSARefChecker Check(Stack); if (Check.Visit(VDDef->getInit())) { - S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange; + S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) + << getOpenMPClauseName(ClauseKind) << ERange; S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; continue; } @@ -9152,7 +9163,7 @@ static bool ActOnOMPReductionKindClause( DVar = Stack->getTopDSA(D, false); if (DVar.CKind == OMPC_reduction) { S.Diag(ELoc, diag::err_omp_once_referenced) - << getOpenMPClauseName(OMPC_reduction); + << getOpenMPClauseName(ClauseKind); if (DVar.RefExpr) S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); } else if (DVar.CKind != OMPC_unknown) { @@ -9216,7 +9227,7 @@ static bool ActOnOMPReductionKindClause( !(Type->isScalarType() || (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) - << S.getLangOpts().CPlusPlus; + << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; if (!ASE && !OASE) { bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; @@ -9228,7 +9239,8 @@ static bool ActOnOMPReductionKindClause( } if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { - S.Diag(ELoc, diag::err_omp_clause_floating_type_arg); + S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) + << getOpenMPClauseName(ClauseKind); if (!ASE && !OASE) { bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; @@ -9481,6 +9493,8 @@ static bool ActOnOMPReductionKindClause( } } } + // All reduction items are still marked as reduction (to do not increase + // code base size). Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get()); } @@ -9494,9 +9508,10 @@ OMPClause *Sema::ActOnOpenMPReductionClause( ArrayRef<Expr *> UnresolvedReductions) { ReductionData RD(VarList.size()); - if (ActOnOMPReductionKindClause(*this, DSAStack, VarList, StartLoc, LParenLoc, - ColonLoc, EndLoc, ReductionIdScopeSpec, - ReductionId, UnresolvedReductions, RD)) + if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, + StartLoc, LParenLoc, ColonLoc, EndLoc, + ReductionIdScopeSpec, ReductionId, + UnresolvedReductions, RD)) return nullptr; return OMPReductionClause::Create( @@ -9507,6 +9522,27 @@ OMPClause *Sema::ActOnOpenMPReductionClause( buildPostUpdate(*this, RD.ExprPostUpdates)); } +OMPClause *Sema::ActOnOpenMPTaskReductionClause( + ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation ColonLoc, SourceLocation EndLoc, + CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, + ArrayRef<Expr *> UnresolvedReductions) { + ReductionData RD(VarList.size()); + + if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, + VarList, StartLoc, LParenLoc, ColonLoc, + EndLoc, ReductionIdScopeSpec, ReductionId, + UnresolvedReductions, RD)) + return nullptr; + + return OMPTaskReductionClause::Create( + Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, + ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, + RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, + buildPreInits(Context, RD.ExprCaptures), + buildPostUpdate(*this, RD.ExprPostUpdates)); +} + bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc) { if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 7aa8f64d50..91da9f88c5 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1651,6 +1651,21 @@ public: ReductionId, UnresolvedReductions); } + /// Build a new OpenMP 'task_reduction' clause. + /// + /// By default, performs semantic analysis to build the new statement. + /// Subclasses may override this routine to provide different behavior. + OMPClause *RebuildOMPTaskReductionClause( + ArrayRef<Expr *> VarList, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, + CXXScopeSpec &ReductionIdScopeSpec, + const DeclarationNameInfo &ReductionId, + ArrayRef<Expr *> UnresolvedReductions) { + return getSema().ActOnOpenMPTaskReductionClause( + VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec, + ReductionId, UnresolvedReductions); + } + /// \brief Build a new OpenMP 'linear' clause. /// /// By default, performs semantic analysis to build the new OpenMP clause. @@ -8400,6 +8415,51 @@ TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) { } template <typename Derived> +OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause( + OMPTaskReductionClause *C) { + llvm::SmallVector<Expr *, 16> Vars; + Vars.reserve(C->varlist_size()); + for (auto *VE : C->varlists()) { + ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); + if (EVar.isInvalid()) + return nullptr; + Vars.push_back(EVar.get()); + } + CXXScopeSpec ReductionIdScopeSpec; + ReductionIdScopeSpec.Adopt(C->getQualifierLoc()); + + DeclarationNameInfo NameInfo = C->getNameInfo(); + if (NameInfo.getName()) { + NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo); + if (!NameInfo.getName()) + return nullptr; + } + // Build a list of all UDR decls with the same names ranged by the Scopes. + // The Scope boundary is a duplication of the previous decl. + llvm::SmallVector<Expr *, 16> UnresolvedReductions; + for (auto *E : C->reduction_ops()) { + // Transform all the decls. + if (E) { + auto *ULE = cast<UnresolvedLookupExpr>(E); + UnresolvedSet<8> Decls; + for (auto *D : ULE->decls()) { + NamedDecl *InstD = + cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D)); + Decls.addDecl(InstD, InstD->getAccess()); + } + UnresolvedReductions.push_back(UnresolvedLookupExpr::Create( + SemaRef.Context, /*NamingClass=*/nullptr, + ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo, + /*ADL=*/true, ULE->isOverloaded(), Decls.begin(), Decls.end())); + } else + UnresolvedReductions.push_back(nullptr); + } + return getDerived().RebuildOMPTaskReductionClause( + Vars, C->getLocStart(), C->getLParenLoc(), C->getColonLoc(), + C->getLocEnd(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions); +} + +template <typename Derived> OMPClause * TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) { llvm::SmallVector<Expr *, 16> Vars; diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp index afee50ffa3..21adcddd3a 100644 --- a/lib/Serialization/ASTReaderStmt.cpp +++ b/lib/Serialization/ASTReaderStmt.cpp @@ -1834,6 +1834,9 @@ OMPClause *OMPClauseReader::readClause() { case OMPC_reduction: C = OMPReductionClause::CreateEmpty(Context, Reader->Record.readInt()); break; + case OMPC_task_reduction: + C = OMPTaskReductionClause::CreateEmpty(Context, Reader->Record.readInt()); + break; case OMPC_linear: C = OMPLinearClause::CreateEmpty(Context, Reader->Record.readInt()); break; @@ -2138,6 +2141,40 @@ void OMPClauseReader::VisitOMPReductionClause(OMPReductionClause *C) { C->setReductionOps(Vars); } +void OMPClauseReader::VisitOMPTaskReductionClause(OMPTaskReductionClause *C) { + VisitOMPClauseWithPostUpdate(C); + C->setLParenLoc(Reader->ReadSourceLocation()); + C->setColonLoc(Reader->ReadSourceLocation()); + NestedNameSpecifierLoc NNSL = Reader->Record.readNestedNameSpecifierLoc(); + DeclarationNameInfo DNI; + Reader->ReadDeclarationNameInfo(DNI); + C->setQualifierLoc(NNSL); + C->setNameInfo(DNI); + + unsigned NumVars = C->varlist_size(); + SmallVector<Expr *, 16> Vars; + Vars.reserve(NumVars); + for (unsigned I = 0; I != NumVars; ++I) + Vars.push_back(Reader->Record.readSubExpr()); + C->setVarRefs(Vars); + Vars.clear(); + for (unsigned I = 0; I != NumVars; ++I) + Vars.push_back(Reader->Record.readSubExpr()); + C->setPrivates(Vars); + Vars.clear(); + for (unsigned I = 0; I != NumVars; ++I) + Vars.push_back(Reader->Record.readSubExpr()); + C->setLHSExprs(Vars); + Vars.clear(); + for (unsigned I = 0; I != NumVars; ++I) + Vars.push_back(Reader->Record.readSubExpr()); + C->setRHSExprs(Vars); + Vars.clear(); + for (unsigned I = 0; I != NumVars; ++I) + Vars.push_back(Reader->Record.readSubExpr()); + C->setReductionOps(Vars); +} + void OMPClauseReader::VisitOMPLinearClause(OMPLinearClause *C) { VisitOMPClauseWithPostUpdate(C); C->setLParenLoc(Reader->ReadSourceLocation()); @@ -2709,6 +2746,8 @@ void ASTStmtReader::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) { void ASTStmtReader::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) { VisitStmt(D); + // The NumClauses field was read in ReadStmtFromStream. + Record.skipInts(1); VisitOMPExecutableDirective(D); } @@ -3479,7 +3518,8 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; case STMT_OMP_TASKGROUP_DIRECTIVE: - S = OMPTaskgroupDirective::CreateEmpty(Context, Empty); + S = OMPTaskgroupDirective::CreateEmpty( + Context, Record[ASTStmtReader::NumStmtFields], Empty); break; case STMT_OMP_FLUSH_DIRECTIVE: diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp index 90a732e575..ae2e0b88c3 100644 --- a/lib/Serialization/ASTWriterStmt.cpp +++ b/lib/Serialization/ASTWriterStmt.cpp @@ -1963,6 +1963,25 @@ void OMPClauseWriter::VisitOMPReductionClause(OMPReductionClause *C) { Record.AddStmt(E); } +void OMPClauseWriter::VisitOMPTaskReductionClause(OMPTaskReductionClause *C) { + Record.push_back(C->varlist_size()); + VisitOMPClauseWithPostUpdate(C); + Record.AddSourceLocation(C->getLParenLoc()); + Record.AddSourceLocation(C->getColonLoc()); + Record.AddNestedNameSpecifierLoc(C->getQualifierLoc()); + Record.AddDeclarationNameInfo(C->getNameInfo()); + for (auto *VE : C->varlists()) + Record.AddStmt(VE); + for (auto *VE : C->privates()) + Record.AddStmt(VE); + for (auto *E : C->lhs_exprs()) + Record.AddStmt(E); + for (auto *E : C->rhs_exprs()) + Record.AddStmt(E); + for (auto *E : C->reduction_ops()) + Record.AddStmt(E); +} + void OMPClauseWriter::VisitOMPLinearClause(OMPLinearClause *C) { Record.push_back(C->varlist_size()); VisitOMPClauseWithPostUpdate(C); @@ -2440,6 +2459,7 @@ void ASTStmtWriter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) { void ASTStmtWriter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) { VisitStmt(D); + Record.push_back(D->getNumClauses()); VisitOMPExecutableDirective(D); Code = serialization::STMT_OMP_TASKGROUP_DIRECTIVE; } |