diff options
Diffstat (limited to 'contrib/llvm/tools/clang/include/clang/AST/OpenMPClause.h')
-rw-r--r-- | contrib/llvm/tools/clang/include/clang/AST/OpenMPClause.h | 314 |
1 files changed, 282 insertions, 32 deletions
diff --git a/contrib/llvm/tools/clang/include/clang/AST/OpenMPClause.h b/contrib/llvm/tools/clang/include/clang/AST/OpenMPClause.h index 3e4c4bc..a1cae8e 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/OpenMPClause.h +++ b/contrib/llvm/tools/clang/include/clang/AST/OpenMPClause.h @@ -20,6 +20,7 @@ #include "clang/AST/Stmt.h" #include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/MapVector.h" namespace clang { @@ -76,10 +77,17 @@ class OMPClauseWithPreInit { friend class OMPClauseReader; /// Pre-initialization statement for the clause. Stmt *PreInit; + /// Region that captures the associated stmt. + OpenMPDirectiveKind CaptureRegion; + protected: /// Set pre-initialization statement for the clause. - void setPreInitStmt(Stmt *S) { PreInit = S; } - OMPClauseWithPreInit(const OMPClause *This) : PreInit(nullptr) { + void setPreInitStmt(Stmt *S, OpenMPDirectiveKind ThisRegion = OMPD_unknown) { + PreInit = S; + CaptureRegion = ThisRegion; + } + OMPClauseWithPreInit(const OMPClause *This) + : PreInit(nullptr), CaptureRegion(OMPD_unknown) { assert(get(This) && "get is not tuned for pre-init."); } @@ -88,6 +96,8 @@ public: const Stmt *getPreInitStmt() const { return PreInit; } /// Get pre-initialization statement for the clause. Stmt *getPreInitStmt() { return PreInit; } + /// Get capture region for the stmt in the clause. + OpenMPDirectiveKind getCaptureRegion() { return CaptureRegion; } static OMPClauseWithPreInit *get(OMPClause *C); static const OMPClauseWithPreInit *get(const OMPClause *C); }; @@ -194,7 +204,7 @@ public: /// In this example directive '#pragma omp parallel' has simple 'if' clause with /// condition 'a > 5' and directive name modifier 'parallel'. /// -class OMPIfClause : public OMPClause { +class OMPIfClause : public OMPClause, public OMPClauseWithPreInit { friend class OMPClauseReader; /// \brief Location of '('. SourceLocation LParenLoc; @@ -225,26 +235,31 @@ public: /// /// \param NameModifier [OpenMP 4.1] Directive name modifier of clause. /// \param Cond Condition of the clause. + /// \param HelperCond Helper condition for the clause. + /// \param CaptureRegion Innermost OpenMP region where expressions in this + /// clause must be captured. /// \param StartLoc Starting location of the clause. /// \param LParenLoc Location of '('. /// \param NameModifierLoc Location of directive name modifier. /// \param ColonLoc [OpenMP 4.1] Location of ':'. /// \param EndLoc Ending location of the clause. /// - OMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Cond, - SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation NameModifierLoc, SourceLocation ColonLoc, - SourceLocation EndLoc) - : OMPClause(OMPC_if, StartLoc, EndLoc), LParenLoc(LParenLoc), - Condition(Cond), ColonLoc(ColonLoc), NameModifier(NameModifier), - NameModifierLoc(NameModifierLoc) {} + OMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Cond, Stmt *HelperCond, + OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation NameModifierLoc, + SourceLocation ColonLoc, SourceLocation EndLoc) + : OMPClause(OMPC_if, StartLoc, EndLoc), OMPClauseWithPreInit(this), + LParenLoc(LParenLoc), Condition(Cond), ColonLoc(ColonLoc), + NameModifier(NameModifier), NameModifierLoc(NameModifierLoc) { + setPreInitStmt(HelperCond, CaptureRegion); + } /// \brief Build an empty clause. /// OMPIfClause() - : OMPClause(OMPC_if, SourceLocation(), SourceLocation()), LParenLoc(), - Condition(nullptr), ColonLoc(), NameModifier(OMPD_unknown), - NameModifierLoc() {} + : OMPClause(OMPC_if, SourceLocation(), SourceLocation()), + OMPClauseWithPreInit(this), LParenLoc(), Condition(nullptr), ColonLoc(), + NameModifier(OMPD_unknown), NameModifierLoc() {} /// \brief Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -331,7 +346,7 @@ public: /// In this example directive '#pragma omp parallel' has simple 'num_threads' /// clause with number of threads '6'. /// -class OMPNumThreadsClause : public OMPClause { +class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit { friend class OMPClauseReader; /// \brief Location of '('. SourceLocation LParenLoc; @@ -346,20 +361,29 @@ public: /// \brief Build 'num_threads' clause with condition \a NumThreads. /// /// \param NumThreads Number of threads for the construct. + /// \param HelperNumThreads Helper Number of threads for the construct. + /// \param CaptureRegion Innermost OpenMP region where expressions in this + /// clause must be captured. /// \param StartLoc Starting location of the clause. /// \param LParenLoc Location of '('. /// \param EndLoc Ending location of the clause. /// - OMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_num_threads, StartLoc, EndLoc), LParenLoc(LParenLoc), - NumThreads(NumThreads) {} + OMPNumThreadsClause(Expr *NumThreads, Stmt *HelperNumThreads, + OpenMPDirectiveKind CaptureRegion, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPClause(OMPC_num_threads, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), + NumThreads(NumThreads) { + setPreInitStmt(HelperNumThreads, CaptureRegion); + } /// \brief Build an empty clause. /// OMPNumThreadsClause() : OMPClause(OMPC_num_threads, SourceLocation(), SourceLocation()), - LParenLoc(SourceLocation()), NumThreads(nullptr) {} + OMPClauseWithPreInit(this), LParenLoc(SourceLocation()), + NumThreads(nullptr) {} /// \brief Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -1866,6 +1890,217 @@ public: } }; +/// This represents clause 'task_reduction' in the '#pragma omp taskgroup' +/// directives. +/// +/// \code +/// #pragma omp taskgroup task_reduction(+:a,b) +/// \endcode +/// In this example directive '#pragma omp taskgroup' has clause +/// 'task_reduction' with operator '+' and the variables 'a' and 'b'. +/// +class OMPTaskReductionClause final + : public OMPVarListClause<OMPTaskReductionClause>, + public OMPClauseWithPostUpdate, + private llvm::TrailingObjects<OMPTaskReductionClause, Expr *> { + friend TrailingObjects; + friend OMPVarListClause; + friend class OMPClauseReader; + /// Location of ':'. + SourceLocation ColonLoc; + /// Nested name specifier for C++. + NestedNameSpecifierLoc QualifierLoc; + /// Name of custom operator. + DeclarationNameInfo NameInfo; + + /// Build clause with number of variables \a N. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param ColonLoc Location of ':'. + /// \param N Number of the variables in the clause. + /// \param QualifierLoc The nested-name qualifier with location information + /// \param NameInfo The full name info for reduction identifier. + /// + OMPTaskReductionClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation ColonLoc, SourceLocation EndLoc, + unsigned N, NestedNameSpecifierLoc QualifierLoc, + const DeclarationNameInfo &NameInfo) + : OMPVarListClause<OMPTaskReductionClause>(OMPC_task_reduction, StartLoc, + LParenLoc, EndLoc, N), + OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc), + QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} + + /// Build an empty clause. + /// + /// \param N Number of variables. + /// + explicit OMPTaskReductionClause(unsigned N) + : OMPVarListClause<OMPTaskReductionClause>( + OMPC_task_reduction, SourceLocation(), SourceLocation(), + SourceLocation(), N), + OMPClauseWithPostUpdate(this), ColonLoc(), QualifierLoc(), NameInfo() {} + + /// Sets location of ':' symbol in clause. + void setColonLoc(SourceLocation CL) { ColonLoc = CL; } + /// Sets the name info for specified reduction identifier. + void setNameInfo(DeclarationNameInfo DNI) { NameInfo = DNI; } + /// Sets the nested name specifier. + void setQualifierLoc(NestedNameSpecifierLoc NSL) { QualifierLoc = NSL; } + + /// Set list of helper expressions, required for proper codegen of the clause. + /// These expressions represent private copy of the reduction variable. + void setPrivates(ArrayRef<Expr *> Privates); + + /// Get the list of helper privates. + MutableArrayRef<Expr *> getPrivates() { + return MutableArrayRef<Expr *>(varlist_end(), varlist_size()); + } + ArrayRef<const Expr *> getPrivates() const { + return llvm::makeArrayRef(varlist_end(), varlist_size()); + } + + /// Set list of helper expressions, required for proper codegen of the clause. + /// These expressions represent LHS expression in the final reduction + /// expression performed by the reduction clause. + void setLHSExprs(ArrayRef<Expr *> LHSExprs); + + /// Get the list of helper LHS expressions. + MutableArrayRef<Expr *> getLHSExprs() { + return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size()); + } + ArrayRef<const Expr *> getLHSExprs() const { + return llvm::makeArrayRef(getPrivates().end(), varlist_size()); + } + + /// Set list of helper expressions, required for proper codegen of the clause. + /// These expressions represent RHS expression in the final reduction + /// expression performed by the reduction clause. Also, variables in these + /// expressions are used for proper initialization of reduction copies. + void setRHSExprs(ArrayRef<Expr *> RHSExprs); + + /// Get the list of helper destination expressions. + MutableArrayRef<Expr *> getRHSExprs() { + return MutableArrayRef<Expr *>(getLHSExprs().end(), varlist_size()); + } + ArrayRef<const Expr *> getRHSExprs() const { + return llvm::makeArrayRef(getLHSExprs().end(), varlist_size()); + } + + /// Set list of helper reduction expressions, required for proper + /// codegen of the clause. These expressions are binary expressions or + /// operator/custom reduction call that calculates new value from source + /// helper expressions to destination helper expressions. + void setReductionOps(ArrayRef<Expr *> ReductionOps); + + /// Get the list of helper reduction expressions. + MutableArrayRef<Expr *> getReductionOps() { + return MutableArrayRef<Expr *>(getRHSExprs().end(), varlist_size()); + } + ArrayRef<const Expr *> getReductionOps() const { + return llvm::makeArrayRef(getRHSExprs().end(), varlist_size()); + } + +public: + /// Creates clause with a list of variables \a VL. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param ColonLoc Location of ':'. + /// \param EndLoc Ending location of the clause. + /// \param VL The variables in the clause. + /// \param QualifierLoc The nested-name qualifier with location information + /// \param NameInfo The full name info for reduction identifier. + /// \param Privates List of helper expressions for proper generation of + /// private copies. + /// \param LHSExprs List of helper expressions for proper generation of + /// assignment operation required for copyprivate clause. This list represents + /// LHSs of the reduction expressions. + /// \param RHSExprs List of helper expressions for proper generation of + /// assignment operation required for copyprivate clause. This list represents + /// RHSs of the reduction expressions. + /// Also, variables in these expressions are used for proper initialization of + /// reduction copies. + /// \param ReductionOps List of helper expressions that represents reduction + /// expressions: + /// \code + /// LHSExprs binop RHSExprs; + /// operator binop(LHSExpr, RHSExpr); + /// <CutomReduction>(LHSExpr, RHSExpr); + /// \endcode + /// Required for proper codegen of final reduction operation performed by the + /// reduction clause. + /// \param PreInit Statement that must be executed before entering the OpenMP + /// region with this clause. + /// \param PostUpdate Expression that must be executed after exit from the + /// OpenMP region with this clause. + /// + static OMPTaskReductionClause * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL, + NestedNameSpecifierLoc QualifierLoc, + const DeclarationNameInfo &NameInfo, ArrayRef<Expr *> Privates, + ArrayRef<Expr *> LHSExprs, ArrayRef<Expr *> RHSExprs, + ArrayRef<Expr *> ReductionOps, Stmt *PreInit, Expr *PostUpdate); + + /// Creates an empty clause with the place for \a N variables. + /// + /// \param C AST context. + /// \param N The number of variables. + /// + static OMPTaskReductionClause *CreateEmpty(const ASTContext &C, unsigned N); + + /// Gets location of ':' symbol in clause. + SourceLocation getColonLoc() const { return ColonLoc; } + /// Gets the name info for specified reduction identifier. + const DeclarationNameInfo &getNameInfo() const { return NameInfo; } + /// Gets the nested name specifier. + NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; } + + typedef MutableArrayRef<Expr *>::iterator helper_expr_iterator; + typedef ArrayRef<const Expr *>::iterator helper_expr_const_iterator; + typedef llvm::iterator_range<helper_expr_iterator> helper_expr_range; + typedef llvm::iterator_range<helper_expr_const_iterator> + helper_expr_const_range; + + helper_expr_const_range privates() const { + return helper_expr_const_range(getPrivates().begin(), getPrivates().end()); + } + helper_expr_range privates() { + return helper_expr_range(getPrivates().begin(), getPrivates().end()); + } + helper_expr_const_range lhs_exprs() const { + return helper_expr_const_range(getLHSExprs().begin(), getLHSExprs().end()); + } + helper_expr_range lhs_exprs() { + return helper_expr_range(getLHSExprs().begin(), getLHSExprs().end()); + } + helper_expr_const_range rhs_exprs() const { + return helper_expr_const_range(getRHSExprs().begin(), getRHSExprs().end()); + } + helper_expr_range rhs_exprs() { + return helper_expr_range(getRHSExprs().begin(), getRHSExprs().end()); + } + helper_expr_const_range reduction_ops() const { + return helper_expr_const_range(getReductionOps().begin(), + getReductionOps().end()); + } + helper_expr_range reduction_ops() { + return helper_expr_range(getReductionOps().begin(), + getReductionOps().end()); + } + + child_range children() { + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_task_reduction; + } +}; + /// \brief This represents clause 'linear' in the '#pragma omp ...' /// directives. /// @@ -2978,7 +3213,7 @@ protected: // Organize the components by declaration and retrieve the original // expression. Original expressions are always the first component of the // mappable component list. - llvm::DenseMap<ValueDecl *, SmallVector<MappableExprComponentListRef, 8>> + llvm::MapVector<ValueDecl *, SmallVector<MappableExprComponentListRef, 8>> ComponentListMap; { auto CI = ComponentLists.begin(); @@ -3456,7 +3691,7 @@ public: /// In this example directive '#pragma omp teams' has clause 'num_teams' /// with single expression 'n'. /// -class OMPNumTeamsClause : public OMPClause { +class OMPNumTeamsClause : public OMPClause, public OMPClauseWithPreInit { friend class OMPClauseReader; /// \brief Location of '('. SourceLocation LParenLoc; @@ -3472,20 +3707,27 @@ public: /// \brief Build 'num_teams' clause. /// /// \param E Expression associated with this clause. + /// \param HelperE Helper Expression associated with this clause. + /// \param CaptureRegion Innermost OpenMP region where expressions in this + /// clause must be captured. /// \param StartLoc Starting location of the clause. /// \param LParenLoc Location of '('. /// \param EndLoc Ending location of the clause. /// - OMPNumTeamsClause(Expr *E, SourceLocation StartLoc, SourceLocation LParenLoc, + OMPNumTeamsClause(Expr *E, Stmt *HelperE, OpenMPDirectiveKind CaptureRegion, + SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_num_teams, StartLoc, EndLoc), LParenLoc(LParenLoc), - NumTeams(E) {} + : OMPClause(OMPC_num_teams, StartLoc, EndLoc), OMPClauseWithPreInit(this), + LParenLoc(LParenLoc), NumTeams(E) { + setPreInitStmt(HelperE, CaptureRegion); + } /// \brief Build an empty clause. /// OMPNumTeamsClause() - : OMPClause(OMPC_num_teams, SourceLocation(), SourceLocation()), - LParenLoc(SourceLocation()), NumTeams(nullptr) {} + : OMPClause(OMPC_num_teams, SourceLocation(), SourceLocation()), + OMPClauseWithPreInit(this), LParenLoc(SourceLocation()), + NumTeams(nullptr) {} /// \brief Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } /// \brief Returns the location of '('. @@ -3511,7 +3753,7 @@ public: /// In this example directive '#pragma omp teams' has clause 'thread_limit' /// with single expression 'n'. /// -class OMPThreadLimitClause : public OMPClause { +class OMPThreadLimitClause : public OMPClause, public OMPClauseWithPreInit { friend class OMPClauseReader; /// \brief Location of '('. SourceLocation LParenLoc; @@ -3527,20 +3769,28 @@ public: /// \brief Build 'thread_limit' clause. /// /// \param E Expression associated with this clause. + /// \param HelperE Helper Expression associated with this clause. + /// \param CaptureRegion Innermost OpenMP region where expressions in this + /// clause must be captured. /// \param StartLoc Starting location of the clause. /// \param LParenLoc Location of '('. /// \param EndLoc Ending location of the clause. /// - OMPThreadLimitClause(Expr *E, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_thread_limit, StartLoc, EndLoc), LParenLoc(LParenLoc), - ThreadLimit(E) {} + OMPThreadLimitClause(Expr *E, Stmt *HelperE, + OpenMPDirectiveKind CaptureRegion, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPClause(OMPC_thread_limit, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), ThreadLimit(E) { + setPreInitStmt(HelperE, CaptureRegion); + } /// \brief Build an empty clause. /// OMPThreadLimitClause() : OMPClause(OMPC_thread_limit, SourceLocation(), SourceLocation()), - LParenLoc(SourceLocation()), ThreadLimit(nullptr) {} + OMPClauseWithPreInit(this), LParenLoc(SourceLocation()), + ThreadLimit(nullptr) {} /// \brief Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } /// \brief Returns the location of '('. |