On Mon, Aug 31, 2015 at 9:48 AM, Benjamin Kramer <benny....@gmail.com> wrote:
> > > On Mon, Aug 31, 2015 at 5:12 PM, David Blaikie <dblai...@gmail.com> wrote: > >> Any chance this would be improved/further simplified by basing it on the >> adapter_iterator helper in LLVM's STL Utilities? >> > > Fair enough, r246452. I was a bit nervous because this iterator overrides > operator++ but iterator_adaptor_base seems to be doing the right thing even > when ++ is overridden. > Neat - thanks a bunch! :D > > - Ben > > >> On Sun, Aug 30, 2015 at 8:12 AM, Benjamin Kramer via cfe-commits < >> cfe-commits@lists.llvm.org> wrote: >> >>> Author: d0k >>> Date: Sun Aug 30 10:12:28 2015 >>> New Revision: 246384 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=246384&view=rev >>> Log: >>> [OpenMP] Make the filetered clause iterator a real iterator and type >>> safe. >>> >>> This replaces the filtered generic iterator with a type-specfic one based >>> on dyn_cast instead of comparing the kind enum. This allows us to use >>> range-based for loops and eliminates casts. No functionality change >>> intended. >>> >>> Modified: >>> cfe/trunk/include/clang/AST/StmtOpenMP.h >>> cfe/trunk/lib/AST/Stmt.cpp >>> cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp >>> cfe/trunk/lib/Sema/SemaOpenMP.cpp >>> >>> Modified: cfe/trunk/include/clang/AST/StmtOpenMP.h >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtOpenMP.h?rev=246384&r1=246383&r2=246384&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/include/clang/AST/StmtOpenMP.h (original) >>> +++ cfe/trunk/include/clang/AST/StmtOpenMP.h Sun Aug 30 10:12:28 2015 >>> @@ -92,65 +92,91 @@ public: >>> /// \brief Iterates over a filtered subrange of clauses applied to a >>> /// directive. >>> /// >>> - /// This iterator visits only those declarations that meet some >>> run-time >>> - /// criteria. >>> - template <class FilterPredicate> class filtered_clause_iterator { >>> - protected: >>> + /// This iterator visits only clauses of type SpecificClause. >>> + template <typename SpecificClause> >>> + class specific_clause_iterator >>> + : public std::iterator<std::forward_iterator_tag, const >>> SpecificClause *, >>> + ptrdiff_t, const SpecificClause *, >>> + const SpecificClause *> { >>> ArrayRef<OMPClause *>::const_iterator Current; >>> ArrayRef<OMPClause *>::const_iterator End; >>> - FilterPredicate Pred; >>> + >>> void SkipToNextClause() { >>> - while (Current != End && !Pred(*Current)) >>> + while (Current != End && !isa<SpecificClause>(*Current)) >>> ++Current; >>> } >>> >>> 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(std::move(Pred)) { >>> + explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses) >>> + : Current(Clauses.begin()), End(Clauses.end()) { >>> SkipToNextClause(); >>> } >>> - value_type operator*() const { return *Current; } >>> - value_type operator->() const { return *Current; } >>> - filtered_clause_iterator &operator++() { >>> + >>> + const SpecificClause *operator*() const { >>> + return cast<SpecificClause>(*Current); >>> + } >>> + const SpecificClause *operator->() const { >>> + return cast<SpecificClause>(*Current); >>> + } >>> + >>> + specific_clause_iterator &operator++() { >>> ++Current; >>> SkipToNextClause(); >>> return *this; >>> } >>> - >>> - filtered_clause_iterator operator++(int) { >>> - filtered_clause_iterator tmp(*this); >>> + specific_clause_iterator operator++(int) { >>> + specific_clause_iterator tmp(*this); >>> ++(*this); >>> return tmp; >>> } >>> >>> - bool operator!() { return Current == End; } >>> - explicit operator bool() { return Current != End; } >>> - bool empty() const { return Current == End; } >>> + bool operator==(const specific_clause_iterator &RHS) const { >>> + assert(End == RHS.End && "Comparing iterators of different >>> directives!"); >>> + return Current == RHS.Current; >>> + } >>> + bool operator!=(const specific_clause_iterator &RHS) const { >>> + return !(*this == RHS); >>> + } >>> }; >>> >>> - template <typename Fn> >>> - filtered_clause_iterator<Fn> getFilteredClauses(Fn &&fn) const { >>> - return filtered_clause_iterator<Fn>(clauses(), std::move(fn)); >>> + template <typename SpecificClause> >>> + static llvm::iterator_range<specific_clause_iterator<SpecificClause>> >>> + getClausesOfKind(ArrayRef<OMPClause *> Clauses) { >>> + return {specific_clause_iterator<SpecificClause>(Clauses), >>> + specific_clause_iterator<SpecificClause>( >>> + llvm::makeArrayRef(Clauses.end(), 0))}; >>> } >>> - 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}); >>> + >>> + template <typename SpecificClause> >>> + llvm::iterator_range<specific_clause_iterator<SpecificClause>> >>> + getClausesOfKind() const { >>> + return getClausesOfKind<SpecificClause>(clauses()); >>> } >>> >>> - /// \brief Gets a single clause of the specified kind \a K associated >>> with the >>> + /// Gets a single clause of the specified kind associated with the >>> /// current directive iff there is only one clause of this kind (and >>> assertion >>> /// is fired if there is more than one clause is associated with the >>> - /// directive). Returns nullptr if no clause of kind \a K is >>> associated with >>> + /// directive). Returns nullptr if no clause of this kind is >>> associated with >>> /// the directive. >>> - const OMPClause *getSingleClause(OpenMPClauseKind K) const; >>> + template <typename SpecificClause> >>> + const SpecificClause *getSingleClause() const { >>> + auto Clauses = getClausesOfKind<SpecificClause>(); >>> + >>> + if (Clauses.begin() != Clauses.end()) { >>> + assert(std::next(Clauses.begin()) == Clauses.end() && >>> + "There are at least 2 clauses of the specified kind"); >>> + return *Clauses.begin(); >>> + } >>> + return nullptr; >>> + } >>> + >>> + /// Returns true if the current directive has one or more clauses of a >>> + /// specific kind. >>> + template <typename SpecificClause> >>> + bool hasClausesOfKind() const { >>> + auto Clauses = getClausesOfKind<SpecificClause>(); >>> + return Clauses.begin() != Clauses.end(); >>> + } >>> >>> /// \brief Returns starting location of directive kind. >>> SourceLocation getLocStart() const { return StartLoc; } >>> >>> Modified: cfe/trunk/lib/AST/Stmt.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=246384&r1=246383&r2=246384&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/lib/AST/Stmt.cpp (original) >>> +++ cfe/trunk/lib/AST/Stmt.cpp Sun Aug 30 10:12:28 2015 >>> @@ -1621,18 +1621,6 @@ OMPDependClause *OMPDependClause::Create >>> return new (Mem) OMPDependClause(N); >>> } >>> >>> -const OMPClause * >>> -OMPExecutableDirective::getSingleClause(OpenMPClauseKind K) const { >>> - auto &&I = getClausesOfKind(K); >>> - >>> - if (I) { >>> - auto *Clause = *I; >>> - assert(!++I && "There are at least 2 clauses of the specified >>> kind"); >>> - return Clause; >>> - } >>> - return nullptr; >>> -} >>> - >>> OMPParallelDirective *OMPParallelDirective::Create( >>> const ASTContext &C, >>> SourceLocation StartLoc, >>> >>> Modified: cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp?rev=246384&r1=246383&r2=246384&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp (original) >>> +++ cfe/trunk/lib/CodeGen/CGStmtOpenMP.cpp Sun Aug 30 10:12:28 2015 >>> @@ -115,8 +115,7 @@ void CodeGenFunction::EmitOMPCopy(CodeGe >>> bool CodeGenFunction::EmitOMPFirstprivateClause(const >>> OMPExecutableDirective &D, >>> OMPPrivateScope >>> &PrivateScope) { >>> llvm::DenseSet<const VarDecl *> EmittedAsFirstprivate; >>> - for (auto &&I = D.getClausesOfKind(OMPC_firstprivate); I; ++I) { >>> - auto *C = cast<OMPFirstprivateClause>(*I); >>> + for (const auto *C : D.getClausesOfKind<OMPFirstprivateClause>()) { >>> auto IRef = C->varlist_begin(); >>> auto InitsRef = C->inits().begin(); >>> for (auto IInit : C->private_copies()) { >>> @@ -189,8 +188,7 @@ void CodeGenFunction::EmitOMPPrivateClau >>> const OMPExecutableDirective &D, >>> CodeGenFunction::OMPPrivateScope &PrivateScope) { >>> llvm::DenseSet<const VarDecl *> EmittedAsPrivate; >>> - for (auto &&I = D.getClausesOfKind(OMPC_private); I; ++I) { >>> - auto *C = cast<OMPPrivateClause>(*I); >>> + for (const auto *C : D.getClausesOfKind<OMPPrivateClause>()) { >>> auto IRef = C->varlist_begin(); >>> for (auto IInit : C->private_copies()) { >>> auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); >>> @@ -218,8 +216,7 @@ bool CodeGenFunction::EmitOMPCopyinClaus >>> // __kmpc_barrier(&loc, global_tid); >>> llvm::DenseSet<const VarDecl *> CopiedVars; >>> llvm::BasicBlock *CopyBegin = nullptr, *CopyEnd = nullptr; >>> - for (auto &&I = D.getClausesOfKind(OMPC_copyin); I; ++I) { >>> - auto *C = cast<OMPCopyinClause>(*I); >>> + for (const auto *C : D.getClausesOfKind<OMPCopyinClause>()) { >>> auto IRef = C->varlist_begin(); >>> auto ISrcRef = C->source_exprs().begin(); >>> auto IDestRef = C->destination_exprs().begin(); >>> @@ -279,9 +276,8 @@ bool CodeGenFunction::EmitOMPLastprivate >>> const OMPExecutableDirective &D, OMPPrivateScope &PrivateScope) { >>> bool HasAtLeastOneLastprivate = false; >>> llvm::DenseSet<const VarDecl *> AlreadyEmittedVars; >>> - for (auto &&I = D.getClausesOfKind(OMPC_lastprivate); I; ++I) { >>> + for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) { >>> HasAtLeastOneLastprivate = true; >>> - auto *C = cast<OMPLastprivateClause>(*I); >>> auto IRef = C->varlist_begin(); >>> auto IDestRef = C->destination_exprs().begin(); >>> for (auto *IInit : C->private_copies()) { >>> @@ -359,8 +355,7 @@ void CodeGenFunction::EmitOMPLastprivate >>> { >>> llvm::DenseSet<const VarDecl *> AlreadyEmittedVars; >>> bool FirstLCV = true; >>> - for (auto &&I = D.getClausesOfKind(OMPC_lastprivate); I; ++I) { >>> - auto *C = cast<OMPLastprivateClause>(*I); >>> + for (const auto *C : D.getClausesOfKind<OMPLastprivateClause>()) { >>> auto IRef = C->varlist_begin(); >>> auto ISrcRef = C->source_exprs().begin(); >>> auto IDestRef = C->destination_exprs().begin(); >>> @@ -405,8 +400,7 @@ void CodeGenFunction::EmitOMPLastprivate >>> void CodeGenFunction::EmitOMPReductionClauseInit( >>> const OMPExecutableDirective &D, >>> CodeGenFunction::OMPPrivateScope &PrivateScope) { >>> - for (auto &&I = D.getClausesOfKind(OMPC_reduction); I; ++I) { >>> - auto *C = cast<OMPReductionClause>(*I); >>> + for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) { >>> auto ILHS = C->lhs_exprs().begin(); >>> auto IRHS = C->rhs_exprs().begin(); >>> for (auto IRef : C->varlists()) { >>> @@ -442,9 +436,8 @@ void CodeGenFunction::EmitOMPReductionCl >>> llvm::SmallVector<const Expr *, 8> RHSExprs; >>> llvm::SmallVector<const Expr *, 8> ReductionOps; >>> bool HasAtLeastOneReduction = false; >>> - for (auto &&I = D.getClausesOfKind(OMPC_reduction); I; ++I) { >>> + for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) { >>> HasAtLeastOneReduction = true; >>> - auto *C = cast<OMPReductionClause>(*I); >>> LHSExprs.append(C->lhs_exprs().begin(), C->lhs_exprs().end()); >>> RHSExprs.append(C->rhs_exprs().begin(), C->rhs_exprs().end()); >>> ReductionOps.append(C->reduction_ops().begin(), >>> C->reduction_ops().end()); >>> @@ -454,7 +447,7 @@ void CodeGenFunction::EmitOMPReductionCl >>> // parallel directive (it always has implicit barrier). >>> CGM.getOpenMPRuntime().emitReduction( >>> *this, D.getLocEnd(), LHSExprs, RHSExprs, ReductionOps, >>> - D.getSingleClause(OMPC_nowait) || >>> + D.getSingleClause<OMPNowaitClause>() || >>> isOpenMPParallelDirective(D.getDirectiveKind()) || >>> D.getDirectiveKind() == OMPD_simd, >>> D.getDirectiveKind() == OMPD_simd); >>> @@ -469,23 +462,21 @@ static void emitCommonOMPParallelDirecti >>> auto CapturedStruct = CGF.GenerateCapturedStmtArgument(*CS); >>> auto OutlinedFn = >>> CGF.CGM.getOpenMPRuntime().emitParallelOutlinedFunction( >>> S, *CS->getCapturedDecl()->param_begin(), InnermostKind, CodeGen); >>> - if (auto C = S.getSingleClause(OMPC_num_threads)) { >>> + if (const auto *NumThreadsClause = >>> S.getSingleClause<OMPNumThreadsClause>()) { >>> CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF); >>> - auto NumThreadsClause = cast<OMPNumThreadsClause>(C); >>> auto NumThreads = >>> CGF.EmitScalarExpr(NumThreadsClause->getNumThreads(), >>> /*IgnoreResultAssign*/ true); >>> CGF.CGM.getOpenMPRuntime().emitNumThreadsClause( >>> CGF, NumThreads, NumThreadsClause->getLocStart()); >>> } >>> - if (auto *C = S.getSingleClause(OMPC_proc_bind)) { >>> + if (const auto *ProcBindClause = >>> S.getSingleClause<OMPProcBindClause>()) { >>> CodeGenFunction::RunCleanupsScope NumThreadsScope(CGF); >>> - auto *ProcBindClause = cast<OMPProcBindClause>(C); >>> CGF.CGM.getOpenMPRuntime().emitProcBindClause( >>> CGF, ProcBindClause->getProcBindKind(), >>> ProcBindClause->getLocStart()); >>> } >>> const Expr *IfCond = nullptr; >>> - if (auto C = S.getSingleClause(OMPC_if)) { >>> - IfCond = cast<OMPIfClause>(C)->getCondition(); >>> + if (const auto *C = S.getSingleClause<OMPIfClause>()) { >>> + IfCond = C->getCondition(); >>> } >>> CGF.CGM.getOpenMPRuntime().emitParallelCall(CGF, S.getLocStart(), >>> OutlinedFn, >>> CapturedStruct, IfCond); >>> @@ -526,8 +517,7 @@ void CodeGenFunction::EmitOMPLoopBody(co >>> EmitIgnoredExpr(I); >>> } >>> // Update the linear variables. >>> - for (auto &&I = D.getClausesOfKind(OMPC_linear); I; ++I) { >>> - auto *C = cast<OMPLinearClause>(*I); >>> + for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { >>> for (auto U : C->updates()) { >>> EmitIgnoredExpr(U); >>> } >>> @@ -596,8 +586,7 @@ void CodeGenFunction::EmitOMPInnerLoop( >>> >>> void CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective >>> &D) { >>> // Emit inits for the linear variables. >>> - for (auto &&I = D.getClausesOfKind(OMPC_linear); I; ++I) { >>> - auto *C = cast<OMPLinearClause>(*I); >>> + for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { >>> for (auto Init : C->inits()) { >>> auto *VD = cast<VarDecl>(cast<DeclRefExpr>(Init)->getDecl()); >>> auto *OrigVD = cast<VarDecl>( >>> @@ -627,8 +616,7 @@ void CodeGenFunction::EmitOMPLinearClaus >>> static void emitLinearClauseFinal(CodeGenFunction &CGF, >>> const OMPLoopDirective &D) { >>> // Emit the final values of the linear variables. >>> - for (auto &&I = D.getClausesOfKind(OMPC_linear); I; ++I) { >>> - auto *C = cast<OMPLinearClause>(*I); >>> + for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { >>> auto IC = C->varlist_begin(); >>> for (auto F : C->finals()) { >>> auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl()); >>> @@ -648,8 +636,7 @@ static void emitLinearClauseFinal(CodeGe >>> >>> static void emitAlignedClause(CodeGenFunction &CGF, >>> const OMPExecutableDirective &D) { >>> - for (auto &&I = D.getClausesOfKind(OMPC_aligned); I; ++I) { >>> - auto *Clause = cast<OMPAlignedClause>(*I); >>> + for (const auto *Clause : D.getClausesOfKind<OMPAlignedClause>()) { >>> unsigned ClauseAlignment = 0; >>> if (auto AlignmentExpr = Clause->getAlignment()) { >>> auto AlignmentCI = >>> @@ -719,8 +706,7 @@ static void emitPreCond(CodeGenFunction >>> static void >>> emitPrivateLinearVars(CodeGenFunction &CGF, const >>> OMPExecutableDirective &D, >>> CodeGenFunction::OMPPrivateScope &PrivateScope) { >>> - for (auto &&I = D.getClausesOfKind(OMPC_linear); I; ++I) { >>> - auto *C = cast<OMPLinearClause>(*I); >>> + for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { >>> auto CurPrivate = C->privates().begin(); >>> for (auto *E : C->varlists()) { >>> auto *VD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl()); >>> @@ -741,8 +727,7 @@ emitPrivateLinearVars(CodeGenFunction &C >>> >>> static void emitSimdlenSafelenClause(CodeGenFunction &CGF, >>> const OMPExecutableDirective &D) { >>> - if (auto *C = >>> - >>> cast_or_null<OMPSimdlenClause>(D.getSingleClause(OMPC_simdlen))) { >>> + if (const auto *C = D.getSingleClause<OMPSimdlenClause>()) { >>> RValue Len = CGF.EmitAnyExpr(C->getSimdlen(), >>> AggValueSlot::ignored(), >>> /*ignoreResult=*/true); >>> llvm::ConstantInt *Val = >>> cast<llvm::ConstantInt>(Len.getScalarVal()); >>> @@ -750,9 +735,8 @@ static void emitSimdlenSafelenClause(Cod >>> // In presence of finite 'safelen', it may be unsafe to mark all >>> // the memory instructions parallel, because loop-carried >>> // dependences of 'safelen' iterations are possible. >>> - CGF.LoopStack.setParallel(!D.getSingleClause(OMPC_safelen)); >>> - } else if (auto *C = cast_or_null<OMPSafelenClause>( >>> - D.getSingleClause(OMPC_safelen))) { >>> + CGF.LoopStack.setParallel(!D.getSingleClause<OMPSafelenClause>()); >>> + } else if (const auto *C = D.getSingleClause<OMPSafelenClause>()) { >>> RValue Len = CGF.EmitAnyExpr(C->getSafelen(), >>> AggValueSlot::ignored(), >>> /*ignoreResult=*/true); >>> llvm::ConstantInt *Val = >>> cast<llvm::ConstantInt>(Len.getScalarVal()); >>> @@ -1041,8 +1025,7 @@ emitScheduleClause(CodeGenFunction &CGF, >>> // Detect the loop schedule kind and chunk. >>> auto ScheduleKind = OMPC_SCHEDULE_unknown; >>> llvm::Value *Chunk = nullptr; >>> - if (auto *C = >>> - >>> cast_or_null<OMPScheduleClause>(S.getSingleClause(OMPC_schedule))) { >>> + if (const auto *C = S.getSingleClause<OMPScheduleClause>()) { >>> ScheduleKind = C->getScheduleKind(); >>> if (const auto *Ch = C->getChunkSize()) { >>> if (auto *ImpRef = >>> cast_or_null<DeclRefExpr>(C->getHelperChunkSize())) { >>> @@ -1143,7 +1126,7 @@ bool CodeGenFunction::EmitOMPWorksharing >>> ScheduleKind = ScheduleInfo.second; >>> const unsigned IVSize = >>> getContext().getTypeSize(IVExpr->getType()); >>> const bool IVSigned = >>> IVExpr->getType()->hasSignedIntegerRepresentation(); >>> - const bool Ordered = S.getSingleClause(OMPC_ordered) != nullptr; >>> + const bool Ordered = S.getSingleClause<OMPOrderedClause>() != >>> nullptr; >>> if (RT.isStaticNonchunked(ScheduleKind, >>> /* Chunked */ Chunk != nullptr) && >>> !Ordered) { >>> @@ -1208,7 +1191,7 @@ void CodeGenFunction::EmitOMPForDirectiv >>> CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen); >>> >>> // Emit an implicit barrier at the end. >>> - if (!S.getSingleClause(OMPC_nowait) || HasLastprivates) { >>> + if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates) { >>> CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), >>> OMPD_for); >>> } >>> } >>> @@ -1222,7 +1205,7 @@ void CodeGenFunction::EmitOMPForSimdDire >>> CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_simd, >>> CodeGen); >>> >>> // Emit an implicit barrier at the end. >>> - if (!S.getSingleClause(OMPC_nowait) || HasLastprivates) { >>> + if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates) { >>> CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), >>> OMPD_for); >>> } >>> } >>> @@ -1338,7 +1321,7 @@ CodeGenFunction::EmitSections(const OMPE >>> // Emit barrier for lastprivates only if 'sections' directive has >>> 'nowait' >>> // clause. Otherwise the barrier will be generated by the codegen >>> for the >>> // directive. >>> - if (HasLastprivates && S.getSingleClause(OMPC_nowait)) { >>> + if (HasLastprivates && S.getSingleClause<OMPNowaitClause>()) { >>> // Emit implicit barrier to synchronize threads and avoid data >>> races on >>> // initialization of firstprivate variables. >>> CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), >>> @@ -1351,11 +1334,11 @@ CodeGenFunction::EmitSections(const OMPE >>> bool HasFirstprivates; >>> // No need to generate reductions for sections with single section >>> region, we >>> // can use original shared variables for all operations. >>> - bool HasReductions = !S.getClausesOfKind(OMPC_reduction).empty(); >>> + bool HasReductions = S.hasClausesOfKind<OMPReductionClause>(); >>> // 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. >>> - bool HasLastprivates = !S.getClausesOfKind(OMPC_lastprivate).empty(); >>> + bool HasLastprivates = S.hasClausesOfKind<OMPLastprivateClause>(); >>> auto &&CodeGen = [Stmt, &S, &HasFirstprivates](CodeGenFunction &CGF) { >>> CodeGenFunction::OMPPrivateScope SingleScope(CGF); >>> HasFirstprivates = CGF.EmitOMPFirstprivateClause(S, SingleScope); >>> @@ -1371,7 +1354,7 @@ CodeGenFunction::EmitSections(const OMPE >>> // 'sections' directive has 'nowait' clause. Otherwise the barrier >>> will be >>> // generated by the codegen for the directive. >>> if ((HasFirstprivates || HasLastprivates || HasReductions) && >>> - S.getSingleClause(OMPC_nowait)) { >>> + S.getSingleClause<OMPNowaitClause>()) { >>> // Emit implicit barrier to synchronize threads and avoid data >>> races on >>> // initialization of firstprivate variables. >>> CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), >>> OMPD_unknown); >>> @@ -1383,7 +1366,7 @@ void CodeGenFunction::EmitOMPSectionsDir >>> LexicalScope Scope(*this, S.getSourceRange()); >>> OpenMPDirectiveKind EmittedAs = EmitSections(S); >>> // Emit an implicit barrier at the end. >>> - if (!S.getSingleClause(OMPC_nowait)) { >>> + if (!S.getSingleClause<OMPNowaitClause>()) { >>> CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), >>> EmittedAs); >>> } >>> } >>> @@ -1407,8 +1390,7 @@ void CodeGenFunction::EmitOMPSingleDirec >>> // construct. >>> // Build a list of copyprivate variables along with helper expressions >>> // (<source>, <destination>, <destination>=<source> expressions) >>> - for (auto &&I = S.getClausesOfKind(OMPC_copyprivate); I; ++I) { >>> - auto *C = cast<OMPCopyprivateClause>(*I); >>> + for (const auto *C : S.getClausesOfKind<OMPCopyprivateClause>()) { >>> CopyprivateVars.append(C->varlists().begin(), C->varlists().end()); >>> DestExprs.append(C->destination_exprs().begin(), >>> C->destination_exprs().end()); >>> @@ -1433,11 +1415,11 @@ void CodeGenFunction::EmitOMPSingleDirec >>> AssignmentOps); >>> // Emit an implicit barrier at the end (to avoid data race on >>> firstprivate >>> // init or if no 'nowait' clause was specified and no 'copyprivate' >>> clause). >>> - if ((!S.getSingleClause(OMPC_nowait) || HasFirstprivates) && >>> + if ((!S.getSingleClause<OMPNowaitClause>() || HasFirstprivates) && >>> CopyprivateVars.empty()) { >>> CGM.getOpenMPRuntime().emitBarrierCall( >>> *this, S.getLocStart(), >>> - S.getSingleClause(OMPC_nowait) ? OMPD_unknown : OMPD_single); >>> + S.getSingleClause<OMPNowaitClause>() ? OMPD_unknown : >>> OMPD_single); >>> } >>> } >>> >>> @@ -1521,8 +1503,7 @@ void CodeGenFunction::EmitOMPTaskDirecti >>> // Get list of private variables. >>> llvm::SmallVector<const Expr *, 8> PrivateVars; >>> llvm::SmallVector<const Expr *, 8> PrivateCopies; >>> - for (auto &&I = S.getClausesOfKind(OMPC_private); I; ++I) { >>> - auto *C = cast<OMPPrivateClause>(*I); >>> + for (const auto *C : S.getClausesOfKind<OMPPrivateClause>()) { >>> auto IRef = C->varlist_begin(); >>> for (auto *IInit : C->private_copies()) { >>> auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IRef)->getDecl()); >>> @@ -1538,8 +1519,7 @@ void CodeGenFunction::EmitOMPTaskDirecti >>> llvm::SmallVector<const Expr *, 8> FirstprivateVars; >>> llvm::SmallVector<const Expr *, 8> FirstprivateCopies; >>> llvm::SmallVector<const Expr *, 8> FirstprivateInits; >>> - for (auto &&I = S.getClausesOfKind(OMPC_firstprivate); I; ++I) { >>> - auto *C = cast<OMPFirstprivateClause>(*I); >>> + for (const auto *C : S.getClausesOfKind<OMPFirstprivateClause>()) { >>> auto IRef = C->varlist_begin(); >>> auto IElemInitRef = C->inits().begin(); >>> for (auto *IInit : C->private_copies()) { >>> @@ -1555,8 +1535,7 @@ void CodeGenFunction::EmitOMPTaskDirecti >>> // Build list of dependences. >>> llvm::SmallVector<std::pair<OpenMPDependClauseKind, const Expr *>, 8> >>> Dependences; >>> - for (auto &&I = S.getClausesOfKind(OMPC_depend); I; ++I) { >>> - auto *C = cast<OMPDependClause>(*I); >>> + for (const auto *C : S.getClausesOfKind<OMPDependClause>()) { >>> for (auto *IRef : C->varlists()) { >>> Dependences.push_back(std::make_pair(C->getDependencyKind(), >>> IRef)); >>> } >>> @@ -1608,13 +1587,13 @@ void CodeGenFunction::EmitOMPTaskDirecti >>> auto OutlinedFn = CGM.getOpenMPRuntime().emitTaskOutlinedFunction( >>> S, *I, OMPD_task, CodeGen); >>> // Check if we should emit tied or untied task. >>> - bool Tied = !S.getSingleClause(OMPC_untied); >>> + bool Tied = !S.getSingleClause<OMPUntiedClause>(); >>> // Check if the task is final >>> llvm::PointerIntPair<llvm::Value *, 1, bool> Final; >>> - if (auto *Clause = S.getSingleClause(OMPC_final)) { >>> + if (const auto *Clause = S.getSingleClause<OMPFinalClause>()) { >>> // If the condition constant folds and can be elided, try to avoid >>> emitting >>> // the condition and the dead arm of the if/else. >>> - auto *Cond = cast<OMPFinalClause>(Clause)->getCondition(); >>> + auto *Cond = Clause->getCondition(); >>> bool CondConstant; >>> if (ConstantFoldsToSimpleInteger(Cond, CondConstant)) >>> Final.setInt(CondConstant); >>> @@ -1626,8 +1605,8 @@ void CodeGenFunction::EmitOMPTaskDirecti >>> } >>> auto SharedsTy = >>> getContext().getRecordType(CS->getCapturedRecordDecl()); >>> const Expr *IfCond = nullptr; >>> - if (auto C = S.getSingleClause(OMPC_if)) { >>> - IfCond = cast<OMPIfClause>(C)->getCondition(); >>> + if (const auto *C = S.getSingleClause<OMPIfClause>()) { >>> + IfCond = C->getCondition(); >>> } >>> CGM.getOpenMPRuntime().emitTaskCall( >>> *this, S.getLocStart(), S, Tied, Final, OutlinedFn, SharedsTy, >>> @@ -1660,8 +1639,7 @@ void CodeGenFunction::EmitOMPTaskgroupDi >>> >>> void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &S) >>> { >>> CGM.getOpenMPRuntime().emitFlush(*this, [&]() -> ArrayRef<const Expr >>> *> { >>> - if (auto C = S.getSingleClause(/*K*/ OMPC_flush)) { >>> - auto FlushClause = cast<OMPFlushClause>(C); >>> + if (const auto *FlushClause = S.getSingleClause<OMPFlushClause>()) { >>> return llvm::makeArrayRef(FlushClause->varlist_begin(), >>> FlushClause->varlist_end()); >>> } >>> @@ -2084,7 +2062,7 @@ static void EmitOMPAtomicExpr(CodeGenFun >>> } >>> >>> void CodeGenFunction::EmitOMPAtomicDirective(const OMPAtomicDirective >>> &S) { >>> - bool IsSeqCst = S.getSingleClause(/*K=*/OMPC_seq_cst); >>> + bool IsSeqCst = S.getSingleClause<OMPSeqCstClause>(); >>> OpenMPClauseKind Kind = OMPC_unknown; >>> for (auto *C : S.clauses()) { >>> // Find first clause (skip seq_cst clause, if it is first). >>> >>> Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=246384&r1=246383&r2=246384&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original) >>> +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Sun Aug 30 10:12:28 2015 >>> @@ -3514,24 +3514,18 @@ CheckOpenMPLoop(OpenMPDirectiveKind DKin >>> } >>> >>> static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { >>> - auto &&CollapseFilter = [](const OMPClause *C) -> bool { >>> - return C->getClauseKind() == OMPC_collapse; >>> - }; >>> - >>> OMPExecutableDirective::filtered_clause_iterator<decltype(CollapseFilter)> >>> I( >>> - Clauses, std::move(CollapseFilter)); >>> - if (I) >>> - return cast<OMPCollapseClause>(*I)->getNumForLoops(); >>> + auto CollapseClauses = >>> + >>> OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); >>> + if (CollapseClauses.begin() != CollapseClauses.end()) >>> + return (*CollapseClauses.begin())->getNumForLoops(); >>> return nullptr; >>> } >>> >>> static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { >>> - auto &&OrderedFilter = [](const OMPClause *C) -> bool { >>> - return C->getClauseKind() == OMPC_ordered; >>> - }; >>> - >>> OMPExecutableDirective::filtered_clause_iterator<decltype(OrderedFilter)> I( >>> - Clauses, std::move(OrderedFilter)); >>> - if (I) >>> - return cast<OMPOrderedClause>(*I)->getNumForLoops(); >>> + auto OrderedClauses = >>> + >>> OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); >>> + if (OrderedClauses.begin() != OrderedClauses.end()) >>> + return (*OrderedClauses.begin())->getNumForLoops(); >>> return nullptr; >>> } >>> >>> >>> >>> _______________________________________________ >>> cfe-commits mailing list >>> cfe-commits@lists.llvm.org >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >>> >> >> >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits