diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h index 2238e3483b91882926840afa46f1367117ccda5a..5161eff0993b4db8cb8fbfdd53761cc52c9b083b 100644 --- a/include/clang/AST/StmtOpenMP.h +++ b/include/clang/AST/StmtOpenMP.h @@ -108,7 +108,7 @@ public: typedef const OMPClause *value_type; filtered_clause_iterator() : Current(), End() {} filtered_clause_iterator(ArrayRef<OMPClause *> Arr, FilterPredicate Pred) - : Current(Arr.begin()), End(Arr.end()), Pred(Pred) { + : Current(Arr.begin()), End(Arr.end()), Pred(std::move(Pred)) { SkipToNextClause(); } value_type operator*() const { return *Current; } @@ -126,29 +126,24 @@ public: } bool operator!() { return Current == End; } - operator bool() { return Current != End; } + explicit operator bool() { return Current != End; } bool empty() const { return Current == End; } }; - /// \brief A filter to iterate over 'linear' clauses using a C++ range - /// for loop. - struct linear_filter : public filtered_clause_iterator< - std::function<bool(const OMPClause *)> > { - linear_filter(ArrayRef<OMPClause *> Arr) - : filtered_clause_iterator(Arr, [](const OMPClause *C)->bool { - return C->getClauseKind() == OMPC_linear; - }) {} - const OMPLinearClause *operator*() const { - return cast<OMPLinearClause>(*Current); - } - const OMPLinearClause *operator->() const { - return cast<OMPLinearClause>(*Current); - } - friend linear_filter begin(const linear_filter &range) { return range; } - friend linear_filter end(const linear_filter &range) { - return linear_filter(ArrayRef<OMPClause *>(range.End, range.End)); + template <typename Fn> + filtered_clause_iterator<Fn> getFilteredClauses(Fn &&fn) const { + return filtered_clause_iterator<Fn>(clauses(), std::move(fn)); + } + struct ClauseKindFilter { + OpenMPClauseKind Kind; + bool operator()(const OMPClause *clause) const { + return clause->getClauseKind() == Kind; } }; + filtered_clause_iterator<ClauseKindFilter> + getClausesOfKind(OpenMPClauseKind Kind) const { + return getFilteredClauses(ClauseKindFilter{Kind}); + } /// \brief Gets a single clause of the specified kind \a K associated with the /// current directive iff there is only one clause of this kind (and assertion diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index 0e8652f82a5b2987f32fdd5566bd4e6fcf57f4cf..6baa99bbc5bf94f536ec46d4f1a97924b3918040 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -1581,10 +1581,7 @@ OMPFlushClause *OMPFlushClause::CreateEmpty(const ASTContext &C, unsigned N) { const OMPClause * OMPExecutableDirective::getSingleClause(OpenMPClauseKind K) const { - auto ClauseFilter = - [=](const OMPClause *C) -> bool { return C->getClauseKind() == K; }; - OMPExecutableDirective::filtered_clause_iterator<decltype(ClauseFilter)> I( - clauses(), ClauseFilter); + auto &&I = getClausesOfKind(K); if (I) { auto *Clause = *I; diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp index a31d6bcb484e7306471b02f33390f55d8ac04b70..e445e7668ee493dfe0003e4dd00320eb58ec1090 100644 --- a/lib/CodeGen/CGStmtOpenMP.cpp +++ b/lib/CodeGen/CGStmtOpenMP.cpp @@ -114,13 +114,8 @@ void CodeGenFunction::EmitOMPCopy(CodeGenFunction &CGF, bool CodeGenFunction::EmitOMPFirstprivateClause(const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope) { - auto FirstprivateFilter = [](const OMPClause *C) -> bool { - return C->getClauseKind() == OMPC_firstprivate; - }; llvm::DenseSet<const VarDecl *> EmittedAsFirstprivate; - for (OMPExecutableDirective::filtered_clause_iterator<decltype( - FirstprivateFilter)> I(D.clauses(), FirstprivateFilter); - I; ++I) { + for (auto &&I = D.getClausesOfKind(OMPC_firstprivate); I; ++I) { auto *C = cast<OMPFirstprivateClause>(*I); auto IRef = C->varlist_begin(); auto InitsRef = C->inits().begin(); @@ -193,13 +188,8 @@ bool CodeGenFunction::EmitOMPFirstprivateClause(const OMPExecutableDirective &D, void CodeGenFunction::EmitOMPPrivateClause( const OMPExecutableDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope) { - auto PrivateFilter = [](const OMPClause *C) -> bool { - return C->getClauseKind() == OMPC_private; - }; llvm::DenseSet<const VarDecl *> EmittedAsPrivate; - for (OMPExecutableDirective::filtered_clause_iterator<decltype(PrivateFilter)> - I(D.clauses(), PrivateFilter); - I; ++I) { + for (auto &&I = D.getClausesOfKind(OMPC_private); I; ++I) { auto *C = cast<OMPPrivateClause>(*I); auto IRef = C->varlist_begin(); for (auto IInit : C->private_copies()) { @@ -226,14 +216,9 @@ bool CodeGenFunction::EmitOMPCopyinClause(const OMPExecutableDirective &D) { // operator=(threadprivate_var2, master_threadprivate_var2); // ... // __kmpc_barrier(&loc, global_tid); - auto CopyinFilter = [](const OMPClause *C) -> bool { - return C->getClauseKind() == OMPC_copyin; - }; llvm::DenseSet<const VarDecl *> CopiedVars; llvm::BasicBlock *CopyBegin = nullptr, *CopyEnd = nullptr; - for (OMPExecutableDirective::filtered_clause_iterator<decltype(CopyinFilter)> - I(D.clauses(), CopyinFilter); - I; ++I) { + for (auto &&I = D.getClausesOfKind(OMPC_copyin); I; ++I) { auto *C = cast<OMPCopyinClause>(*I); auto IRef = C->varlist_begin(); auto ISrcRef = C->source_exprs().begin(); @@ -279,14 +264,9 @@ bool CodeGenFunction::EmitOMPCopyinClause(const OMPExecutableDirective &D) { bool CodeGenFunction::EmitOMPLastprivateClauseInit( const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope) { - auto LastprivateFilter = [](const OMPClause *C) -> bool { - return C->getClauseKind() == OMPC_lastprivate; - }; bool HasAtLeastOneLastprivate = false; llvm::DenseSet<const VarDecl *> AlreadyEmittedVars; - for (OMPExecutableDirective::filtered_clause_iterator<decltype( - LastprivateFilter)> I(D.clauses(), LastprivateFilter); - I; ++I) { + for (auto &&I = D.getClausesOfKind(OMPC_lastprivate); I; ++I) { auto *C = cast<OMPLastprivateClause>(*I); auto IRef = C->varlist_begin(); auto IDestRef = C->destination_exprs().begin(); @@ -338,13 +318,8 @@ void CodeGenFunction::EmitOMPLastprivateClauseFinal( Builder.CreateCondBr(IsLastIterCond, ThenBB, DoneBB); EmitBlock(ThenBB); { - auto LastprivateFilter = [](const OMPClause *C) -> bool { - return C->getClauseKind() == OMPC_lastprivate; - }; llvm::DenseSet<const VarDecl *> AlreadyEmittedVars; - for (OMPExecutableDirective::filtered_clause_iterator<decltype( - LastprivateFilter)> I(D.clauses(), LastprivateFilter); - I; ++I) { + for (auto &&I = D.getClausesOfKind(OMPC_lastprivate); I; ++I) { auto *C = cast<OMPLastprivateClause>(*I); auto IRef = C->varlist_begin(); auto ISrcRef = C->source_exprs().begin(); @@ -373,12 +348,7 @@ void CodeGenFunction::EmitOMPLastprivateClauseFinal( void CodeGenFunction::EmitOMPReductionClauseInit( const OMPExecutableDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope) { - auto ReductionFilter = [](const OMPClause *C) -> bool { - return C->getClauseKind() == OMPC_reduction; - }; - for (OMPExecutableDirective::filtered_clause_iterator<decltype( - ReductionFilter)> I(D.clauses(), ReductionFilter); - I; ++I) { + for (auto &&I = D.getClausesOfKind(OMPC_reduction); I; ++I) { auto *C = cast<OMPReductionClause>(*I); auto ILHS = C->lhs_exprs().begin(); auto IRHS = C->rhs_exprs().begin(); @@ -414,13 +384,8 @@ void CodeGenFunction::EmitOMPReductionClauseFinal( llvm::SmallVector<const Expr *, 8> LHSExprs; llvm::SmallVector<const Expr *, 8> RHSExprs; llvm::SmallVector<const Expr *, 8> ReductionOps; - auto ReductionFilter = [](const OMPClause *C) -> bool { - return C->getClauseKind() == OMPC_reduction; - }; bool HasAtLeastOneReduction = false; - for (OMPExecutableDirective::filtered_clause_iterator<decltype( - ReductionFilter)> I(D.clauses(), ReductionFilter); - I; ++I) { + for (auto &&I = D.getClausesOfKind(OMPC_reduction); I; ++I) { HasAtLeastOneReduction = true; auto *C = cast<OMPReductionClause>(*I); LHSExprs.append(C->lhs_exprs().begin(), C->lhs_exprs().end()); @@ -495,7 +460,8 @@ void CodeGenFunction::EmitOMPLoopBody(const OMPLoopDirective &S, EmitIgnoredExpr(I); } // Update the linear variables. - for (auto C : OMPExecutableDirective::linear_filter(S.clauses())) { + for (auto &&I = S.getClausesOfKind(OMPC_linear); I; ++I) { + auto *C = cast<OMPLinearClause>(*I); for (auto U : C->updates()) { EmitIgnoredExpr(U); } @@ -573,7 +539,8 @@ void CodeGenFunction::EmitOMPSimdFinal(const OMPLoopDirective &S) { ++IC; } // Emit the final values of the linear variables. - for (auto C : OMPExecutableDirective::linear_filter(S.clauses())) { + for (auto &&I = S.getClausesOfKind(OMPC_linear); I; ++I) { + auto *C = cast<OMPLinearClause>(*I); for (auto F : C->finals()) { EmitIgnoredExpr(F); } @@ -658,8 +625,9 @@ static void emitPreCond(CodeGenFunction &CGF, const OMPLoopDirective &S, static void EmitPrivateLinearVars(CodeGenFunction &CGF, const OMPExecutableDirective &D, CodeGenFunction::OMPPrivateScope &PrivateScope) { - for (auto Clause : OMPExecutableDirective::linear_filter(D.clauses())) { - for (auto *E : Clause->varlists()) { + for (auto &&I = D.getClausesOfKind(OMPC_linear); I; ++I) { + auto *C = cast<OMPLinearClause>(*I); + for (auto *E : C->varlists()) { auto VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); bool IsRegistered = PrivateScope.addPrivate(VD, [&]()->llvm::Value * { // Emit var without initialization. @@ -739,7 +707,8 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { } // Emit inits for the linear variables. - for (auto C : OMPExecutableDirective::linear_filter(S.clauses())) { + for (auto &&I = S.getClausesOfKind(OMPC_linear); I; ++I) { + auto *C = cast<OMPLinearClause>(*I); for (auto Init : C->inits()) { auto *D = cast<VarDecl>(cast<DeclRefExpr>(Init)->getDecl()); CGF.EmitVarDecl(*D); @@ -764,7 +733,8 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { // Emit the linear steps for the linear clauses. // If a step is not constant, it is pre-calculated before the loop. - for (auto C : OMPExecutableDirective::linear_filter(S.clauses())) { + for (auto &&I = S.getClausesOfKind(OMPC_linear); I; ++I) { + auto *C = cast<OMPLinearClause>(*I); if (auto CS = cast_or_null<BinaryOperator>(C->getCalcStep())) if (auto SaveRef = cast<DeclRefExpr>(CS->getLHS())) { CGF.EmitVarDecl(*cast<VarDecl>(SaveRef->getDecl())); @@ -1221,21 +1191,11 @@ static OpenMPDirectiveKind emitSections(CodeGenFunction &CGF, bool HasFirstprivates; // No need to generate reductions for sections with single section region, we // can use original shared variables for all operations. - auto ReductionFilter = [](const OMPClause *C) -> bool { - return C->getClauseKind() == OMPC_reduction; - }; - OMPExecutableDirective::filtered_clause_iterator<decltype(ReductionFilter)> I( - S.clauses(), ReductionFilter); - bool HasReductions = I; + bool HasReductions = !S.getClausesOfKind(OMPC_reduction).empty(); // No need to generate lastprivates for sections with single section region, // we can use original shared variable for all calculations with barrier at // the end of the sections. - auto LastprivateFilter = [](const OMPClause *C) -> bool { - return C->getClauseKind() == OMPC_lastprivate; - }; - OMPExecutableDirective::filtered_clause_iterator<decltype(LastprivateFilter)> - I1(S.clauses(), LastprivateFilter); - bool HasLastprivates = I1; + bool HasLastprivates = !S.getClausesOfKind(OMPC_lastprivate).empty(); auto &&CodeGen = [Stmt, &S, &HasFirstprivates](CodeGenFunction &CGF) { CodeGenFunction::OMPPrivateScope SingleScope(CGF); HasFirstprivates = CGF.EmitOMPFirstprivateClause(S, SingleScope); @@ -1287,14 +1247,9 @@ void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) { // Check if there are any 'copyprivate' clauses associated with this // 'single' // construct. - auto CopyprivateFilter = [](const OMPClause *C) -> bool { - return C->getClauseKind() == OMPC_copyprivate; - }; // Build a list of copyprivate variables along with helper expressions // (<source>, <destination>, <destination>=<source> expressions) - typedef OMPExecutableDirective::filtered_clause_iterator<decltype( - CopyprivateFilter)> CopyprivateIter; - for (CopyprivateIter I(S.clauses(), CopyprivateFilter); I; ++I) { + for (auto &&I = S.getClausesOfKind(OMPC_copyprivate); I; ++I) { auto *C = cast<OMPCopyprivateClause>(*I); CopyprivateVars.append(C->varlists().begin(), C->varlists().end()); DestExprs.append(C->destination_exprs().begin(), diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index a968f30247aac45b782943ea700d895f11e57949..06b9d56cdc76f870fcd7771f5a3955adbf6f0cec 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -2997,11 +2997,11 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr, } static Expr *GetCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { - auto CollapseFilter = [](const OMPClause *C) -> bool { + auto &&CollapseFilter = [](const OMPClause *C) -> bool { return C->getClauseKind() == OMPC_collapse; }; OMPExecutableDirective::filtered_clause_iterator<decltype(CollapseFilter)> I( - Clauses, CollapseFilter); + Clauses, std::move(CollapseFilter)); if (I) return cast<OMPCollapseClause>(*I)->getNumForLoops(); return nullptr;