diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-07-19 07:02:30 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-07-19 07:02:30 +0000 |
commit | de51d671486b6ac9a2ad9ee5fcfdb1a23cc59238 (patch) | |
tree | 17ff629bd1f00b82d8dbb66a022e2f59e218c3c2 /lib/Sema/SemaOpenMP.cpp | |
parent | 8746d127c04f5bbaf6c6e88cef8606ca5a6a54e9 (diff) |
Diffstat (limited to 'lib/Sema/SemaOpenMP.cpp')
-rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 350 |
1 files changed, 214 insertions, 136 deletions
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 1e0b6c158348f..01f574b6aeeb4 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -1807,6 +1807,8 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { std::make_pair(".lb.", KmpUInt64Ty), std::make_pair(".ub.", KmpUInt64Ty), std::make_pair(".st.", KmpInt64Ty), std::make_pair(".liter.", KmpInt32Ty), + std::make_pair(".reductions.", + Context.VoidPtrTy.withConst().withRestrict()), std::make_pair(StringRef(), QualType()) // __context with shared vars }; ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, @@ -2498,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 && @@ -5067,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) @@ -5077,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, @@ -6849,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: @@ -7152,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: @@ -7467,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: @@ -7624,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: @@ -7821,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: @@ -7933,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); @@ -8901,15 +8914,66 @@ buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, return ExprEmpty(); } -OMPClause *Sema::ActOnOpenMPReductionClause( +namespace { +/// Data for the reduction-based clauses. +struct ReductionData { + /// List of original reduction items. + SmallVector<Expr *, 8> Vars; + /// List of private copies of the reduction items. + SmallVector<Expr *, 8> Privates; + /// LHS expressions for the reduction_op expressions. + SmallVector<Expr *, 8> LHSs; + /// RHS expressions for the reduction_op expressions. + SmallVector<Expr *, 8> RHSs; + /// Reduction operation expression. + SmallVector<Expr *, 8> ReductionOps; + /// List of captures for clause. + SmallVector<Decl *, 4> ExprCaptures; + /// List of postupdate expressions. + SmallVector<Expr *, 4> ExprPostUpdates; + ReductionData() = delete; + /// Reserves required memory for the reduction data. + ReductionData(unsigned Size) { + Vars.reserve(Size); + Privates.reserve(Size); + LHSs.reserve(Size); + RHSs.reserve(Size); + ReductionOps.reserve(Size); + ExprCaptures.reserve(Size); + ExprPostUpdates.reserve(Size); + } + /// Stores reduction item and reduction operation only (required for dependent + /// reduction item). + void push(Expr *Item, Expr *ReductionOp) { + Vars.emplace_back(Item); + Privates.emplace_back(nullptr); + LHSs.emplace_back(nullptr); + RHSs.emplace_back(nullptr); + ReductionOps.emplace_back(ReductionOp); + } + /// Stores reduction data. + void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, + Expr *ReductionOp) { + Vars.emplace_back(Item); + Privates.emplace_back(Private); + LHSs.emplace_back(LHS); + RHSs.emplace_back(RHS); + ReductionOps.emplace_back(ReductionOp); + } +}; +} // namespace + +static bool ActOnOMPReductionKindClause( + 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) { + ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { auto DN = ReductionId.getName(); auto OOK = DN.getCXXOverloadedOperator(); BinaryOperatorKind BOK = BO_Comma; + ASTContext &Context = S.Context; // OpenMP [2.14.3.6, reduction clause] // C // reduction-identifier is either an identifier or one of the following @@ -8993,13 +9057,6 @@ OMPClause *Sema::ActOnOpenMPReductionClause( ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); ReductionIdRange.setEnd(ReductionId.getEndLoc()); - SmallVector<Expr *, 8> Vars; - SmallVector<Expr *, 8> Privates; - SmallVector<Expr *, 8> LHSs; - SmallVector<Expr *, 8> RHSs; - SmallVector<Expr *, 8> ReductionOps; - SmallVector<Decl *, 4> ExprCaptures; - SmallVector<Expr *, 4> ExprPostUpdates; auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); bool FirstIter = true; for (auto RefExpr : VarList) { @@ -9017,27 +9074,23 @@ OMPClause *Sema::ActOnOpenMPReductionClause( SourceLocation ELoc; SourceRange ERange; Expr *SimpleRefExpr = RefExpr; - auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, + auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, /*AllowArraySection=*/true); if (Res.second) { - // It will be analyzed later. - Vars.push_back(RefExpr); - Privates.push_back(nullptr); - LHSs.push_back(nullptr); - RHSs.push_back(nullptr); // Try to find 'declare reduction' corresponding construct before using // builtin/overloaded operators. QualType Type = Context.DependentTy; CXXCastPath BasePath; ExprResult DeclareReductionRef = buildDeclareReductionRef( - *this, ELoc, ERange, DSAStack->getCurScope(), ReductionIdScopeSpec, + S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); - if (CurContext->isDependentContext() && + Expr *ReductionOp = nullptr; + if (S.CurContext->isDependentContext() && (DeclareReductionRef.isUnset() || isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) - ReductionOps.push_back(DeclareReductionRef.get()); - else - ReductionOps.push_back(nullptr); + ReductionOp = DeclareReductionRef.get(); + // It will be analyzed later. + RD.push(RefExpr, ReductionOp); } ValueDecl *D = Res.first; if (!D) @@ -9062,21 +9115,19 @@ OMPClause *Sema::ActOnOpenMPReductionClause( // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] // A variable that appears in a private clause must not have an incomplete // type or a reference type. - if (RequireCompleteType(ELoc, Type, - diag::err_omp_reduction_incomplete_type)) + if (S.RequireCompleteType(ELoc, Type, + diag::err_omp_reduction_incomplete_type)) continue; // OpenMP [2.14.3.6, reduction clause, Restrictions] // A list item that appears in a reduction clause must not be // const-qualified. if (Type.getNonReferenceType().isConstant(Context)) { - 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; - Diag(D->getLocation(), - IsDecl ? diag::note_previous_decl : diag::note_defined_here) + bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == + VarDecl::DeclarationOnly; + S.Diag(D->getLocation(), + IsDecl ? diag::note_previous_decl : diag::note_defined_here) << D; } continue; @@ -9087,10 +9138,11 @@ OMPClause *Sema::ActOnOpenMPReductionClause( if (!ASE && !OASE && VD) { VarDecl *VDDef = VD->getDefinition(); if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { - DSARefChecker Check(DSAStack); + DSARefChecker Check(Stack); if (Check.Visit(VDDef->getInit())) { - Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange; - Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; + S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) + << getOpenMPClauseName(ClauseKind) << ERange; + S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; continue; } } @@ -9108,17 +9160,17 @@ OMPClause *Sema::ActOnOpenMPReductionClause( // but a list item can appear only once in the reduction clauses for that // directive. DSAStackTy::DSAVarData DVar; - DVar = DSAStack->getTopDSA(D, false); + DVar = Stack->getTopDSA(D, false); if (DVar.CKind == OMPC_reduction) { - Diag(ELoc, diag::err_omp_once_referenced) - << getOpenMPClauseName(OMPC_reduction); + S.Diag(ELoc, diag::err_omp_once_referenced) + << getOpenMPClauseName(ClauseKind); if (DVar.RefExpr) - Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); + S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); } else if (DVar.CKind != OMPC_unknown) { - Diag(ELoc, diag::err_omp_wrong_dsa) + S.Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) << getOpenMPClauseName(OMPC_reduction); - ReportOriginalDSA(*this, DSAStack, D, DVar); + ReportOriginalDSA(S, Stack, D, DVar); continue; } @@ -9126,16 +9178,16 @@ OMPClause *Sema::ActOnOpenMPReductionClause( // A list item that appears in a reduction clause of a worksharing // construct must be shared in the parallel regions to which any of the // worksharing regions arising from the worksharing construct bind. - OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); + OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); if (isOpenMPWorksharingDirective(CurrDir) && !isOpenMPParallelDirective(CurrDir) && !isOpenMPTeamsDirective(CurrDir)) { - DVar = DSAStack->getImplicitDSA(D, true); + DVar = Stack->getImplicitDSA(D, true); if (DVar.CKind != OMPC_shared) { - Diag(ELoc, diag::err_omp_required_access) + S.Diag(ELoc, diag::err_omp_required_access) << getOpenMPClauseName(OMPC_reduction) << getOpenMPClauseName(OMPC_shared); - ReportOriginalDSA(*this, DSAStack, D, DVar); + ReportOriginalDSA(S, Stack, D, DVar); continue; } } @@ -9144,24 +9196,20 @@ OMPClause *Sema::ActOnOpenMPReductionClause( // builtin/overloaded operators. CXXCastPath BasePath; ExprResult DeclareReductionRef = buildDeclareReductionRef( - *this, ELoc, ERange, DSAStack->getCurScope(), ReductionIdScopeSpec, + S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); if (DeclareReductionRef.isInvalid()) continue; - if (CurContext->isDependentContext() && + if (S.CurContext->isDependentContext() && (DeclareReductionRef.isUnset() || isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { - Vars.push_back(RefExpr); - Privates.push_back(nullptr); - LHSs.push_back(nullptr); - RHSs.push_back(nullptr); - ReductionOps.push_back(DeclareReductionRef.get()); + RD.push(RefExpr, DeclareReductionRef.get()); continue; } if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { // Not allowed reduction identifier is found. - Diag(ReductionId.getLocStart(), - diag::err_omp_unknown_reduction_identifier) + S.Diag(ReductionId.getLocStart(), + diag::err_omp_unknown_reduction_identifier) << Type << ReductionIdRange; continue; } @@ -9177,28 +9225,27 @@ OMPClause *Sema::ActOnOpenMPReductionClause( if (DeclareReductionRef.isUnset()) { if ((BOK == BO_GT || BOK == BO_LT) && !(Type->isScalarType() || - (getLangOpts().CPlusPlus && Type->isArithmeticType()))) { - Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) - << getLangOpts().CPlusPlus; + (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { + S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) + << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; if (!ASE && !OASE) { - bool IsDecl = !VD || - VD->isThisDeclarationADefinition(Context) == - VarDecl::DeclarationOnly; - Diag(D->getLocation(), - IsDecl ? diag::note_previous_decl : diag::note_defined_here) + bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == + VarDecl::DeclarationOnly; + S.Diag(D->getLocation(), + IsDecl ? diag::note_previous_decl : diag::note_defined_here) << D; } continue; } if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && - !getLangOpts().CPlusPlus && Type->isFloatingType()) { - Diag(ELoc, diag::err_omp_clause_floating_type_arg); + !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { + S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) + << getOpenMPClauseName(ClauseKind); if (!ASE && !OASE) { - bool IsDecl = !VD || - VD->isThisDeclarationADefinition(Context) == - VarDecl::DeclarationOnly; - Diag(D->getLocation(), - IsDecl ? diag::note_previous_decl : diag::note_defined_here) + bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == + VarDecl::DeclarationOnly; + S.Diag(D->getLocation(), + IsDecl ? diag::note_previous_decl : diag::note_defined_here) << D; } continue; @@ -9206,9 +9253,9 @@ OMPClause *Sema::ActOnOpenMPReductionClause( } Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); - auto *LHSVD = buildVarDecl(*this, ELoc, Type, ".reduction.lhs", + auto *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", D->hasAttrs() ? &D->getAttrs() : nullptr); - auto *RHSVD = buildVarDecl(*this, ELoc, Type, D->getName(), + auto *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), D->hasAttrs() ? &D->getAttrs() : nullptr); auto PrivateTy = Type; if (OASE || @@ -9220,19 +9267,20 @@ OMPClause *Sema::ActOnOpenMPReductionClause( // For array subscripts or single variables Private Ty is the same as Type // (type of the variable or single array element). PrivateTy = Context.getVariableArrayType( - Type, new (Context) OpaqueValueExpr(SourceLocation(), - Context.getSizeType(), VK_RValue), + Type, + new (Context) OpaqueValueExpr(SourceLocation(), Context.getSizeType(), + VK_RValue), ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); } else if (!ASE && !OASE && Context.getAsArrayType(D->getType().getNonReferenceType())) PrivateTy = D->getType().getNonReferenceType(); // Private copy. - auto *PrivateVD = buildVarDecl(*this, ELoc, PrivateTy, D->getName(), + auto *PrivateVD = buildVarDecl(S, ELoc, PrivateTy, D->getName(), D->hasAttrs() ? &D->getAttrs() : nullptr); // Add initializer for private variable. Expr *Init = nullptr; - auto *LHSDRE = buildDeclRefExpr(*this, LHSVD, Type, ELoc); - auto *RHSDRE = buildDeclRefExpr(*this, RHSVD, Type, ELoc); + auto *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); + auto *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); if (DeclareReductionRef.isUsable()) { auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); @@ -9249,13 +9297,13 @@ OMPClause *Sema::ActOnOpenMPReductionClause( case BO_LOr: // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. if (Type->isScalarType() || Type->isAnyComplexType()) - Init = ActOnIntegerConstant(ELoc, /*Val=*/0).get(); + Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); break; case BO_Mul: case BO_LAnd: if (Type->isScalarType() || Type->isAnyComplexType()) { // '*' and '&&' reduction ops - initializer is '1'. - Init = ActOnIntegerConstant(ELoc, /*Val=*/1).get(); + Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); } break; case BO_And: { @@ -9278,7 +9326,7 @@ OMPClause *Sema::ActOnOpenMPReductionClause( if (Init && OrigType->isAnyComplexType()) { // Init = 0xFFFF + 0xFFFFi; auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); - Init = CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); + Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); } Type = OrigType; break; @@ -9295,15 +9343,14 @@ OMPClause *Sema::ActOnOpenMPReductionClause( QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); llvm::APInt InitValue = - (BOK != BO_LT) - ? IsSigned ? llvm::APInt::getSignedMinValue(Size) - : llvm::APInt::getMinValue(Size) - : IsSigned ? llvm::APInt::getSignedMaxValue(Size) - : llvm::APInt::getMaxValue(Size); + (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) + : llvm::APInt::getMinValue(Size) + : IsSigned ? llvm::APInt::getSignedMaxValue(Size) + : llvm::APInt::getMaxValue(Size); Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); if (Type->isPointerType()) { // Cast to pointer type. - auto CastExpr = BuildCStyleCastExpr( + auto CastExpr = S.BuildCStyleCastExpr( SourceLocation(), Context.getTrivialTypeSourceInfo(Type, ELoc), SourceLocation(), Init); if (CastExpr.isInvalid()) @@ -9344,20 +9391,19 @@ OMPClause *Sema::ActOnOpenMPReductionClause( llvm_unreachable("Unexpected reduction operation"); } } - if (Init && DeclareReductionRef.isUnset()) { - AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); - } else if (!Init) - ActOnUninitializedDecl(RHSVD); + if (Init && DeclareReductionRef.isUnset()) + S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); + else if (!Init) + S.ActOnUninitializedDecl(RHSVD); if (RHSVD->isInvalidDecl()) continue; if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { - Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type - << ReductionIdRange; - bool IsDecl = - !VD || - VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; - Diag(D->getLocation(), - IsDecl ? diag::note_previous_decl : diag::note_defined_here) + S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) + << Type << ReductionIdRange; + bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == + VarDecl::DeclarationOnly; + S.Diag(D->getLocation(), + IsDecl ? diag::note_previous_decl : diag::note_defined_here) << D; continue; } @@ -9365,16 +9411,16 @@ OMPClause *Sema::ActOnOpenMPReductionClause( // codegen. PrivateVD->setInit(RHSVD->getInit()); PrivateVD->setInitStyle(RHSVD->getInitStyle()); - auto *PrivateDRE = buildDeclRefExpr(*this, PrivateVD, PrivateTy, ELoc); + auto *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); ExprResult ReductionOp; if (DeclareReductionRef.isUsable()) { QualType RedTy = DeclareReductionRef.get()->getType(); QualType PtrRedTy = Context.getPointerType(RedTy); - ExprResult LHS = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); - ExprResult RHS = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); + ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); + ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); if (!BasePath.empty()) { - LHS = DefaultLvalueConversion(LHS.get()); - RHS = DefaultLvalueConversion(RHS.get()); + LHS = S.DefaultLvalueConversion(LHS.get()); + RHS = S.DefaultLvalueConversion(RHS.get()); LHS = ImplicitCastExpr::Create(Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath, LHS.get()->getValueKind()); @@ -9387,27 +9433,27 @@ OMPClause *Sema::ActOnOpenMPReductionClause( QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); auto *OVE = new (Context) OpaqueValueExpr( ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, - DefaultLvalueConversion(DeclareReductionRef.get()).get()); + S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); Expr *Args[] = {LHS.get(), RHS.get()}; ReductionOp = new (Context) CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); } else { - ReductionOp = BuildBinOp(DSAStack->getCurScope(), - ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE); + ReductionOp = S.BuildBinOp( + Stack->getCurScope(), ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE); if (ReductionOp.isUsable()) { if (BOK != BO_LT && BOK != BO_GT) { ReductionOp = - BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), - BO_Assign, LHSDRE, ReductionOp.get()); + S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(), + BO_Assign, LHSDRE, ReductionOp.get()); } else { auto *ConditionalOp = new (Context) ConditionalOperator( ReductionOp.get(), SourceLocation(), LHSDRE, SourceLocation(), RHSDRE, Type, VK_LValue, OK_Ordinary); ReductionOp = - BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), - BO_Assign, LHSDRE, ConditionalOp); + S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(), + BO_Assign, LHSDRE, ConditionalOp); } - ReductionOp = ActOnFinishFullExpr(ReductionOp.get()); + ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get()); } if (ReductionOp.isInvalid()) continue; @@ -9415,54 +9461,86 @@ OMPClause *Sema::ActOnOpenMPReductionClause( DeclRefExpr *Ref = nullptr; Expr *VarsExpr = RefExpr->IgnoreParens(); - if (!VD && !CurContext->isDependentContext()) { + if (!VD && !S.CurContext->isDependentContext()) { if (ASE || OASE) { - TransformExprToCaptures RebuildToCapture(*this, D); + TransformExprToCaptures RebuildToCapture(S, D); VarsExpr = RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); Ref = RebuildToCapture.getCapturedExpr(); } else { - VarsExpr = Ref = - buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); + VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); } - if (!IsOpenMPCapturedDecl(D)) { - ExprCaptures.push_back(Ref->getDecl()); + if (!S.IsOpenMPCapturedDecl(D)) { + RD.ExprCaptures.emplace_back(Ref->getDecl()); if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { - ExprResult RefRes = DefaultLvalueConversion(Ref); + ExprResult RefRes = S.DefaultLvalueConversion(Ref); if (!RefRes.isUsable()) continue; ExprResult PostUpdateRes = - BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, - SimpleRefExpr, RefRes.get()); + S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, + RefRes.get()); if (!PostUpdateRes.isUsable()) continue; - if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { - Diag(RefExpr->getExprLoc(), - diag::err_omp_reduction_non_addressable_expression) + if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || + Stack->getCurrentDirective() == OMPD_taskgroup) { + S.Diag(RefExpr->getExprLoc(), + diag::err_omp_reduction_non_addressable_expression) << RefExpr->getSourceRange(); continue; } - ExprPostUpdates.push_back( - IgnoredValueConversions(PostUpdateRes.get()).get()); + RD.ExprPostUpdates.emplace_back( + S.IgnoredValueConversions(PostUpdateRes.get()).get()); } } } - DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); - Vars.push_back(VarsExpr); - Privates.push_back(PrivateDRE); - LHSs.push_back(LHSDRE); - RHSs.push_back(RHSDRE); - ReductionOps.push_back(ReductionOp.get()); + // 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()); } + return RD.Vars.empty(); +} - if (Vars.empty()) +OMPClause *Sema::ActOnOpenMPReductionClause( + 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_reduction, VarList, + StartLoc, LParenLoc, ColonLoc, EndLoc, + ReductionIdScopeSpec, ReductionId, + UnresolvedReductions, RD)) return nullptr; return OMPReductionClause::Create( - Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars, - ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, Privates, - LHSs, RHSs, ReductionOps, buildPreInits(Context, ExprCaptures), - buildPostUpdate(*this, ExprPostUpdates)); + 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)); +} + +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, |