| //===- StmtOpenMP.h - Classes for OpenMP directives ------------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| /// \file |
| /// This file defines OpenMP AST classes for executable directives and |
| /// clauses. |
| /// |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_CLANG_AST_STMTOPENMP_H |
| #define LLVM_CLANG_AST_STMTOPENMP_H |
| |
| #include "clang/AST/ASTContext.h" |
| #include "clang/AST/Expr.h" |
| #include "clang/AST/OpenMPClause.h" |
| #include "clang/AST/Stmt.h" |
| #include "clang/AST/StmtCXX.h" |
| #include "clang/Basic/OpenMPKinds.h" |
| #include "clang/Basic/SourceLocation.h" |
| |
| namespace clang { |
| |
| //===----------------------------------------------------------------------===// |
| // AST classes for directives. |
| //===----------------------------------------------------------------------===// |
| |
| /// Representation of an OpenMP canonical loop. |
| /// |
| /// OpenMP 1.0 C/C++, section 2.4.1 for Construct; canonical-shape |
| /// OpenMP 2.0 C/C++, section 2.4.1 for Construct; canonical-shape |
| /// OpenMP 2.5, section 2.5.1 Loop Construct; canonical form |
| /// OpenMP 3.1, section 2.5.1 Loop Construct; canonical form |
| /// OpenMP 4.0, section 2.6 Canonical Loop Form |
| /// OpenMP 4.5, section 2.6 Canonical Loop Form |
| /// OpenMP 5.0, section 2.9.1 Canonical Loop Form |
| /// OpenMP 5.1, section 2.11.1 Canonical Loop Nest Form |
| /// |
| /// An OpenMP canonical loop is a for-statement or range-based for-statement |
| /// with additional requirements that ensure that the number of iterations is |
| /// known before entering the loop and allow skipping to an arbitrary iteration. |
| /// The OMPCanonicalLoop AST node wraps a ForStmt or CXXForRangeStmt that is |
| /// known to fulfill OpenMP's canonical loop requirements because of being |
| /// associated to an OMPLoopBasedDirective. That is, the general structure is: |
| /// |
| /// OMPLoopBasedDirective |
| /// [`- CapturedStmt ] |
| /// [ `- CapturedDecl] |
| /// ` OMPCanonicalLoop |
| /// `- ForStmt/CXXForRangeStmt |
| /// `- Stmt |
| /// |
| /// One or multiple CapturedStmt/CapturedDecl pairs may be inserted by some |
| /// directives such as OMPParallelForDirective, but others do not need them |
| /// (such as OMPTileDirective). In The OMPCanonicalLoop and |
| /// ForStmt/CXXForRangeStmt pair is repeated for loop associated with the |
| /// directive. A OMPCanonicalLoop must not appear in the AST unless associated |
| /// with a OMPLoopBasedDirective. In an imperfectly nested loop nest, the |
| /// OMPCanonicalLoop may also be wrapped in a CompoundStmt: |
| /// |
| /// [...] |
| /// ` OMPCanonicalLoop |
| /// `- ForStmt/CXXForRangeStmt |
| /// `- CompoundStmt |
| /// |- Leading in-between code (if any) |
| /// |- OMPCanonicalLoop |
| /// | `- ForStmt/CXXForRangeStmt |
| /// | `- ... |
| /// `- Trailing in-between code (if any) |
| /// |
| /// The leading/trailing in-between code must not itself be a OMPCanonicalLoop |
| /// to avoid confusion which loop belongs to the nesting. |
| /// |
| /// There are three different kinds of iteration variables for different |
| /// purposes: |
| /// * Loop user variable: The user-accessible variable with different value for |
| /// each iteration. |
| /// * Loop iteration variable: The variable used to identify a loop iteration; |
| /// for range-based for-statement, this is the hidden iterator '__begin'. For |
| /// other loops, it is identical to the loop user variable. Must be a |
| /// random-access iterator, pointer or integer type. |
| /// * Logical iteration counter: Normalized loop counter starting at 0 and |
| /// incrementing by one at each iteration. Allows abstracting over the type |
| /// of the loop iteration variable and is always an unsigned integer type |
| /// appropriate to represent the range of the loop iteration variable. Its |
| /// value corresponds to the logical iteration number in the OpenMP |
| /// specification. |
| /// |
| /// This AST node provides two captured statements: |
| /// * The distance function which computes the number of iterations. |
| /// * The loop user variable function that computes the loop user variable when |
| /// given a logical iteration number. |
| /// |
| /// These captured statements provide the link between C/C++ semantics and the |
| /// logical iteration counters used by the OpenMPIRBuilder which is |
| /// language-agnostic and therefore does not know e.g. how to advance a |
| /// random-access iterator. The OpenMPIRBuilder will use this information to |
| /// apply simd, workshare-loop, distribute, taskloop and loop directives to the |
| /// loop. For compatibility with the non-OpenMPIRBuilder codegen path, an |
| /// OMPCanonicalLoop can itself also be wrapped into the CapturedStmts of an |
| /// OMPLoopDirective and skipped when searching for the associated syntactical |
| /// loop. |
| /// |
| /// Example: |
| /// <code> |
| /// std::vector<std::string> Container{1,2,3}; |
| /// for (std::string Str : Container) |
| /// Body(Str); |
| /// </code> |
| /// which is syntactic sugar for approximately: |
| /// <code> |
| /// auto &&__range = Container; |
| /// auto __begin = std::begin(__range); |
| /// auto __end = std::end(__range); |
| /// for (; __begin != __end; ++__begin) { |
| /// std::String Str = *__begin; |
| /// Body(Str); |
| /// } |
| /// </code> |
| /// In this example, the loop user variable is `Str`, the loop iteration |
| /// variable is `__begin` of type `std::vector<std::string>::iterator` and the |
| /// logical iteration number type is `size_t` (unsigned version of |
| /// `std::vector<std::string>::iterator::difference_type` aka `ptrdiff_t`). |
| /// Therefore, the distance function will be |
| /// <code> |
| /// [&](size_t &Result) { Result = __end - __begin; } |
| /// </code> |
| /// and the loop variable function is |
| /// <code> |
| /// [&,__begin](std::vector<std::string>::iterator &Result, size_t Logical) { |
| /// Result = __begin + Logical; |
| /// } |
| /// </code> |
| /// The variable `__begin`, aka the loop iteration variable, is captured by |
| /// value because it is modified in the loop body, but both functions require |
| /// the initial value. The OpenMP specification explicitly leaves unspecified |
| /// when the loop expressions are evaluated such that a capture by reference is |
| /// sufficient. |
| class OMPCanonicalLoop : public Stmt { |
| friend class ASTStmtReader; |
| friend class ASTStmtWriter; |
| |
| /// Children of this AST node. |
| enum { |
| LOOP_STMT, |
| DISTANCE_FUNC, |
| LOOPVAR_FUNC, |
| LOOPVAR_REF, |
| LastSubStmt = LOOPVAR_REF |
| }; |
| |
| private: |
| /// This AST node's children. |
| Stmt *SubStmts[LastSubStmt + 1] = {}; |
| |
| OMPCanonicalLoop() : Stmt(StmtClass::OMPCanonicalLoopClass) {} |
| |
| public: |
| /// Create a new OMPCanonicalLoop. |
| static OMPCanonicalLoop *create(const ASTContext &Ctx, Stmt *LoopStmt, |
| CapturedStmt *DistanceFunc, |
| CapturedStmt *LoopVarFunc, |
| DeclRefExpr *LoopVarRef) { |
| OMPCanonicalLoop *S = new (Ctx) OMPCanonicalLoop(); |
| S->setLoopStmt(LoopStmt); |
| S->setDistanceFunc(DistanceFunc); |
| S->setLoopVarFunc(LoopVarFunc); |
| S->setLoopVarRef(LoopVarRef); |
| return S; |
| } |
| |
| /// Create an empty OMPCanonicalLoop for deserialization. |
| static OMPCanonicalLoop *createEmpty(const ASTContext &Ctx) { |
| return new (Ctx) OMPCanonicalLoop(); |
| } |
| |
| static bool classof(const Stmt *S) { |
| return S->getStmtClass() == StmtClass::OMPCanonicalLoopClass; |
| } |
| |
| SourceLocation getBeginLoc() const { return getLoopStmt()->getBeginLoc(); } |
| SourceLocation getEndLoc() const { return getLoopStmt()->getEndLoc(); } |
| |
| /// Return this AST node's children. |
| /// @{ |
| child_range children() { |
| return child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1); |
| } |
| const_child_range children() const { |
| return const_child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1); |
| } |
| /// @} |
| |
| /// The wrapped syntactic loop statement (ForStmt or CXXForRangeStmt). |
| /// @{ |
| Stmt *getLoopStmt() { return SubStmts[LOOP_STMT]; } |
| const Stmt *getLoopStmt() const { return SubStmts[LOOP_STMT]; } |
| void setLoopStmt(Stmt *S) { |
| assert((isa<ForStmt>(S) || isa<CXXForRangeStmt>(S)) && |
| "Canonical loop must be a for loop (range-based or otherwise)"); |
| SubStmts[LOOP_STMT] = S; |
| } |
| /// @} |
| |
| /// The function that computes the number of loop iterations. Can be evaluated |
| /// before entering the loop but after the syntactical loop's init |
| /// statement(s). |
| /// |
| /// Function signature: void(LogicalTy &Result) |
| /// Any values necessary to compute the distance are captures of the closure. |
| /// @{ |
| CapturedStmt *getDistanceFunc() { |
| return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]); |
| } |
| const CapturedStmt *getDistanceFunc() const { |
| return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]); |
| } |
| void setDistanceFunc(CapturedStmt *S) { |
| assert(S && "Expected non-null captured statement"); |
| SubStmts[DISTANCE_FUNC] = S; |
| } |
| /// @} |
| |
| /// The function that computes the loop user variable from a logical iteration |
| /// counter. Can be evaluated as first statement in the loop. |
| /// |
| /// Function signature: void(LoopVarTy &Result, LogicalTy Number) |
| /// Any other values required to compute the loop user variable (such as start |
| /// value, step size) are captured by the closure. In particular, the initial |
| /// value of loop iteration variable is captured by value to be unaffected by |
| /// previous iterations. |
| /// @{ |
| CapturedStmt *getLoopVarFunc() { |
| return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]); |
| } |
| const CapturedStmt *getLoopVarFunc() const { |
| return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]); |
| } |
| void setLoopVarFunc(CapturedStmt *S) { |
| assert(S && "Expected non-null captured statement"); |
| SubStmts[LOOPVAR_FUNC] = S; |
| } |
| /// @} |
| |
| /// Reference to the loop user variable as accessed in the loop body. |
| /// @{ |
| DeclRefExpr *getLoopVarRef() { |
| return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]); |
| } |
| const DeclRefExpr *getLoopVarRef() const { |
| return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]); |
| } |
| void setLoopVarRef(DeclRefExpr *E) { |
| assert(E && "Expected non-null loop variable"); |
| SubStmts[LOOPVAR_REF] = E; |
| } |
| /// @} |
| }; |
| |
| /// This is a basic class for representing single OpenMP executable |
| /// directive. |
| /// |
| class OMPExecutableDirective : public Stmt { |
| friend class ASTStmtReader; |
| friend class ASTStmtWriter; |
| |
| /// Kind of the directive. |
| OpenMPDirectiveKind Kind = llvm::omp::OMPD_unknown; |
| /// Starting location of the directive (directive keyword). |
| SourceLocation StartLoc; |
| /// Ending location of the directive. |
| SourceLocation EndLoc; |
| |
| /// Get the clauses storage. |
| MutableArrayRef<OMPClause *> getClauses() { |
| if (!Data) |
| return llvm::None; |
| return Data->getClauses(); |
| } |
| |
| protected: |
| /// Data, associated with the directive. |
| OMPChildren *Data = nullptr; |
| |
| /// Build instance of directive of class \a K. |
| /// |
| /// \param SC Statement class. |
| /// \param K Kind of OpenMP directive. |
| /// \param StartLoc Starting location of the directive (directive keyword). |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPExecutableDirective(StmtClass SC, OpenMPDirectiveKind K, |
| SourceLocation StartLoc, SourceLocation EndLoc) |
| : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)), |
| EndLoc(std::move(EndLoc)) {} |
| |
| template <typename T, typename... Params> |
| static T *createDirective(const ASTContext &C, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, unsigned NumChildren, |
| Params &&... P) { |
| void *Mem = |
| C.Allocate(sizeof(T) + OMPChildren::size(Clauses.size(), AssociatedStmt, |
| NumChildren), |
| alignof(T)); |
| |
| auto *Data = OMPChildren::Create(reinterpret_cast<T *>(Mem) + 1, Clauses, |
| AssociatedStmt, NumChildren); |
| auto *Inst = new (Mem) T(std::forward<Params>(P)...); |
| Inst->Data = Data; |
| return Inst; |
| } |
| |
| template <typename T, typename... Params> |
| static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses, |
| bool HasAssociatedStmt, unsigned NumChildren, |
| Params &&... P) { |
| void *Mem = |
| C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt, |
| NumChildren), |
| alignof(T)); |
| auto *Data = |
| OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses, |
| HasAssociatedStmt, NumChildren); |
| auto *Inst = new (Mem) T(std::forward<Params>(P)...); |
| Inst->Data = Data; |
| return Inst; |
| } |
| |
| template <typename T> |
| static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses, |
| bool HasAssociatedStmt = false, |
| unsigned NumChildren = 0) { |
| void *Mem = |
| C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt, |
| NumChildren), |
| alignof(T)); |
| auto *Data = |
| OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses, |
| HasAssociatedStmt, NumChildren); |
| auto *Inst = new (Mem) T; |
| Inst->Data = Data; |
| return Inst; |
| } |
| |
| public: |
| /// Iterates over expressions/statements used in the construct. |
| class used_clauses_child_iterator |
| : public llvm::iterator_adaptor_base< |
| used_clauses_child_iterator, ArrayRef<OMPClause *>::iterator, |
| std::forward_iterator_tag, Stmt *, ptrdiff_t, Stmt *, Stmt *> { |
| ArrayRef<OMPClause *>::iterator End; |
| OMPClause::child_iterator ChildI, ChildEnd; |
| |
| void MoveToNext() { |
| if (ChildI != ChildEnd) |
| return; |
| while (this->I != End) { |
| ++this->I; |
| if (this->I != End) { |
| ChildI = (*this->I)->used_children().begin(); |
| ChildEnd = (*this->I)->used_children().end(); |
| if (ChildI != ChildEnd) |
| return; |
| } |
| } |
| } |
| |
| public: |
| explicit used_clauses_child_iterator(ArrayRef<OMPClause *> Clauses) |
| : used_clauses_child_iterator::iterator_adaptor_base(Clauses.begin()), |
| End(Clauses.end()) { |
| if (this->I != End) { |
| ChildI = (*this->I)->used_children().begin(); |
| ChildEnd = (*this->I)->used_children().end(); |
| MoveToNext(); |
| } |
| } |
| Stmt *operator*() const { return *ChildI; } |
| Stmt *operator->() const { return **this; } |
| |
| used_clauses_child_iterator &operator++() { |
| ++ChildI; |
| if (ChildI != ChildEnd) |
| return *this; |
| if (this->I != End) { |
| ++this->I; |
| if (this->I != End) { |
| ChildI = (*this->I)->used_children().begin(); |
| ChildEnd = (*this->I)->used_children().end(); |
| } |
| } |
| MoveToNext(); |
| return *this; |
| } |
| }; |
| |
| static llvm::iterator_range<used_clauses_child_iterator> |
| used_clauses_children(ArrayRef<OMPClause *> Clauses) { |
| return {used_clauses_child_iterator(Clauses), |
| used_clauses_child_iterator(llvm::makeArrayRef(Clauses.end(), 0))}; |
| } |
| |
| /// Iterates over a filtered subrange of clauses applied to a |
| /// directive. |
| /// |
| /// This iterator visits only clauses of type SpecificClause. |
| template <typename SpecificClause> |
| class specific_clause_iterator |
| : public llvm::iterator_adaptor_base< |
| specific_clause_iterator<SpecificClause>, |
| ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag, |
| const SpecificClause *, ptrdiff_t, const SpecificClause *, |
| const SpecificClause *> { |
| ArrayRef<OMPClause *>::const_iterator End; |
| |
| void SkipToNextClause() { |
| while (this->I != End && !isa<SpecificClause>(*this->I)) |
| ++this->I; |
| } |
| |
| public: |
| explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses) |
| : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()), |
| End(Clauses.end()) { |
| SkipToNextClause(); |
| } |
| |
| const SpecificClause *operator*() const { |
| return cast<SpecificClause>(*this->I); |
| } |
| const SpecificClause *operator->() const { return **this; } |
| |
| specific_clause_iterator &operator++() { |
| ++this->I; |
| SkipToNextClause(); |
| return *this; |
| } |
| }; |
| |
| 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))}; |
| } |
| |
| template <typename SpecificClause> |
| llvm::iterator_range<specific_clause_iterator<SpecificClause>> |
| getClausesOfKind() const { |
| return getClausesOfKind<SpecificClause>(clauses()); |
| } |
| |
| /// 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 this kind is associated with |
| /// the directive. |
| template <typename SpecificClause> |
| static const SpecificClause *getSingleClause(ArrayRef<OMPClause *> Clauses) { |
| auto ClausesOfKind = getClausesOfKind<SpecificClause>(Clauses); |
| |
| if (ClausesOfKind.begin() != ClausesOfKind.end()) { |
| assert(std::next(ClausesOfKind.begin()) == ClausesOfKind.end() && |
| "There are at least 2 clauses of the specified kind"); |
| return *ClausesOfKind.begin(); |
| } |
| return nullptr; |
| } |
| |
| template <typename SpecificClause> |
| const SpecificClause *getSingleClause() const { |
| return getSingleClause<SpecificClause>(clauses()); |
| } |
| |
| /// 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(); |
| } |
| |
| /// Returns starting location of directive kind. |
| SourceLocation getBeginLoc() const { return StartLoc; } |
| /// Returns ending location of directive. |
| SourceLocation getEndLoc() const { return EndLoc; } |
| |
| /// Set starting location of directive kind. |
| /// |
| /// \param Loc New starting location of directive. |
| /// |
| void setLocStart(SourceLocation Loc) { StartLoc = Loc; } |
| /// Set ending location of directive. |
| /// |
| /// \param Loc New ending location of directive. |
| /// |
| void setLocEnd(SourceLocation Loc) { EndLoc = Loc; } |
| |
| /// Get number of clauses. |
| unsigned getNumClauses() const { |
| if (!Data) |
| return 0; |
| return Data->getNumClauses(); |
| } |
| |
| /// Returns specified clause. |
| /// |
| /// \param I Number of clause. |
| /// |
| OMPClause *getClause(unsigned I) const { return clauses()[I]; } |
| |
| /// Returns true if directive has associated statement. |
| bool hasAssociatedStmt() const { return Data && Data->hasAssociatedStmt(); } |
| |
| /// Returns statement associated with the directive. |
| const Stmt *getAssociatedStmt() const { |
| return const_cast<OMPExecutableDirective *>(this)->getAssociatedStmt(); |
| } |
| Stmt *getAssociatedStmt() { |
| assert(hasAssociatedStmt() && |
| "Expected directive with the associated statement."); |
| return Data->getAssociatedStmt(); |
| } |
| |
| /// Returns the captured statement associated with the |
| /// component region within the (combined) directive. |
| /// |
| /// \param RegionKind Component region kind. |
| const CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const { |
| assert(hasAssociatedStmt() && |
| "Expected directive with the associated statement."); |
| SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; |
| getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind()); |
| return Data->getCapturedStmt(RegionKind, CaptureRegions); |
| } |
| |
| /// Get innermost captured statement for the construct. |
| CapturedStmt *getInnermostCapturedStmt() { |
| assert(hasAssociatedStmt() && |
| "Expected directive with the associated statement."); |
| SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; |
| getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind()); |
| return Data->getInnermostCapturedStmt(CaptureRegions); |
| } |
| |
| const CapturedStmt *getInnermostCapturedStmt() const { |
| return const_cast<OMPExecutableDirective *>(this) |
| ->getInnermostCapturedStmt(); |
| } |
| |
| OpenMPDirectiveKind getDirectiveKind() const { return Kind; } |
| |
| static bool classof(const Stmt *S) { |
| return S->getStmtClass() >= firstOMPExecutableDirectiveConstant && |
| S->getStmtClass() <= lastOMPExecutableDirectiveConstant; |
| } |
| |
| child_range children() { |
| if (!Data) |
| return child_range(child_iterator(), child_iterator()); |
| return Data->getAssociatedStmtAsRange(); |
| } |
| |
| const_child_range children() const { |
| return const_cast<OMPExecutableDirective *>(this)->children(); |
| } |
| |
| ArrayRef<OMPClause *> clauses() const { |
| if (!Data) |
| return llvm::None; |
| return Data->getClauses(); |
| } |
| |
| /// Returns whether or not this is a Standalone directive. |
| /// |
| /// Stand-alone directives are executable directives |
| /// that have no associated user code. |
| bool isStandaloneDirective() const; |
| |
| /// Returns the AST node representing OpenMP structured-block of this |
| /// OpenMP executable directive, |
| /// Prerequisite: Executable Directive must not be Standalone directive. |
| const Stmt *getStructuredBlock() const { |
| return const_cast<OMPExecutableDirective *>(this)->getStructuredBlock(); |
| } |
| Stmt *getStructuredBlock(); |
| |
| const Stmt *getRawStmt() const { |
| return const_cast<OMPExecutableDirective *>(this)->getRawStmt(); |
| } |
| Stmt *getRawStmt() { |
| assert(hasAssociatedStmt() && |
| "Expected directive with the associated statement."); |
| return Data->getRawStmt(); |
| } |
| }; |
| |
| /// This represents '#pragma omp parallel' directive. |
| /// |
| /// \code |
| /// #pragma omp parallel private(a,b) reduction(+: c,d) |
| /// \endcode |
| /// In this example directive '#pragma omp parallel' has clauses 'private' |
| /// with the variables 'a' and 'b' and 'reduction' with operator '+' and |
| /// variables 'c' and 'd'. |
| /// |
| class OMPParallelDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// true if the construct has inner cancel directive. |
| bool HasCancel = false; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive (directive keyword). |
| /// \param EndLoc Ending Location of the directive. |
| /// |
| OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPParallelDirectiveClass, |
| llvm::omp::OMPD_parallel, StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPParallelDirective() |
| : OMPExecutableDirective(OMPParallelDirectiveClass, |
| llvm::omp::OMPD_parallel, SourceLocation(), |
| SourceLocation()) {} |
| |
| /// Sets special task reduction descriptor. |
| void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } |
| |
| /// Set cancel state. |
| void setHasCancel(bool Has) { HasCancel = Has; } |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement associated with the directive. |
| /// \param TaskRedRef Task reduction special reference expression to handle |
| /// taskgroup descriptor. |
| /// \param HasCancel true if this directive has inner cancel directive. |
| /// |
| static OMPParallelDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, |
| bool HasCancel); |
| |
| /// Creates an empty directive with the place for \a N clauses. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPParallelDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, EmptyShell); |
| |
| /// Returns special task reduction reference expression. |
| Expr *getTaskReductionRefExpr() { |
| return cast_or_null<Expr>(Data->getChildren()[0]); |
| } |
| const Expr *getTaskReductionRefExpr() const { |
| return const_cast<OMPParallelDirective *>(this)->getTaskReductionRefExpr(); |
| } |
| |
| /// Return true if current directive has inner cancel directive. |
| bool hasCancel() const { return HasCancel; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPParallelDirectiveClass; |
| } |
| }; |
| |
| /// The base class for all loop-based directives, including loop transformation |
| /// directives. |
| class OMPLoopBasedDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| |
| protected: |
| /// Number of collapsed loops as specified by 'collapse' clause. |
| unsigned NumAssociatedLoops = 0; |
| |
| /// Build instance of loop directive of class \a Kind. |
| /// |
| /// \param SC Statement class. |
| /// \param Kind Kind of OpenMP directive. |
| /// \param StartLoc Starting location of the directive (directive keyword). |
| /// \param EndLoc Ending location of the directive. |
| /// \param NumAssociatedLoops Number of loops associated with the construct. |
| /// |
| OMPLoopBasedDirective(StmtClass SC, OpenMPDirectiveKind Kind, |
| SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned NumAssociatedLoops) |
| : OMPExecutableDirective(SC, Kind, StartLoc, EndLoc), |
| NumAssociatedLoops(NumAssociatedLoops) {} |
| |
| public: |
| /// The expressions built to support OpenMP loops in combined/composite |
| /// pragmas (e.g. pragma omp distribute parallel for) |
| struct DistCombinedHelperExprs { |
| /// DistributeLowerBound - used when composing 'omp distribute' with |
| /// 'omp for' in a same construct. |
| Expr *LB; |
| /// DistributeUpperBound - used when composing 'omp distribute' with |
| /// 'omp for' in a same construct. |
| Expr *UB; |
| /// DistributeEnsureUpperBound - used when composing 'omp distribute' |
| /// with 'omp for' in a same construct, EUB depends on DistUB |
| Expr *EUB; |
| /// Distribute loop iteration variable init used when composing 'omp |
| /// distribute' |
| /// with 'omp for' in a same construct |
| Expr *Init; |
| /// Distribute Loop condition used when composing 'omp distribute' |
| /// with 'omp for' in a same construct |
| Expr *Cond; |
| /// Update of LowerBound for statically scheduled omp loops for |
| /// outer loop in combined constructs (e.g. 'distribute parallel for') |
| Expr *NLB; |
| /// Update of UpperBound for statically scheduled omp loops for |
| /// outer loop in combined constructs (e.g. 'distribute parallel for') |
| Expr *NUB; |
| /// Distribute Loop condition used when composing 'omp distribute' |
| /// with 'omp for' in a same construct when schedule is chunked. |
| Expr *DistCond; |
| /// 'omp parallel for' loop condition used when composed with |
| /// 'omp distribute' in the same construct and when schedule is |
| /// chunked and the chunk size is 1. |
| Expr *ParForInDistCond; |
| }; |
| |
| /// The expressions built for the OpenMP loop CodeGen for the |
| /// whole collapsed loop nest. |
| struct HelperExprs { |
| /// Loop iteration variable. |
| Expr *IterationVarRef; |
| /// Loop last iteration number. |
| Expr *LastIteration; |
| /// Loop number of iterations. |
| Expr *NumIterations; |
| /// Calculation of last iteration. |
| Expr *CalcLastIteration; |
| /// Loop pre-condition. |
| Expr *PreCond; |
| /// Loop condition. |
| Expr *Cond; |
| /// Loop iteration variable init. |
| Expr *Init; |
| /// Loop increment. |
| Expr *Inc; |
| /// IsLastIteration - local flag variable passed to runtime. |
| Expr *IL; |
| /// LowerBound - local variable passed to runtime. |
| Expr *LB; |
| /// UpperBound - local variable passed to runtime. |
| Expr *UB; |
| /// Stride - local variable passed to runtime. |
| Expr *ST; |
| /// EnsureUpperBound -- expression UB = min(UB, NumIterations). |
| Expr *EUB; |
| /// Update of LowerBound for statically scheduled 'omp for' loops. |
| Expr *NLB; |
| /// Update of UpperBound for statically scheduled 'omp for' loops. |
| Expr *NUB; |
| /// PreviousLowerBound - local variable passed to runtime in the |
| /// enclosing schedule or null if that does not apply. |
| Expr *PrevLB; |
| /// PreviousUpperBound - local variable passed to runtime in the |
| /// enclosing schedule or null if that does not apply. |
| Expr *PrevUB; |
| /// DistInc - increment expression for distribute loop when found |
| /// combined with a further loop level (e.g. in 'distribute parallel for') |
| /// expression IV = IV + ST |
| Expr *DistInc; |
| /// PrevEUB - expression similar to EUB but to be used when loop |
| /// scheduling uses PrevLB and PrevUB (e.g. in 'distribute parallel for' |
| /// when ensuring that the UB is either the calculated UB by the runtime or |
| /// the end of the assigned distribute chunk) |
| /// expression UB = min (UB, PrevUB) |
| Expr *PrevEUB; |
| /// Counters Loop counters. |
| SmallVector<Expr *, 4> Counters; |
| /// PrivateCounters Loop counters. |
| SmallVector<Expr *, 4> PrivateCounters; |
| /// Expressions for loop counters inits for CodeGen. |
| SmallVector<Expr *, 4> Inits; |
| /// Expressions for loop counters update for CodeGen. |
| SmallVector<Expr *, 4> Updates; |
| /// Final loop counter values for GodeGen. |
| SmallVector<Expr *, 4> Finals; |
| /// List of counters required for the generation of the non-rectangular |
| /// loops. |
| SmallVector<Expr *, 4> DependentCounters; |
| /// List of initializers required for the generation of the non-rectangular |
| /// loops. |
| SmallVector<Expr *, 4> DependentInits; |
| /// List of final conditions required for the generation of the |
| /// non-rectangular loops. |
| SmallVector<Expr *, 4> FinalsConditions; |
| /// Init statement for all captured expressions. |
| Stmt *PreInits; |
| |
| /// Expressions used when combining OpenMP loop pragmas |
| DistCombinedHelperExprs DistCombinedFields; |
| |
| /// Check if all the expressions are built (does not check the |
| /// worksharing ones). |
| bool builtAll() { |
| return IterationVarRef != nullptr && LastIteration != nullptr && |
| NumIterations != nullptr && PreCond != nullptr && |
| Cond != nullptr && Init != nullptr && Inc != nullptr; |
| } |
| |
| /// Initialize all the fields to null. |
| /// \param Size Number of elements in the |
| /// counters/finals/updates/dependent_counters/dependent_inits/finals_conditions |
| /// arrays. |
| void clear(unsigned Size) { |
| IterationVarRef = nullptr; |
| LastIteration = nullptr; |
| CalcLastIteration = nullptr; |
| PreCond = nullptr; |
| Cond = nullptr; |
| Init = nullptr; |
| Inc = nullptr; |
| IL = nullptr; |
| LB = nullptr; |
| UB = nullptr; |
| ST = nullptr; |
| EUB = nullptr; |
| NLB = nullptr; |
| NUB = nullptr; |
| NumIterations = nullptr; |
| PrevLB = nullptr; |
| PrevUB = nullptr; |
| DistInc = nullptr; |
| PrevEUB = nullptr; |
| Counters.resize(Size); |
| PrivateCounters.resize(Size); |
| Inits.resize(Size); |
| Updates.resize(Size); |
| Finals.resize(Size); |
| DependentCounters.resize(Size); |
| DependentInits.resize(Size); |
| FinalsConditions.resize(Size); |
| for (unsigned I = 0; I < Size; ++I) { |
| Counters[I] = nullptr; |
| PrivateCounters[I] = nullptr; |
| Inits[I] = nullptr; |
| Updates[I] = nullptr; |
| Finals[I] = nullptr; |
| DependentCounters[I] = nullptr; |
| DependentInits[I] = nullptr; |
| FinalsConditions[I] = nullptr; |
| } |
| PreInits = nullptr; |
| DistCombinedFields.LB = nullptr; |
| DistCombinedFields.UB = nullptr; |
| DistCombinedFields.EUB = nullptr; |
| DistCombinedFields.Init = nullptr; |
| DistCombinedFields.Cond = nullptr; |
| DistCombinedFields.NLB = nullptr; |
| DistCombinedFields.NUB = nullptr; |
| DistCombinedFields.DistCond = nullptr; |
| DistCombinedFields.ParForInDistCond = nullptr; |
| } |
| }; |
| |
| /// Get number of collapsed loops. |
| unsigned getLoopsNumber() const { return NumAssociatedLoops; } |
| |
| /// Try to find the next loop sub-statement in the specified statement \p |
| /// CurStmt. |
| /// \param TryImperfectlyNestedLoops true, if we need to try to look for the |
| /// imperfectly nested loop. |
| static Stmt *tryToFindNextInnerLoop(Stmt *CurStmt, |
| bool TryImperfectlyNestedLoops); |
| static const Stmt *tryToFindNextInnerLoop(const Stmt *CurStmt, |
| bool TryImperfectlyNestedLoops) { |
| return tryToFindNextInnerLoop(const_cast<Stmt *>(CurStmt), |
| TryImperfectlyNestedLoops); |
| } |
| |
| /// Calls the specified callback function for all the loops in \p CurStmt, |
| /// from the outermost to the innermost. |
| static bool |
| doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops, |
| unsigned NumLoops, |
| llvm::function_ref<bool(unsigned, Stmt *)> Callback, |
| llvm::function_ref<void(OMPLoopTransformationDirective *)> |
| OnTransformationCallback); |
| static bool |
| doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops, |
| unsigned NumLoops, |
| llvm::function_ref<bool(unsigned, const Stmt *)> Callback, |
| llvm::function_ref<void(const OMPLoopTransformationDirective *)> |
| OnTransformationCallback) { |
| auto &&NewCallback = [Callback](unsigned Cnt, Stmt *CurStmt) { |
| return Callback(Cnt, CurStmt); |
| }; |
| auto &&NewTransformCb = |
| [OnTransformationCallback](OMPLoopTransformationDirective *A) { |
| OnTransformationCallback(A); |
| }; |
| return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops, |
| NumLoops, NewCallback, NewTransformCb); |
| } |
| |
| /// Calls the specified callback function for all the loops in \p CurStmt, |
| /// from the outermost to the innermost. |
| static bool |
| doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops, |
| unsigned NumLoops, |
| llvm::function_ref<bool(unsigned, Stmt *)> Callback) { |
| auto &&TransformCb = [](OMPLoopTransformationDirective *) {}; |
| return doForAllLoops(CurStmt, TryImperfectlyNestedLoops, NumLoops, Callback, |
| TransformCb); |
| } |
| static bool |
| doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops, |
| unsigned NumLoops, |
| llvm::function_ref<bool(unsigned, const Stmt *)> Callback) { |
| auto &&NewCallback = [Callback](unsigned Cnt, const Stmt *CurStmt) { |
| return Callback(Cnt, CurStmt); |
| }; |
| return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops, |
| NumLoops, NewCallback); |
| } |
| |
| /// Calls the specified callback function for all the loop bodies in \p |
| /// CurStmt, from the outermost loop to the innermost. |
| static void doForAllLoopsBodies( |
| Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops, |
| llvm::function_ref<void(unsigned, Stmt *, Stmt *)> Callback); |
| static void doForAllLoopsBodies( |
| const Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops, |
| llvm::function_ref<void(unsigned, const Stmt *, const Stmt *)> Callback) { |
| auto &&NewCallback = [Callback](unsigned Cnt, Stmt *Loop, Stmt *Body) { |
| Callback(Cnt, Loop, Body); |
| }; |
| doForAllLoopsBodies(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops, |
| NumLoops, NewCallback); |
| } |
| |
| static bool classof(const Stmt *T) { |
| if (auto *D = dyn_cast<OMPExecutableDirective>(T)) |
| return isOpenMPLoopDirective(D->getDirectiveKind()); |
| return false; |
| } |
| }; |
| |
| /// The base class for all loop transformation directives. |
| class OMPLoopTransformationDirective : public OMPLoopBasedDirective { |
| friend class ASTStmtReader; |
| |
| /// Number of loops generated by this loop transformation. |
| unsigned NumGeneratedLoops = 0; |
| |
| protected: |
| explicit OMPLoopTransformationDirective(StmtClass SC, |
| OpenMPDirectiveKind Kind, |
| SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| unsigned NumAssociatedLoops) |
| : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, NumAssociatedLoops) {} |
| |
| /// Set the number of loops generated by this loop transformation. |
| void setNumGeneratedLoops(unsigned Num) { NumGeneratedLoops = Num; } |
| |
| public: |
| /// Return the number of associated (consumed) loops. |
| unsigned getNumAssociatedLoops() const { return getLoopsNumber(); } |
| |
| /// Return the number of loops generated by this loop transformation. |
| unsigned getNumGeneratedLoops() { return NumGeneratedLoops; } |
| |
| /// Get the de-sugared statements after after the loop transformation. |
| /// |
| /// Might be nullptr if either the directive generates no loops and is handled |
| /// directly in CodeGen, or resolving a template-dependence context is |
| /// required. |
| Stmt *getTransformedStmt() const; |
| |
| /// Return preinits statement. |
| Stmt *getPreInits() const; |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTileDirectiveClass || |
| T->getStmtClass() == OMPUnrollDirectiveClass; |
| } |
| }; |
| |
| /// This is a common base class for loop directives ('omp simd', 'omp |
| /// for', 'omp for simd' etc.). It is responsible for the loop code generation. |
| /// |
| class OMPLoopDirective : public OMPLoopBasedDirective { |
| friend class ASTStmtReader; |
| |
| /// Offsets to the stored exprs. |
| /// This enumeration contains offsets to all the pointers to children |
| /// expressions stored in OMPLoopDirective. |
| /// The first 9 children are necessary for all the loop directives, |
| /// the next 8 are specific to the worksharing ones, and the next 11 are |
| /// used for combined constructs containing two pragmas associated to loops. |
| /// After the fixed children, three arrays of length NumAssociatedLoops are |
| /// allocated: loop counters, their updates and final values. |
| /// PrevLowerBound and PrevUpperBound are used to communicate blocking |
| /// information in composite constructs which require loop blocking |
| /// DistInc is used to generate the increment expression for the distribute |
| /// loop when combined with a further nested loop |
| /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the |
| /// for loop when combined with a previous distribute loop in the same pragma |
| /// (e.g. 'distribute parallel for') |
| /// |
| enum { |
| IterationVariableOffset = 0, |
| LastIterationOffset = 1, |
| CalcLastIterationOffset = 2, |
| PreConditionOffset = 3, |
| CondOffset = 4, |
| InitOffset = 5, |
| IncOffset = 6, |
| PreInitsOffset = 7, |
| // The '...End' enumerators do not correspond to child expressions - they |
| // specify the offset to the end (and start of the following counters/ |
| // updates/finals/dependent_counters/dependent_inits/finals_conditions |
| // arrays). |
| DefaultEnd = 8, |
| // The following 8 exprs are used by worksharing and distribute loops only. |
| IsLastIterVariableOffset = 8, |
| LowerBoundVariableOffset = 9, |
| UpperBoundVariableOffset = 10, |
| StrideVariableOffset = 11, |
| EnsureUpperBoundOffset = 12, |
| NextLowerBoundOffset = 13, |
| NextUpperBoundOffset = 14, |
| NumIterationsOffset = 15, |
| // Offset to the end for worksharing loop directives. |
| WorksharingEnd = 16, |
| PrevLowerBoundVariableOffset = 16, |
| PrevUpperBoundVariableOffset = 17, |
| DistIncOffset = 18, |
| PrevEnsureUpperBoundOffset = 19, |
| CombinedLowerBoundVariableOffset = 20, |
| CombinedUpperBoundVariableOffset = 21, |
| CombinedEnsureUpperBoundOffset = 22, |
| CombinedInitOffset = 23, |
| CombinedConditionOffset = 24, |
| CombinedNextLowerBoundOffset = 25, |
| CombinedNextUpperBoundOffset = 26, |
| CombinedDistConditionOffset = 27, |
| CombinedParForInDistConditionOffset = 28, |
| // Offset to the end (and start of the following |
| // counters/updates/finals/dependent_counters/dependent_inits/finals_conditions |
| // arrays) for combined distribute loop directives. |
| CombinedDistributeEnd = 29, |
| }; |
| |
| /// Get the counters storage. |
| MutableArrayRef<Expr *> getCounters() { |
| auto **Storage = reinterpret_cast<Expr **>( |
| &Data->getChildren()[getArraysOffset(getDirectiveKind())]); |
| return llvm::makeMutableArrayRef(Storage, getLoopsNumber()); |
| } |
| |
| /// Get the private counters storage. |
| MutableArrayRef<Expr *> getPrivateCounters() { |
| auto **Storage = reinterpret_cast<Expr **>( |
| &Data->getChildren()[getArraysOffset(getDirectiveKind()) + |
| getLoopsNumber()]); |
| return llvm::makeMutableArrayRef(Storage, getLoopsNumber()); |
| } |
| |
| /// Get the updates storage. |
| MutableArrayRef<Expr *> getInits() { |
| auto **Storage = reinterpret_cast<Expr **>( |
| &Data->getChildren()[getArraysOffset(getDirectiveKind()) + |
| 2 * getLoopsNumber()]); |
| return llvm::makeMutableArrayRef(Storage, getLoopsNumber()); |
| } |
| |
| /// Get the updates storage. |
| MutableArrayRef<Expr *> getUpdates() { |
| auto **Storage = reinterpret_cast<Expr **>( |
| &Data->getChildren()[getArraysOffset(getDirectiveKind()) + |
| 3 * getLoopsNumber()]); |
| return llvm::makeMutableArrayRef(Storage, getLoopsNumber()); |
| } |
| |
| /// Get the final counter updates storage. |
| MutableArrayRef<Expr *> getFinals() { |
| auto **Storage = reinterpret_cast<Expr **>( |
| &Data->getChildren()[getArraysOffset(getDirectiveKind()) + |
| 4 * getLoopsNumber()]); |
| return llvm::makeMutableArrayRef(Storage, getLoopsNumber()); |
| } |
| |
| /// Get the dependent counters storage. |
| MutableArrayRef<Expr *> getDependentCounters() { |
| auto **Storage = reinterpret_cast<Expr **>( |
| &Data->getChildren()[getArraysOffset(getDirectiveKind()) + |
| 5 * getLoopsNumber()]); |
| return llvm::makeMutableArrayRef(Storage, getLoopsNumber()); |
| } |
| |
| /// Get the dependent inits storage. |
| MutableArrayRef<Expr *> getDependentInits() { |
| auto **Storage = reinterpret_cast<Expr **>( |
| &Data->getChildren()[getArraysOffset(getDirectiveKind()) + |
| 6 * getLoopsNumber()]); |
| return llvm::makeMutableArrayRef(Storage, getLoopsNumber()); |
| } |
| |
| /// Get the finals conditions storage. |
| MutableArrayRef<Expr *> getFinalsConditions() { |
| auto **Storage = reinterpret_cast<Expr **>( |
| &Data->getChildren()[getArraysOffset(getDirectiveKind()) + |
| 7 * getLoopsNumber()]); |
| return llvm::makeMutableArrayRef(Storage, getLoopsNumber()); |
| } |
| |
| protected: |
| /// Build instance of loop directive of class \a Kind. |
| /// |
| /// \param SC Statement class. |
| /// \param Kind Kind of OpenMP directive. |
| /// \param StartLoc Starting location of the directive (directive keyword). |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed loops from 'collapse' clause. |
| /// |
| OMPLoopDirective(StmtClass SC, OpenMPDirectiveKind Kind, |
| SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, CollapsedNum) {} |
| |
| /// Offset to the start of children expression arrays. |
| static unsigned getArraysOffset(OpenMPDirectiveKind Kind) { |
| if (isOpenMPLoopBoundSharingDirective(Kind)) |
| return CombinedDistributeEnd; |
| if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) || |
| isOpenMPGenericLoopDirective(Kind) || isOpenMPDistributeDirective(Kind)) |
| return WorksharingEnd; |
| return DefaultEnd; |
| } |
| |
| /// Children number. |
| static unsigned numLoopChildren(unsigned CollapsedNum, |
| OpenMPDirectiveKind Kind) { |
| return getArraysOffset(Kind) + |
| 8 * CollapsedNum; // Counters, PrivateCounters, Inits, |
| // Updates, Finals, DependentCounters, |
| // DependentInits, FinalsConditions. |
| } |
| |
| void setIterationVariable(Expr *IV) { |
| Data->getChildren()[IterationVariableOffset] = IV; |
| } |
| void setLastIteration(Expr *LI) { |
| Data->getChildren()[LastIterationOffset] = LI; |
| } |
| void setCalcLastIteration(Expr *CLI) { |
| Data->getChildren()[CalcLastIterationOffset] = CLI; |
| } |
| void setPreCond(Expr *PC) { Data->getChildren()[PreConditionOffset] = PC; } |
| void setCond(Expr *Cond) { Data->getChildren()[CondOffset] = Cond; } |
| void setInit(Expr *Init) { Data->getChildren()[InitOffset] = Init; } |
| void setInc(Expr *Inc) { Data->getChildren()[IncOffset] = Inc; } |
| void setPreInits(Stmt *PreInits) { |
| Data->getChildren()[PreInitsOffset] = PreInits; |
| } |
| void setIsLastIterVariable(Expr *IL) { |
| assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
| isOpenMPGenericLoopDirective(getDirectiveKind()) || |
| isOpenMPTaskLoopDirective(getDirectiveKind()) || |
| isOpenMPDistributeDirective(getDirectiveKind())) && |
| "expected worksharing loop directive"); |
| Data->getChildren()[IsLastIterVariableOffset] = IL; |
| } |
| void setLowerBoundVariable(Expr *LB) { |
| assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
| isOpenMPGenericLoopDirective(getDirectiveKind()) || |
| isOpenMPTaskLoopDirective(getDirectiveKind()) || |
| isOpenMPDistributeDirective(getDirectiveKind())) && |
| "expected worksharing loop directive"); |
| Data->getChildren()[LowerBoundVariableOffset] = LB; |
| } |
| void setUpperBoundVariable(Expr *UB) { |
| assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
| isOpenMPGenericLoopDirective(getDirectiveKind()) || |
| isOpenMPTaskLoopDirective(getDirectiveKind()) || |
| isOpenMPDistributeDirective(getDirectiveKind())) && |
| "expected worksharing loop directive"); |
| Data->getChildren()[UpperBoundVariableOffset] = UB; |
| } |
| void setStrideVariable(Expr *ST) { |
| assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
| isOpenMPGenericLoopDirective(getDirectiveKind()) || |
| isOpenMPTaskLoopDirective(getDirectiveKind()) || |
| isOpenMPDistributeDirective(getDirectiveKind())) && |
| "expected worksharing loop directive"); |
| Data->getChildren()[StrideVariableOffset] = ST; |
| } |
| void setEnsureUpperBound(Expr *EUB) { |
| assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
| isOpenMPGenericLoopDirective(getDirectiveKind()) || |
| isOpenMPTaskLoopDirective(getDirectiveKind()) || |
| isOpenMPDistributeDirective(getDirectiveKind())) && |
| "expected worksharing loop directive"); |
| Data->getChildren()[EnsureUpperBoundOffset] = EUB; |
| } |
| void setNextLowerBound(Expr *NLB) { |
| assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
| isOpenMPGenericLoopDirective(getDirectiveKind()) || |
| isOpenMPTaskLoopDirective(getDirectiveKind()) || |
| isOpenMPDistributeDirective(getDirectiveKind())) && |
| "expected worksharing loop directive"); |
| Data->getChildren()[NextLowerBoundOffset] = NLB; |
| } |
| void setNextUpperBound(Expr *NUB) { |
| assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
| isOpenMPGenericLoopDirective(getDirectiveKind()) || |
| isOpenMPTaskLoopDirective(getDirectiveKind()) || |
| isOpenMPDistributeDirective(getDirectiveKind())) && |
| "expected worksharing loop directive"); |
| Data->getChildren()[NextUpperBoundOffset] = NUB; |
| } |
| void setNumIterations(Expr *NI) { |
| assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
| isOpenMPGenericLoopDirective(getDirectiveKind()) || |
| isOpenMPTaskLoopDirective(getDirectiveKind()) || |
| isOpenMPDistributeDirective(getDirectiveKind())) && |
| "expected worksharing loop directive"); |
| Data->getChildren()[NumIterationsOffset] = NI; |
| } |
| void setPrevLowerBoundVariable(Expr *PrevLB) { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| Data->getChildren()[PrevLowerBoundVariableOffset] = PrevLB; |
| } |
| void setPrevUpperBoundVariable(Expr *PrevUB) { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| Data->getChildren()[PrevUpperBoundVariableOffset] = PrevUB; |
| } |
| void setDistInc(Expr *DistInc) { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| Data->getChildren()[DistIncOffset] = DistInc; |
| } |
| void setPrevEnsureUpperBound(Expr *PrevEUB) { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| Data->getChildren()[PrevEnsureUpperBoundOffset] = PrevEUB; |
| } |
| void setCombinedLowerBoundVariable(Expr *CombLB) { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| Data->getChildren()[CombinedLowerBoundVariableOffset] = CombLB; |
| } |
| void setCombinedUpperBoundVariable(Expr *CombUB) { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| Data->getChildren()[CombinedUpperBoundVariableOffset] = CombUB; |
| } |
| void setCombinedEnsureUpperBound(Expr *CombEUB) { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| Data->getChildren()[CombinedEnsureUpperBoundOffset] = CombEUB; |
| } |
| void setCombinedInit(Expr *CombInit) { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| Data->getChildren()[CombinedInitOffset] = CombInit; |
| } |
| void setCombinedCond(Expr *CombCond) { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| Data->getChildren()[CombinedConditionOffset] = CombCond; |
| } |
| void setCombinedNextLowerBound(Expr *CombNLB) { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| Data->getChildren()[CombinedNextLowerBoundOffset] = CombNLB; |
| } |
| void setCombinedNextUpperBound(Expr *CombNUB) { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| Data->getChildren()[CombinedNextUpperBoundOffset] = CombNUB; |
| } |
| void setCombinedDistCond(Expr *CombDistCond) { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound distribute sharing directive"); |
| Data->getChildren()[CombinedDistConditionOffset] = CombDistCond; |
| } |
| void setCombinedParForInDistCond(Expr *CombParForInDistCond) { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound distribute sharing directive"); |
| Data->getChildren()[CombinedParForInDistConditionOffset] = |
| CombParForInDistCond; |
| } |
| void setCounters(ArrayRef<Expr *> A); |
| void setPrivateCounters(ArrayRef<Expr *> A); |
| void setInits(ArrayRef<Expr *> A); |
| void setUpdates(ArrayRef<Expr *> A); |
| void setFinals(ArrayRef<Expr *> A); |
| void setDependentCounters(ArrayRef<Expr *> A); |
| void setDependentInits(ArrayRef<Expr *> A); |
| void setFinalsConditions(ArrayRef<Expr *> A); |
| |
| public: |
| Expr *getIterationVariable() const { |
| return cast<Expr>(Data->getChildren()[IterationVariableOffset]); |
| } |
| Expr *getLastIteration() const { |
| return cast<Expr>(Data->getChildren()[LastIterationOffset]); |
| } |
| Expr *getCalcLastIteration() const { |
| return cast<Expr>(Data->getChildren()[CalcLastIterationOffset]); |
| } |
| Expr *getPreCond() const { |
| return cast<Expr>(Data->getChildren()[PreConditionOffset]); |
| } |
| Expr *getCond() const { return cast<Expr>(Data->getChildren()[CondOffset]); } |
| Expr *getInit() const { return cast<Expr>(Data->getChildren()[InitOffset]); } |
| Expr *getInc() const { return cast<Expr>(Data->getChildren()[IncOffset]); } |
| const Stmt *getPreInits() const { |
| return Data->getChildren()[PreInitsOffset]; |
| } |
| Stmt *getPreInits() { return Data->getChildren()[PreInitsOffset]; } |
| Expr *getIsLastIterVariable() const { |
| assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
| isOpenMPGenericLoopDirective(getDirectiveKind()) || |
| isOpenMPTaskLoopDirective(getDirectiveKind()) || |
| isOpenMPDistributeDirective(getDirectiveKind())) && |
| "expected worksharing loop directive"); |
| return cast<Expr>(Data->getChildren()[IsLastIterVariableOffset]); |
| } |
| Expr *getLowerBoundVariable() const { |
| assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
| isOpenMPGenericLoopDirective(getDirectiveKind()) || |
| isOpenMPTaskLoopDirective(getDirectiveKind()) || |
| isOpenMPDistributeDirective(getDirectiveKind())) && |
| "expected worksharing loop directive"); |
| return cast<Expr>(Data->getChildren()[LowerBoundVariableOffset]); |
| } |
| Expr *getUpperBoundVariable() const { |
| assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
| isOpenMPGenericLoopDirective(getDirectiveKind()) || |
| isOpenMPTaskLoopDirective(getDirectiveKind()) || |
| isOpenMPDistributeDirective(getDirectiveKind())) && |
| "expected worksharing loop directive"); |
| return cast<Expr>(Data->getChildren()[UpperBoundVariableOffset]); |
| } |
| Expr *getStrideVariable() const { |
| assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
| isOpenMPGenericLoopDirective(getDirectiveKind()) || |
| isOpenMPTaskLoopDirective(getDirectiveKind()) || |
| isOpenMPDistributeDirective(getDirectiveKind())) && |
| "expected worksharing loop directive"); |
| return cast<Expr>(Data->getChildren()[StrideVariableOffset]); |
| } |
| Expr *getEnsureUpperBound() const { |
| assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
| isOpenMPGenericLoopDirective(getDirectiveKind()) || |
| isOpenMPTaskLoopDirective(getDirectiveKind()) || |
| isOpenMPDistributeDirective(getDirectiveKind())) && |
| "expected worksharing loop directive"); |
| return cast<Expr>(Data->getChildren()[EnsureUpperBoundOffset]); |
| } |
| Expr *getNextLowerBound() const { |
| assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
| isOpenMPGenericLoopDirective(getDirectiveKind()) || |
| isOpenMPTaskLoopDirective(getDirectiveKind()) || |
| isOpenMPDistributeDirective(getDirectiveKind())) && |
| "expected worksharing loop directive"); |
| return cast<Expr>(Data->getChildren()[NextLowerBoundOffset]); |
| } |
| Expr *getNextUpperBound() const { |
| assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
| isOpenMPGenericLoopDirective(getDirectiveKind()) || |
| isOpenMPTaskLoopDirective(getDirectiveKind()) || |
| isOpenMPDistributeDirective(getDirectiveKind())) && |
| "expected worksharing loop directive"); |
| return cast<Expr>(Data->getChildren()[NextUpperBoundOffset]); |
| } |
| Expr *getNumIterations() const { |
| assert((isOpenMPWorksharingDirective(getDirectiveKind()) || |
| isOpenMPGenericLoopDirective(getDirectiveKind()) || |
| isOpenMPTaskLoopDirective(getDirectiveKind()) || |
| isOpenMPDistributeDirective(getDirectiveKind())) && |
| "expected worksharing loop directive"); |
| return cast<Expr>(Data->getChildren()[NumIterationsOffset]); |
| } |
| Expr *getPrevLowerBoundVariable() const { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| return cast<Expr>(Data->getChildren()[PrevLowerBoundVariableOffset]); |
| } |
| Expr *getPrevUpperBoundVariable() const { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| return cast<Expr>(Data->getChildren()[PrevUpperBoundVariableOffset]); |
| } |
| Expr *getDistInc() const { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| return cast<Expr>(Data->getChildren()[DistIncOffset]); |
| } |
| Expr *getPrevEnsureUpperBound() const { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| return cast<Expr>(Data->getChildren()[PrevEnsureUpperBoundOffset]); |
| } |
| Expr *getCombinedLowerBoundVariable() const { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| return cast<Expr>(Data->getChildren()[CombinedLowerBoundVariableOffset]); |
| } |
| Expr *getCombinedUpperBoundVariable() const { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| return cast<Expr>(Data->getChildren()[CombinedUpperBoundVariableOffset]); |
| } |
| Expr *getCombinedEnsureUpperBound() const { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| return cast<Expr>(Data->getChildren()[CombinedEnsureUpperBoundOffset]); |
| } |
| Expr *getCombinedInit() const { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| return cast<Expr>(Data->getChildren()[CombinedInitOffset]); |
| } |
| Expr *getCombinedCond() const { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| return cast<Expr>(Data->getChildren()[CombinedConditionOffset]); |
| } |
| Expr *getCombinedNextLowerBound() const { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| return cast<Expr>(Data->getChildren()[CombinedNextLowerBoundOffset]); |
| } |
| Expr *getCombinedNextUpperBound() const { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound sharing directive"); |
| return cast<Expr>(Data->getChildren()[CombinedNextUpperBoundOffset]); |
| } |
| Expr *getCombinedDistCond() const { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound distribute sharing directive"); |
| return cast<Expr>(Data->getChildren()[CombinedDistConditionOffset]); |
| } |
| Expr *getCombinedParForInDistCond() const { |
| assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && |
| "expected loop bound distribute sharing directive"); |
| return cast<Expr>(Data->getChildren()[CombinedParForInDistConditionOffset]); |
| } |
| Stmt *getBody(); |
| const Stmt *getBody() const { |
| return const_cast<OMPLoopDirective *>(this)->getBody(); |
| } |
| |
| ArrayRef<Expr *> counters() { return getCounters(); } |
| |
| ArrayRef<Expr *> counters() const { |
| return const_cast<OMPLoopDirective *>(this)->getCounters(); |
| } |
| |
| ArrayRef<Expr *> private_counters() { return getPrivateCounters(); } |
| |
| ArrayRef<Expr *> private_counters() const { |
| return const_cast<OMPLoopDirective *>(this)->getPrivateCounters(); |
| } |
| |
| ArrayRef<Expr *> inits() { return getInits(); } |
| |
| ArrayRef<Expr *> inits() const { |
| return const_cast<OMPLoopDirective *>(this)->getInits(); |
| } |
| |
| ArrayRef<Expr *> updates() { return getUpdates(); } |
| |
| ArrayRef<Expr *> updates() const { |
| return const_cast<OMPLoopDirective *>(this)->getUpdates(); |
| } |
| |
| ArrayRef<Expr *> finals() { return getFinals(); } |
| |
| ArrayRef<Expr *> finals() const { |
| return const_cast<OMPLoopDirective *>(this)->getFinals(); |
| } |
| |
| ArrayRef<Expr *> dependent_counters() { return getDependentCounters(); } |
| |
| ArrayRef<Expr *> dependent_counters() const { |
| return const_cast<OMPLoopDirective *>(this)->getDependentCounters(); |
| } |
| |
| ArrayRef<Expr *> dependent_inits() { return getDependentInits(); } |
| |
| ArrayRef<Expr *> dependent_inits() const { |
| return const_cast<OMPLoopDirective *>(this)->getDependentInits(); |
| } |
| |
| ArrayRef<Expr *> finals_conditions() { return getFinalsConditions(); } |
| |
| ArrayRef<Expr *> finals_conditions() const { |
| return const_cast<OMPLoopDirective *>(this)->getFinalsConditions(); |
| } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPSimdDirectiveClass || |
| T->getStmtClass() == OMPForDirectiveClass || |
| T->getStmtClass() == OMPForSimdDirectiveClass || |
| T->getStmtClass() == OMPParallelForDirectiveClass || |
| T->getStmtClass() == OMPParallelForSimdDirectiveClass || |
| T->getStmtClass() == OMPTaskLoopDirectiveClass || |
| T->getStmtClass() == OMPTaskLoopSimdDirectiveClass || |
| T->getStmtClass() == OMPMasterTaskLoopDirectiveClass || |
| T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass || |
| T->getStmtClass() == OMPGenericLoopDirectiveClass || |
| T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass || |
| T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass || |
| T->getStmtClass() == OMPDistributeDirectiveClass || |
| T->getStmtClass() == OMPTargetParallelForDirectiveClass || |
| T->getStmtClass() == OMPDistributeParallelForDirectiveClass || |
| T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass || |
| T->getStmtClass() == OMPDistributeSimdDirectiveClass || |
| T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass || |
| T->getStmtClass() == OMPTargetSimdDirectiveClass || |
| T->getStmtClass() == OMPTeamsDistributeDirectiveClass || |
| T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass || |
| T->getStmtClass() == |
| OMPTeamsDistributeParallelForSimdDirectiveClass || |
| T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass || |
| T->getStmtClass() == |
| OMPTargetTeamsDistributeParallelForDirectiveClass || |
| T->getStmtClass() == |
| OMPTargetTeamsDistributeParallelForSimdDirectiveClass || |
| T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass || |
| T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp simd' directive. |
| /// |
| /// \code |
| /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d) |
| /// \endcode |
| /// In this example directive '#pragma omp simd' has clauses 'private' |
| /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and |
| /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. |
| /// |
| class OMPSimdDirective : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, StartLoc, |
| EndLoc, CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPSimdDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, |
| SourceLocation(), SourceLocation(), CollapsedNum) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// |
| static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc, |
| SourceLocation EndLoc, unsigned CollapsedNum, |
| ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, |
| const HelperExprs &Exprs); |
| |
| /// Creates an empty directive with the place |
| /// for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, |
| unsigned CollapsedNum, EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPSimdDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp for' directive. |
| /// |
| /// \code |
| /// #pragma omp for private(a,b) reduction(+:c,d) |
| /// \endcode |
| /// In this example directive '#pragma omp for' has clauses 'private' with the |
| /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c' |
| /// and 'd'. |
| /// |
| class OMPForDirective : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// true if current directive has inner cancel directive. |
| bool HasCancel = false; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, StartLoc, |
| EndLoc, CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPForDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, |
| SourceLocation(), SourceLocation(), CollapsedNum) {} |
| |
| /// Sets special task reduction descriptor. |
| void setTaskReductionRefExpr(Expr *E) { |
| Data->getChildren()[numLoopChildren(getLoopsNumber(), |
| llvm::omp::OMPD_for)] = E; |
| } |
| |
| /// Set cancel state. |
| void setHasCancel(bool Has) { HasCancel = Has; } |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// \param TaskRedRef Task reduction special reference expression to handle |
| /// taskgroup descriptor. |
| /// \param HasCancel true if current directive has inner cancel directive. |
| /// |
| static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc, |
| SourceLocation EndLoc, unsigned CollapsedNum, |
| ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs, |
| Expr *TaskRedRef, bool HasCancel); |
| |
| /// Creates an empty directive with the place |
| /// for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, |
| unsigned CollapsedNum, EmptyShell); |
| |
| /// Returns special task reduction reference expression. |
| Expr *getTaskReductionRefExpr() { |
| return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( |
| getLoopsNumber(), llvm::omp::OMPD_for)]); |
| } |
| const Expr *getTaskReductionRefExpr() const { |
| return const_cast<OMPForDirective *>(this)->getTaskReductionRefExpr(); |
| } |
| |
| /// Return true if current directive has inner cancel directive. |
| bool hasCancel() const { return HasCancel; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPForDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp for simd' directive. |
| /// |
| /// \code |
| /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d) |
| /// \endcode |
| /// In this example directive '#pragma omp for simd' has clauses 'private' |
| /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and |
| /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. |
| /// |
| class OMPForSimdDirective : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd, |
| StartLoc, EndLoc, CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPForSimdDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd, |
| SourceLocation(), SourceLocation(), CollapsedNum) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// |
| static OMPForSimdDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs); |
| |
| /// Creates an empty directive with the place |
| /// for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPForSimdDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, |
| unsigned CollapsedNum, EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPForSimdDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp sections' directive. |
| /// |
| /// \code |
| /// #pragma omp sections private(a,b) reduction(+:c,d) |
| /// \endcode |
| /// In this example directive '#pragma omp sections' has clauses 'private' with |
| /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables |
| /// 'c' and 'd'. |
| /// |
| class OMPSectionsDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// true if current directive has inner cancel directive. |
| bool HasCancel = false; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPSectionsDirectiveClass, |
| llvm::omp::OMPD_sections, StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPSectionsDirective() |
| : OMPExecutableDirective(OMPSectionsDirectiveClass, |
| llvm::omp::OMPD_sections, SourceLocation(), |
| SourceLocation()) {} |
| |
| /// Sets special task reduction descriptor. |
| void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } |
| |
| /// Set cancel state. |
| void setHasCancel(bool Has) { HasCancel = Has; } |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param TaskRedRef Task reduction special reference expression to handle |
| /// taskgroup descriptor. |
| /// \param HasCancel true if current directive has inner directive. |
| /// |
| static OMPSectionsDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, |
| bool HasCancel); |
| |
| /// Creates an empty directive with the place for \a NumClauses |
| /// clauses. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPSectionsDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, EmptyShell); |
| |
| /// Returns special task reduction reference expression. |
| Expr *getTaskReductionRefExpr() { |
| return cast_or_null<Expr>(Data->getChildren()[0]); |
| } |
| const Expr *getTaskReductionRefExpr() const { |
| return const_cast<OMPSectionsDirective *>(this)->getTaskReductionRefExpr(); |
| } |
| |
| /// Return true if current directive has inner cancel directive. |
| bool hasCancel() const { return HasCancel; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPSectionsDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp section' directive. |
| /// |
| /// \code |
| /// #pragma omp section |
| /// \endcode |
| /// |
| class OMPSectionDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// true if current directive has inner cancel directive. |
| bool HasCancel = false; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPSectionDirectiveClass, |
| llvm::omp::OMPD_section, StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPSectionDirective() |
| : OMPExecutableDirective(OMPSectionDirectiveClass, |
| llvm::omp::OMPD_section, SourceLocation(), |
| SourceLocation()) {} |
| |
| public: |
| /// Creates directive. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param HasCancel true if current directive has inner directive. |
| /// |
| static OMPSectionDirective *Create(const ASTContext &C, |
| SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| Stmt *AssociatedStmt, bool HasCancel); |
| |
| /// Creates an empty directive. |
| /// |
| /// \param C AST context. |
| /// |
| static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell); |
| |
| /// Set cancel state. |
| void setHasCancel(bool Has) { HasCancel = Has; } |
| |
| /// Return true if current directive has inner cancel directive. |
| bool hasCancel() const { return HasCancel; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPSectionDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp single' directive. |
| /// |
| /// \code |
| /// #pragma omp single private(a,b) copyprivate(c,d) |
| /// \endcode |
| /// In this example directive '#pragma omp single' has clauses 'private' with |
| /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'. |
| /// |
| class OMPSingleDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single, |
| StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPSingleDirective() |
| : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single, |
| SourceLocation(), SourceLocation()) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// |
| static OMPSingleDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); |
| |
| /// Creates an empty directive with the place for \a NumClauses |
| /// clauses. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPSingleDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPSingleDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp master' directive. |
| /// |
| /// \code |
| /// #pragma omp master |
| /// \endcode |
| /// |
| class OMPMasterDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master, |
| StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPMasterDirective() |
| : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master, |
| SourceLocation(), SourceLocation()) {} |
| |
| public: |
| /// Creates directive. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// |
| static OMPMasterDirective *Create(const ASTContext &C, |
| SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| Stmt *AssociatedStmt); |
| |
| /// Creates an empty directive. |
| /// |
| /// \param C AST context. |
| /// |
| static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPMasterDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp critical' directive. |
| /// |
| /// \code |
| /// #pragma omp critical |
| /// \endcode |
| /// |
| class OMPCriticalDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Name of the directive. |
| DeclarationNameInfo DirName; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param Name Name of the directive. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc, |
| SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPCriticalDirectiveClass, |
| llvm::omp::OMPD_critical, StartLoc, EndLoc), |
| DirName(Name) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPCriticalDirective() |
| : OMPExecutableDirective(OMPCriticalDirectiveClass, |
| llvm::omp::OMPD_critical, SourceLocation(), |
| SourceLocation()) {} |
| |
| /// Set name of the directive. |
| /// |
| /// \param Name Name of the directive. |
| /// |
| void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; } |
| |
| public: |
| /// Creates directive. |
| /// |
| /// \param C AST context. |
| /// \param Name Name of the directive. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// |
| static OMPCriticalDirective * |
| Create(const ASTContext &C, const DeclarationNameInfo &Name, |
| SourceLocation StartLoc, SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); |
| |
| /// Creates an empty directive. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPCriticalDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, EmptyShell); |
| |
| /// Return name of the directive. |
| /// |
| DeclarationNameInfo getDirectiveName() const { return DirName; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPCriticalDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp parallel for' directive. |
| /// |
| /// \code |
| /// #pragma omp parallel for private(a,b) reduction(+:c,d) |
| /// \endcode |
| /// In this example directive '#pragma omp parallel for' has clauses 'private' |
| /// with the variables 'a' and 'b' and 'reduction' with operator '+' and |
| /// variables 'c' and 'd'. |
| /// |
| class OMPParallelForDirective : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// true if current region has inner cancel directive. |
| bool HasCancel = false; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPParallelForDirectiveClass, |
| llvm::omp::OMPD_parallel_for, StartLoc, EndLoc, |
| CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPParallelForDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPParallelForDirectiveClass, |
| llvm::omp::OMPD_parallel_for, SourceLocation(), |
| SourceLocation(), CollapsedNum) {} |
| |
| /// Sets special task reduction descriptor. |
| void setTaskReductionRefExpr(Expr *E) { |
| Data->getChildren()[numLoopChildren(getLoopsNumber(), |
| llvm::omp::OMPD_parallel_for)] = E; |
| } |
| |
| /// Set cancel state. |
| void setHasCancel(bool Has) { HasCancel = Has; } |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// \param TaskRedRef Task reduction special reference expression to handle |
| /// taskgroup descriptor. |
| /// \param HasCancel true if current directive has inner cancel directive. |
| /// |
| static OMPParallelForDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, |
| bool HasCancel); |
| |
| /// Creates an empty directive with the place |
| /// for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPParallelForDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, |
| unsigned CollapsedNum, |
| EmptyShell); |
| |
| /// Returns special task reduction reference expression. |
| Expr *getTaskReductionRefExpr() { |
| return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( |
| getLoopsNumber(), llvm::omp::OMPD_parallel_for)]); |
| } |
| const Expr *getTaskReductionRefExpr() const { |
| return const_cast<OMPParallelForDirective *>(this) |
| ->getTaskReductionRefExpr(); |
| } |
| |
| /// Return true if current directive has inner cancel directive. |
| bool hasCancel() const { return HasCancel; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPParallelForDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp parallel for simd' directive. |
| /// |
| /// \code |
| /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d) |
| /// \endcode |
| /// In this example directive '#pragma omp parallel for simd' has clauses |
| /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j' |
| /// and linear step 's', 'reduction' with operator '+' and variables 'c' and |
| /// 'd'. |
| /// |
| class OMPParallelForSimdDirective : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPParallelForSimdDirectiveClass, |
| llvm::omp::OMPD_parallel_for_simd, StartLoc, EndLoc, |
| CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPParallelForSimdDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPParallelForSimdDirectiveClass, |
| llvm::omp::OMPD_parallel_for_simd, SourceLocation(), |
| SourceLocation(), CollapsedNum) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// |
| static OMPParallelForSimdDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs); |
| |
| /// Creates an empty directive with the place |
| /// for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, |
| unsigned CollapsedNum, |
| EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPParallelForSimdDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp parallel master' directive. |
| /// |
| /// \code |
| /// #pragma omp parallel master private(a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp parallel master' has clauses |
| /// 'private' with the variables 'a' and 'b' |
| /// |
| class OMPParallelMasterDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| OMPParallelMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPParallelMasterDirectiveClass, |
| llvm::omp::OMPD_parallel_master, StartLoc, |
| EndLoc) {} |
| |
| explicit OMPParallelMasterDirective() |
| : OMPExecutableDirective(OMPParallelMasterDirectiveClass, |
| llvm::omp::OMPD_parallel_master, |
| SourceLocation(), SourceLocation()) {} |
| |
| /// Sets special task reduction descriptor. |
| void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param TaskRedRef Task reduction special reference expression to handle |
| /// taskgroup descriptor. |
| /// |
| static OMPParallelMasterDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef); |
| |
| /// Creates an empty directive with the place for \a NumClauses |
| /// clauses. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPParallelMasterDirective * |
| CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); |
| |
| /// Returns special task reduction reference expression. |
| Expr *getTaskReductionRefExpr() { |
| return cast_or_null<Expr>(Data->getChildren()[0]); |
| } |
| const Expr *getTaskReductionRefExpr() const { |
| return const_cast<OMPParallelMasterDirective *>(this) |
| ->getTaskReductionRefExpr(); |
| } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPParallelMasterDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp parallel sections' directive. |
| /// |
| /// \code |
| /// #pragma omp parallel sections private(a,b) reduction(+:c,d) |
| /// \endcode |
| /// In this example directive '#pragma omp parallel sections' has clauses |
| /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' |
| /// and variables 'c' and 'd'. |
| /// |
| class OMPParallelSectionsDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// true if current directive has inner cancel directive. |
| bool HasCancel = false; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPParallelSectionsDirectiveClass, |
| llvm::omp::OMPD_parallel_sections, StartLoc, |
| EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPParallelSectionsDirective() |
| : OMPExecutableDirective(OMPParallelSectionsDirectiveClass, |
| llvm::omp::OMPD_parallel_sections, |
| SourceLocation(), SourceLocation()) {} |
| |
| /// Sets special task reduction descriptor. |
| void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } |
| |
| /// Set cancel state. |
| void setHasCancel(bool Has) { HasCancel = Has; } |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param TaskRedRef Task reduction special reference expression to handle |
| /// taskgroup descriptor. |
| /// \param HasCancel true if current directive has inner cancel directive. |
| /// |
| static OMPParallelSectionsDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, |
| bool HasCancel); |
| |
| /// Creates an empty directive with the place for \a NumClauses |
| /// clauses. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPParallelSectionsDirective * |
| CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); |
| |
| /// Returns special task reduction reference expression. |
| Expr *getTaskReductionRefExpr() { |
| return cast_or_null<Expr>(Data->getChildren()[0]); |
| } |
| const Expr *getTaskReductionRefExpr() const { |
| return const_cast<OMPParallelSectionsDirective *>(this) |
| ->getTaskReductionRefExpr(); |
| } |
| |
| /// Return true if current directive has inner cancel directive. |
| bool hasCancel() const { return HasCancel; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPParallelSectionsDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp task' directive. |
| /// |
| /// \code |
| /// #pragma omp task private(a,b) final(d) |
| /// \endcode |
| /// In this example directive '#pragma omp task' has clauses 'private' with the |
| /// variables 'a' and 'b' and 'final' with condition 'd'. |
| /// |
| class OMPTaskDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// true if this directive has inner cancel directive. |
| bool HasCancel = false; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task, |
| StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPTaskDirective() |
| : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task, |
| SourceLocation(), SourceLocation()) {} |
| |
| /// Set cancel state. |
| void setHasCancel(bool Has) { HasCancel = Has; } |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param HasCancel true, if current directive has inner cancel directive. |
| /// |
| static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, bool HasCancel); |
| |
| /// Creates an empty directive with the place for \a NumClauses |
| /// clauses. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, |
| EmptyShell); |
| |
| /// Return true if current directive has inner cancel directive. |
| bool hasCancel() const { return HasCancel; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTaskDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp taskyield' directive. |
| /// |
| /// \code |
| /// #pragma omp taskyield |
| /// \endcode |
| /// |
| class OMPTaskyieldDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPTaskyieldDirectiveClass, |
| llvm::omp::OMPD_taskyield, StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPTaskyieldDirective() |
| : OMPExecutableDirective(OMPTaskyieldDirectiveClass, |
| llvm::omp::OMPD_taskyield, SourceLocation(), |
| SourceLocation()) {} |
| |
| public: |
| /// Creates directive. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// |
| static OMPTaskyieldDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); |
| |
| /// Creates an empty directive. |
| /// |
| /// \param C AST context. |
| /// |
| static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTaskyieldDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp barrier' directive. |
| /// |
| /// \code |
| /// #pragma omp barrier |
| /// \endcode |
| /// |
| class OMPBarrierDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPBarrierDirectiveClass, |
| llvm::omp::OMPD_barrier, StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPBarrierDirective() |
| : OMPExecutableDirective(OMPBarrierDirectiveClass, |
| llvm::omp::OMPD_barrier, SourceLocation(), |
| SourceLocation()) {} |
| |
| public: |
| /// Creates directive. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// |
| static OMPBarrierDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); |
| |
| /// Creates an empty directive. |
| /// |
| /// \param C AST context. |
| /// |
| static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPBarrierDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp taskwait' directive. |
| /// |
| /// \code |
| /// #pragma omp taskwait |
| /// \endcode |
| /// |
| class OMPTaskwaitDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPTaskwaitDirectiveClass, |
| llvm::omp::OMPD_taskwait, StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPTaskwaitDirective() |
| : OMPExecutableDirective(OMPTaskwaitDirectiveClass, |
| llvm::omp::OMPD_taskwait, SourceLocation(), |
| SourceLocation()) {} |
| |
| public: |
| /// Creates directive. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// |
| static OMPTaskwaitDirective *Create(const ASTContext &C, |
| SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses); |
| |
| /// Creates an empty directive. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTaskwaitDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp taskgroup' directive. |
| /// |
| /// \code |
| /// #pragma omp taskgroup |
| /// \endcode |
| /// |
| class OMPTaskgroupDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPTaskgroupDirectiveClass, |
| llvm::omp::OMPD_taskgroup, StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPTaskgroupDirective() |
| : OMPExecutableDirective(OMPTaskgroupDirectiveClass, |
| llvm::omp::OMPD_taskgroup, SourceLocation(), |
| SourceLocation()) {} |
| |
| /// Sets the task_reduction return variable. |
| void setReductionRef(Expr *RR) { Data->getChildren()[0] = RR; } |
| |
| public: |
| /// Creates directive. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param ReductionRef Reference to the task_reduction return variable. |
| /// |
| static OMPTaskgroupDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, |
| Expr *ReductionRef); |
| |
| /// Creates an empty directive. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, EmptyShell); |
| |
| |
| /// Returns reference to the task_reduction return variable. |
| const Expr *getReductionRef() const { |
| return const_cast<OMPTaskgroupDirective *>(this)->getReductionRef(); |
| } |
| Expr *getReductionRef() { return cast_or_null<Expr>(Data->getChildren()[0]); } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTaskgroupDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp flush' directive. |
| /// |
| /// \code |
| /// #pragma omp flush(a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a' |
| /// and 'b'. |
| /// 'omp flush' directive does not have clauses but have an optional list of |
| /// variables to flush. This list of variables is stored within some fake clause |
| /// FlushClause. |
| class OMPFlushDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush, |
| StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPFlushDirective() |
| : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush, |
| SourceLocation(), SourceLocation()) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses (only single OMPFlushClause clause is |
| /// allowed). |
| /// |
| static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses); |
| |
| /// Creates an empty directive with the place for \a NumClauses |
| /// clauses. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPFlushDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPFlushDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp depobj' directive. |
| /// |
| /// \code |
| /// #pragma omp depobj(a) depend(in:x,y) |
| /// \endcode |
| /// In this example directive '#pragma omp depobj' initializes a depobj object |
| /// 'a' with dependence type 'in' and a list with 'x' and 'y' locators. |
| class OMPDepobjDirective final : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPDepobjDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj, |
| StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPDepobjDirective() |
| : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj, |
| SourceLocation(), SourceLocation()) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// |
| static OMPDepobjDirective *Create(const ASTContext &C, |
| SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses); |
| |
| /// Creates an empty directive with the place for \a NumClauses |
| /// clauses. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPDepobjDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPDepobjDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp ordered' directive. |
| /// |
| /// \code |
| /// #pragma omp ordered |
| /// \endcode |
| /// |
| class OMPOrderedDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPOrderedDirectiveClass, |
| llvm::omp::OMPD_ordered, StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPOrderedDirective() |
| : OMPExecutableDirective(OMPOrderedDirectiveClass, |
| llvm::omp::OMPD_ordered, SourceLocation(), |
| SourceLocation()) {} |
| |
| public: |
| /// Creates directive. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// |
| static OMPOrderedDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); |
| |
| /// Creates an empty directive. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses Number of clauses. |
| /// \param IsStandalone true, if the the standalone directive is created. |
| /// |
| static OMPOrderedDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, |
| bool IsStandalone, EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPOrderedDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp atomic' directive. |
| /// |
| /// \code |
| /// #pragma omp atomic capture |
| /// \endcode |
| /// In this example directive '#pragma omp atomic' has clause 'capture'. |
| /// |
| class OMPAtomicDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Used for 'atomic update' or 'atomic capture' constructs. They may |
| /// have atomic expressions of forms |
| /// \code |
| /// x = x binop expr; |
| /// x = expr binop x; |
| /// \endcode |
| /// This field is true for the first form of the expression and false for the |
| /// second. Required for correct codegen of non-associative operations (like |
| /// << or >>). |
| bool IsXLHSInRHSPart = false; |
| /// Used for 'atomic update' or 'atomic capture' constructs. They may |
| /// have atomic expressions of forms |
| /// \code |
| /// v = x; <update x>; |
| /// <update x>; v = x; |
| /// \endcode |
| /// This field is true for the first(postfix) form of the expression and false |
| /// otherwise. |
| bool IsPostfixUpdate = false; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic, |
| StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPAtomicDirective() |
| : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic, |
| SourceLocation(), SourceLocation()) {} |
| |
| enum DataPositionTy : size_t { |
| POS_X = 0, |
| POS_V, |
| POS_E, |
| POS_UpdateExpr, |
| }; |
| |
| /// Set 'x' part of the associated expression/statement. |
| void setX(Expr *X) { Data->getChildren()[DataPositionTy::POS_X] = X; } |
| /// Set helper expression of the form |
| /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or |
| /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. |
| void setUpdateExpr(Expr *UE) { |
| Data->getChildren()[DataPositionTy::POS_UpdateExpr] = UE; |
| } |
| /// Set 'v' part of the associated expression/statement. |
| void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; } |
| /// Set 'expr' part of the associated expression/statement. |
| void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; } |
| |
| public: |
| /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr' |
| /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for |
| /// detailed description of 'x', 'v' and 'expr'). |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param X 'x' part of the associated expression/statement. |
| /// \param V 'v' part of the associated expression/statement. |
| /// \param E 'expr' part of the associated expression/statement. |
| /// \param UE Helper expression of the form |
| /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or |
| /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. |
| /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the |
| /// second. |
| /// \param IsPostfixUpdate true if original value of 'x' must be stored in |
| /// 'v', not an updated one. |
| static OMPAtomicDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V, |
| Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate); |
| |
| /// Creates an empty directive with the place for \a NumClauses |
| /// clauses. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPAtomicDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, EmptyShell); |
| |
| /// Get 'x' part of the associated expression/statement. |
| Expr *getX() { |
| return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]); |
| } |
| const Expr *getX() const { |
| return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]); |
| } |
| /// Get helper expression of the form |
| /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or |
| /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. |
| Expr *getUpdateExpr() { |
| return cast_or_null<Expr>( |
| Data->getChildren()[DataPositionTy::POS_UpdateExpr]); |
| } |
| const Expr *getUpdateExpr() const { |
| return cast_or_null<Expr>( |
| Data->getChildren()[DataPositionTy::POS_UpdateExpr]); |
| } |
| /// Return true if helper update expression has form |
| /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form |
| /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. |
| bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } |
| /// Return true if 'v' expression must be updated to original value of |
| /// 'x', false if 'v' must be updated to the new value of 'x'. |
| bool isPostfixUpdate() const { return IsPostfixUpdate; } |
| /// Get 'v' part of the associated expression/statement. |
| Expr *getV() { |
| return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]); |
| } |
| const Expr *getV() const { |
| return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]); |
| } |
| /// Get 'expr' part of the associated expression/statement. |
| Expr *getExpr() { |
| return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]); |
| } |
| const Expr *getExpr() const { |
| return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]); |
| } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPAtomicDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp target' directive. |
| /// |
| /// \code |
| /// #pragma omp target if(a) |
| /// \endcode |
| /// In this example directive '#pragma omp target' has clause 'if' with |
| /// condition 'a'. |
| /// |
| class OMPTargetDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target, |
| StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPTargetDirective() |
| : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target, |
| SourceLocation(), SourceLocation()) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// |
| static OMPTargetDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); |
| |
| /// Creates an empty directive with the place for \a NumClauses |
| /// clauses. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPTargetDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTargetDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp target data' directive. |
| /// |
| /// \code |
| /// #pragma omp target data device(0) if(a) map(b[:]) |
| /// \endcode |
| /// In this example directive '#pragma omp target data' has clauses 'device' |
| /// with the value '0', 'if' with condition 'a' and 'map' with array |
| /// section 'b[:]'. |
| /// |
| class OMPTargetDataDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// |
| OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPTargetDataDirectiveClass, |
| llvm::omp::OMPD_target_data, StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPTargetDataDirective() |
| : OMPExecutableDirective(OMPTargetDataDirectiveClass, |
| llvm::omp::OMPD_target_data, SourceLocation(), |
| SourceLocation()) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// |
| static OMPTargetDataDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); |
| |
| /// Creates an empty directive with the place for \a N clauses. |
| /// |
| /// \param C AST context. |
| /// \param N The number of clauses. |
| /// |
| static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N, |
| EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTargetDataDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp target enter data' directive. |
| /// |
| /// \code |
| /// #pragma omp target enter data device(0) if(a) map(b[:]) |
| /// \endcode |
| /// In this example directive '#pragma omp target enter data' has clauses |
| /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array |
| /// section 'b[:]'. |
| /// |
| class OMPTargetEnterDataDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// |
| OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass, |
| llvm::omp::OMPD_target_enter_data, StartLoc, |
| EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPTargetEnterDataDirective() |
| : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass, |
| llvm::omp::OMPD_target_enter_data, |
| SourceLocation(), SourceLocation()) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// |
| static OMPTargetEnterDataDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); |
| |
| /// Creates an empty directive with the place for \a N clauses. |
| /// |
| /// \param C AST context. |
| /// \param N The number of clauses. |
| /// |
| static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C, |
| unsigned N, EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTargetEnterDataDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp target exit data' directive. |
| /// |
| /// \code |
| /// #pragma omp target exit data device(0) if(a) map(b[:]) |
| /// \endcode |
| /// In this example directive '#pragma omp target exit data' has clauses |
| /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array |
| /// section 'b[:]'. |
| /// |
| class OMPTargetExitDataDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// |
| OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPTargetExitDataDirectiveClass, |
| llvm::omp::OMPD_target_exit_data, StartLoc, |
| EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPTargetExitDataDirective() |
| : OMPExecutableDirective(OMPTargetExitDataDirectiveClass, |
| llvm::omp::OMPD_target_exit_data, |
| SourceLocation(), SourceLocation()) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// |
| static OMPTargetExitDataDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); |
| |
| /// Creates an empty directive with the place for \a N clauses. |
| /// |
| /// \param C AST context. |
| /// \param N The number of clauses. |
| /// |
| static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C, |
| unsigned N, EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTargetExitDataDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp target parallel' directive. |
| /// |
| /// \code |
| /// #pragma omp target parallel if(a) |
| /// \endcode |
| /// In this example directive '#pragma omp target parallel' has clause 'if' with |
| /// condition 'a'. |
| /// |
| class OMPTargetParallelDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// true if the construct has inner cancel directive. |
| bool HasCancel = false; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPTargetParallelDirectiveClass, |
| llvm::omp::OMPD_target_parallel, StartLoc, |
| EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPTargetParallelDirective() |
| : OMPExecutableDirective(OMPTargetParallelDirectiveClass, |
| llvm::omp::OMPD_target_parallel, |
| SourceLocation(), SourceLocation()) {} |
| |
| /// Sets special task reduction descriptor. |
| void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } |
| /// Set cancel state. |
| void setHasCancel(bool Has) { HasCancel = Has; } |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param TaskRedRef Task reduction special reference expression to handle |
| /// taskgroup descriptor. |
| /// \param HasCancel true if this directive has inner cancel directive. |
| /// |
| static OMPTargetParallelDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, |
| bool HasCancel); |
| |
| /// Creates an empty directive with the place for \a NumClauses |
| /// clauses. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPTargetParallelDirective * |
| CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); |
| |
| /// Returns special task reduction reference expression. |
| Expr *getTaskReductionRefExpr() { |
| return cast_or_null<Expr>(Data->getChildren()[0]); |
| } |
| const Expr *getTaskReductionRefExpr() const { |
| return const_cast<OMPTargetParallelDirective *>(this) |
| ->getTaskReductionRefExpr(); |
| } |
| |
| /// Return true if current directive has inner cancel directive. |
| bool hasCancel() const { return HasCancel; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTargetParallelDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp target parallel for' directive. |
| /// |
| /// \code |
| /// #pragma omp target parallel for private(a,b) reduction(+:c,d) |
| /// \endcode |
| /// In this example directive '#pragma omp target parallel for' has clauses |
| /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' |
| /// and variables 'c' and 'd'. |
| /// |
| class OMPTargetParallelForDirective : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// true if current region has inner cancel directive. |
| bool HasCancel = false; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTargetParallelForDirectiveClass, |
| llvm::omp::OMPD_target_parallel_for, StartLoc, EndLoc, |
| CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPTargetParallelForDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTargetParallelForDirectiveClass, |
| llvm::omp::OMPD_target_parallel_for, SourceLocation(), |
| SourceLocation(), CollapsedNum) {} |
| |
| /// Sets special task reduction descriptor. |
| void setTaskReductionRefExpr(Expr *E) { |
| Data->getChildren()[numLoopChildren( |
| getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)] = E; |
| } |
| |
| /// Set cancel state. |
| void setHasCancel(bool Has) { HasCancel = Has; } |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// \param TaskRedRef Task reduction special reference expression to handle |
| /// taskgroup descriptor. |
| /// \param HasCancel true if current directive has inner cancel directive. |
| /// |
| static OMPTargetParallelForDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, |
| bool HasCancel); |
| |
| /// Creates an empty directive with the place |
| /// for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, |
| unsigned CollapsedNum, |
| EmptyShell); |
| |
| /// Returns special task reduction reference expression. |
| Expr *getTaskReductionRefExpr() { |
| return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( |
| getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)]); |
| } |
| const Expr *getTaskReductionRefExpr() const { |
| return const_cast<OMPTargetParallelForDirective *>(this) |
| ->getTaskReductionRefExpr(); |
| } |
| |
| /// Return true if current directive has inner cancel directive. |
| bool hasCancel() const { return HasCancel; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTargetParallelForDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp teams' directive. |
| /// |
| /// \code |
| /// #pragma omp teams if(a) |
| /// \endcode |
| /// In this example directive '#pragma omp teams' has clause 'if' with |
| /// condition 'a'. |
| /// |
| class OMPTeamsDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams, |
| StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPTeamsDirective() |
| : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams, |
| SourceLocation(), SourceLocation()) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// |
| static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt); |
| |
| /// Creates an empty directive with the place for \a NumClauses |
| /// clauses. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPTeamsDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTeamsDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp cancellation point' directive. |
| /// |
| /// \code |
| /// #pragma omp cancellation point for |
| /// \endcode |
| /// |
| /// In this example a cancellation point is created for innermost 'for' region. |
| class OMPCancellationPointDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// statements and child expressions. |
| /// |
| OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPCancellationPointDirectiveClass, |
| llvm::omp::OMPD_cancellation_point, StartLoc, |
| EndLoc) {} |
| |
| /// Build an empty directive. |
| explicit OMPCancellationPointDirective() |
| : OMPExecutableDirective(OMPCancellationPointDirectiveClass, |
| llvm::omp::OMPD_cancellation_point, |
| SourceLocation(), SourceLocation()) {} |
| |
| /// Set cancel region for current cancellation point. |
| /// \param CR Cancellation region. |
| void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } |
| |
| public: |
| /// Creates directive. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// |
| static OMPCancellationPointDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| OpenMPDirectiveKind CancelRegion); |
| |
| /// Creates an empty directive. |
| /// |
| /// \param C AST context. |
| /// |
| static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C, |
| EmptyShell); |
| |
| /// Get cancellation region for the current cancellation point. |
| OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPCancellationPointDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp cancel' directive. |
| /// |
| /// \code |
| /// #pragma omp cancel for |
| /// \endcode |
| /// |
| /// In this example a cancel is created for innermost 'for' region. |
| class OMPCancelDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel, |
| StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPCancelDirective() |
| : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel, |
| SourceLocation(), SourceLocation()) {} |
| |
| /// Set cancel region for current cancellation point. |
| /// \param CR Cancellation region. |
| void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } |
| |
| public: |
| /// Creates directive. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// |
| static OMPCancelDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion); |
| |
| /// Creates an empty directive. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPCancelDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, EmptyShell); |
| |
| /// Get cancellation region for the current cancellation point. |
| OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPCancelDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp taskloop' directive. |
| /// |
| /// \code |
| /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num) |
| /// \endcode |
| /// In this example directive '#pragma omp taskloop' has clauses 'private' |
| /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and |
| /// 'num_tasks' with expression 'num'. |
| /// |
| class OMPTaskLoopDirective : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// true if the construct has inner cancel directive. |
| bool HasCancel = false; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop, |
| StartLoc, EndLoc, CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPTaskLoopDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop, |
| SourceLocation(), SourceLocation(), CollapsedNum) {} |
| |
| /// Set cancel state. |
| void setHasCancel(bool Has) { HasCancel = Has; } |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// \param HasCancel true if this directive has inner cancel directive. |
| /// |
| static OMPTaskLoopDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); |
| |
| /// Creates an empty directive with the place |
| /// for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, |
| unsigned CollapsedNum, EmptyShell); |
| |
| /// Return true if current directive has inner cancel directive. |
| bool hasCancel() const { return HasCancel; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTaskLoopDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp taskloop simd' directive. |
| /// |
| /// \code |
| /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num) |
| /// \endcode |
| /// In this example directive '#pragma omp taskloop simd' has clauses 'private' |
| /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and |
| /// 'num_tasks' with expression 'num'. |
| /// |
| class OMPTaskLoopSimdDirective : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass, |
| llvm::omp::OMPD_taskloop_simd, StartLoc, EndLoc, |
| CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass, |
| llvm::omp::OMPD_taskloop_simd, SourceLocation(), |
| SourceLocation(), CollapsedNum) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// |
| static OMPTaskLoopSimdDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs); |
| |
| /// Creates an empty directive with the place |
| /// for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, |
| unsigned CollapsedNum, |
| EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp master taskloop' directive. |
| /// |
| /// \code |
| /// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num) |
| /// \endcode |
| /// In this example directive '#pragma omp master taskloop' has clauses |
| /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' |
| /// and 'num_tasks' with expression 'num'. |
| /// |
| class OMPMasterTaskLoopDirective : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// true if the construct has inner cancel directive. |
| bool HasCancel = false; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPMasterTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass, |
| llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc, |
| CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass, |
| llvm::omp::OMPD_master_taskloop, SourceLocation(), |
| SourceLocation(), CollapsedNum) {} |
| |
| /// Set cancel state. |
| void setHasCancel(bool Has) { HasCancel = Has; } |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// \param HasCancel true if this directive has inner cancel directive. |
| /// |
| static OMPMasterTaskLoopDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); |
| |
| /// Creates an empty directive with the place |
| /// for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, |
| unsigned CollapsedNum, |
| EmptyShell); |
| |
| /// Return true if current directive has inner cancel directive. |
| bool hasCancel() const { return HasCancel; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp master taskloop simd' directive. |
| /// |
| /// \code |
| /// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num) |
| /// \endcode |
| /// In this example directive '#pragma omp master taskloop simd' has clauses |
| /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' |
| /// and 'num_tasks' with expression 'num'. |
| /// |
| class OMPMasterTaskLoopSimdDirective : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass, |
| llvm::omp::OMPD_master_taskloop_simd, StartLoc, EndLoc, |
| CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass, |
| llvm::omp::OMPD_master_taskloop_simd, SourceLocation(), |
| SourceLocation(), CollapsedNum) {} |
| |
| public: |
| /// Creates directive with a list of \p Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// |
| static OMPMasterTaskLoopSimdDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs); |
| |
| /// Creates an empty directive with the place for \p NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, |
| unsigned CollapsedNum, |
| EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp parallel master taskloop' directive. |
| /// |
| /// \code |
| /// #pragma omp parallel master taskloop private(a,b) grainsize(val) |
| /// num_tasks(num) |
| /// \endcode |
| /// In this example directive '#pragma omp parallel master taskloop' has clauses |
| /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' |
| /// and 'num_tasks' with expression 'num'. |
| /// |
| class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// true if the construct has inner cancel directive. |
| bool HasCancel = false; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass, |
| llvm::omp::OMPD_parallel_master_taskloop, StartLoc, |
| EndLoc, CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass, |
| llvm::omp::OMPD_parallel_master_taskloop, |
| SourceLocation(), SourceLocation(), CollapsedNum) {} |
| |
| /// Set cancel state. |
| void setHasCancel(bool Has) { HasCancel = Has; } |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// \param HasCancel true if this directive has inner cancel directive. |
| /// |
| static OMPParallelMasterTaskLoopDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); |
| |
| /// Creates an empty directive with the place |
| /// for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, |
| unsigned CollapsedNum, |
| EmptyShell); |
| |
| /// Return true if current directive has inner cancel directive. |
| bool hasCancel() const { return HasCancel; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp parallel master taskloop simd' directive. |
| /// |
| /// \code |
| /// #pragma omp parallel master taskloop simd private(a,b) grainsize(val) |
| /// num_tasks(num) |
| /// \endcode |
| /// In this example directive '#pragma omp parallel master taskloop simd' has |
| /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with |
| /// expression 'val' and 'num_tasks' with expression 'num'. |
| /// |
| class OMPParallelMasterTaskLoopSimdDirective : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPParallelMasterTaskLoopSimdDirective(SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass, |
| llvm::omp::OMPD_parallel_master_taskloop_simd, |
| StartLoc, EndLoc, CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass, |
| llvm::omp::OMPD_parallel_master_taskloop_simd, |
| SourceLocation(), SourceLocation(), CollapsedNum) {} |
| |
| public: |
| /// Creates directive with a list of \p Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// |
| static OMPParallelMasterTaskLoopSimdDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs); |
| |
| /// Creates an empty directive with the place |
| /// for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPParallelMasterTaskLoopSimdDirective * |
| CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, |
| EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp distribute' directive. |
| /// |
| /// \code |
| /// #pragma omp distribute private(a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp distribute' has clauses 'private' |
| /// with the variables 'a' and 'b' |
| /// |
| class OMPDistributeDirective : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPDistributeDirectiveClass, |
| llvm::omp::OMPD_distribute, StartLoc, EndLoc, |
| CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPDistributeDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPDistributeDirectiveClass, |
| llvm::omp::OMPD_distribute, SourceLocation(), |
| SourceLocation(), CollapsedNum) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// |
| static OMPDistributeDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs); |
| |
| /// Creates an empty directive with the place |
| /// for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPDistributeDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, |
| unsigned CollapsedNum, EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPDistributeDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp target update' directive. |
| /// |
| /// \code |
| /// #pragma omp target update to(a) from(b) device(1) |
| /// \endcode |
| /// In this example directive '#pragma omp target update' has clause 'to' with |
| /// argument 'a', clause 'from' with argument 'b' and clause 'device' with |
| /// argument '1'. |
| /// |
| class OMPTargetUpdateDirective : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// |
| OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPTargetUpdateDirectiveClass, |
| llvm::omp::OMPD_target_update, StartLoc, |
| EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPTargetUpdateDirective() |
| : OMPExecutableDirective(OMPTargetUpdateDirectiveClass, |
| llvm::omp::OMPD_target_update, SourceLocation(), |
| SourceLocation()) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// |
| static OMPTargetUpdateDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); |
| |
| /// Creates an empty directive with the place for \a NumClauses |
| /// clauses. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses The number of clauses. |
| /// |
| static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTargetUpdateDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp distribute parallel for' composite |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp distribute parallel for private(a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp distribute parallel for' has clause |
| /// 'private' with the variables 'a' and 'b' |
| /// |
| class OMPDistributeParallelForDirective : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// true if the construct has inner cancel directive. |
| bool HasCancel = false; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPDistributeParallelForDirective(SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPDistributeParallelForDirectiveClass, |
| llvm::omp::OMPD_distribute_parallel_for, StartLoc, |
| EndLoc, CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPDistributeParallelForDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPDistributeParallelForDirectiveClass, |
| llvm::omp::OMPD_distribute_parallel_for, |
| SourceLocation(), SourceLocation(), CollapsedNum) {} |
| |
| /// Sets special task reduction descriptor. |
| void setTaskReductionRefExpr(Expr *E) { |
| Data->getChildren()[numLoopChildren( |
| getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)] = E; |
| } |
| |
| /// Set cancel state. |
| void setHasCancel(bool Has) { HasCancel = Has; } |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// \param TaskRedRef Task reduction special reference expression to handle |
| /// taskgroup descriptor. |
| /// \param HasCancel true if this directive has inner cancel directive. |
| /// |
| static OMPDistributeParallelForDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, |
| bool HasCancel); |
| |
| /// Creates an empty directive with the place |
| /// for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, |
| unsigned CollapsedNum, |
| EmptyShell); |
| |
| /// Returns special task reduction reference expression. |
| Expr *getTaskReductionRefExpr() { |
| return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( |
| getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)]); |
| } |
| const Expr *getTaskReductionRefExpr() const { |
| return const_cast<OMPDistributeParallelForDirective *>(this) |
| ->getTaskReductionRefExpr(); |
| } |
| |
| /// Return true if current directive has inner cancel directive. |
| bool hasCancel() const { return HasCancel; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPDistributeParallelForDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp distribute parallel for simd' composite |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp distribute parallel for simd private(x) |
| /// \endcode |
| /// In this example directive '#pragma omp distribute parallel for simd' has |
| /// clause 'private' with the variables 'x' |
| /// |
| class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPDistributeParallelForSimdDirective(SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass, |
| llvm::omp::OMPD_distribute_parallel_for_simd, StartLoc, |
| EndLoc, CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass, |
| llvm::omp::OMPD_distribute_parallel_for_simd, |
| SourceLocation(), SourceLocation(), CollapsedNum) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// |
| static OMPDistributeParallelForSimdDirective *Create( |
| const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs); |
| |
| /// Creates an empty directive with the place for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPDistributeParallelForSimdDirective *CreateEmpty( |
| const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, |
| EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp distribute simd' composite directive. |
| /// |
| /// \code |
| /// #pragma omp distribute simd private(x) |
| /// \endcode |
| /// In this example directive '#pragma omp distribute simd' has clause |
| /// 'private' with the variables 'x' |
| /// |
| class OMPDistributeSimdDirective final : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPDistributeSimdDirectiveClass, |
| llvm::omp::OMPD_distribute_simd, StartLoc, EndLoc, |
| CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPDistributeSimdDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPDistributeSimdDirectiveClass, |
| llvm::omp::OMPD_distribute_simd, SourceLocation(), |
| SourceLocation(), CollapsedNum) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// |
| static OMPDistributeSimdDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs); |
| |
| /// Creates an empty directive with the place for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, |
| unsigned CollapsedNum, |
| EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPDistributeSimdDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp target parallel for simd' directive. |
| /// |
| /// \code |
| /// #pragma omp target parallel for simd private(a) map(b) safelen(c) |
| /// \endcode |
| /// In this example directive '#pragma omp target parallel for simd' has clauses |
| /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen' |
| /// with the variable 'c'. |
| /// |
| class OMPTargetParallelForSimdDirective final : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPTargetParallelForSimdDirective(SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass, |
| llvm::omp::OMPD_target_parallel_for_simd, StartLoc, |
| EndLoc, CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass, |
| llvm::omp::OMPD_target_parallel_for_simd, |
| SourceLocation(), SourceLocation(), CollapsedNum) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// |
| static OMPTargetParallelForSimdDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs); |
| |
| /// Creates an empty directive with the place for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, |
| unsigned CollapsedNum, |
| EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp target simd' directive. |
| /// |
| /// \code |
| /// #pragma omp target simd private(a) map(b) safelen(c) |
| /// \endcode |
| /// In this example directive '#pragma omp target simd' has clauses 'private' |
| /// with the variable 'a', 'map' with the variable 'b' and 'safelen' with |
| /// the variable 'c'. |
| /// |
| class OMPTargetSimdDirective final : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPTargetSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTargetSimdDirectiveClass, |
| llvm::omp::OMPD_target_simd, StartLoc, EndLoc, |
| CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPTargetSimdDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTargetSimdDirectiveClass, |
| llvm::omp::OMPD_target_simd, SourceLocation(), |
| SourceLocation(), CollapsedNum) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// |
| static OMPTargetSimdDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs); |
| |
| /// Creates an empty directive with the place for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, |
| unsigned CollapsedNum, |
| EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTargetSimdDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp teams distribute' directive. |
| /// |
| /// \code |
| /// #pragma omp teams distribute private(a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp teams distribute' has clauses |
| /// 'private' with the variables 'a' and 'b' |
| /// |
| class OMPTeamsDistributeDirective final : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPTeamsDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTeamsDistributeDirectiveClass, |
| llvm::omp::OMPD_teams_distribute, StartLoc, EndLoc, |
| CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPTeamsDistributeDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTeamsDistributeDirectiveClass, |
| llvm::omp::OMPD_teams_distribute, SourceLocation(), |
| SourceLocation(), CollapsedNum) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// |
| static OMPTeamsDistributeDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs); |
| |
| /// Creates an empty directive with the place for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, |
| unsigned CollapsedNum, |
| EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTeamsDistributeDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp teams distribute simd' |
| /// combined directive. |
| /// |
| /// \code |
| /// #pragma omp teams distribute simd private(a,b) |
| /// \endcode |
| /// In this example directive '#pragma omp teams distribute simd' |
| /// has clause 'private' with the variables 'a' and 'b' |
| /// |
| class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPTeamsDistributeSimdDirective(SourceLocation StartLoc, |
| SourceLocation EndLoc, unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass, |
| llvm::omp::OMPD_teams_distribute_simd, StartLoc, |
| EndLoc, CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass, |
| llvm::omp::OMPD_teams_distribute_simd, |
| SourceLocation(), SourceLocation(), CollapsedNum) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// |
| static OMPTeamsDistributeSimdDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs); |
| |
| /// Creates an empty directive with the place |
| /// for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, |
| unsigned CollapsedNum, |
| EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp teams distribute parallel for simd' composite |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp teams distribute parallel for simd private(x) |
| /// \endcode |
| /// In this example directive '#pragma omp teams distribute parallel for simd' |
| /// has clause 'private' with the variables 'x' |
| /// |
| class OMPTeamsDistributeParallelForSimdDirective final |
| : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass, |
| llvm::omp::OMPD_teams_distribute_parallel_for_simd, |
| StartLoc, EndLoc, CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass, |
| llvm::omp::OMPD_teams_distribute_parallel_for_simd, |
| SourceLocation(), SourceLocation(), CollapsedNum) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// |
| static OMPTeamsDistributeParallelForSimdDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs); |
| |
| /// Creates an empty directive with the place for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPTeamsDistributeParallelForSimdDirective * |
| CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, |
| EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp teams distribute parallel for' composite |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp teams distribute parallel for private(x) |
| /// \endcode |
| /// In this example directive '#pragma omp teams distribute parallel for' |
| /// has clause 'private' with the variables 'x' |
| /// |
| class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// true if the construct has inner cancel directive. |
| bool HasCancel = false; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass, |
| llvm::omp::OMPD_teams_distribute_parallel_for, |
| StartLoc, EndLoc, CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass, |
| llvm::omp::OMPD_teams_distribute_parallel_for, |
| SourceLocation(), SourceLocation(), CollapsedNum) {} |
| |
| /// Sets special task reduction descriptor. |
| void setTaskReductionRefExpr(Expr *E) { |
| Data->getChildren()[numLoopChildren( |
| getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)] = E; |
| } |
| |
| /// Set cancel state. |
| void setHasCancel(bool Has) { HasCancel = Has; } |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// \param TaskRedRef Task reduction special reference expression to handle |
| /// taskgroup descriptor. |
| /// \param HasCancel true if this directive has inner cancel directive. |
| /// |
| static OMPTeamsDistributeParallelForDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, |
| bool HasCancel); |
| |
| /// Creates an empty directive with the place for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPTeamsDistributeParallelForDirective * |
| CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, |
| EmptyShell); |
| |
| /// Returns special task reduction reference expression. |
| Expr *getTaskReductionRefExpr() { |
| return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( |
| getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)]); |
| } |
| const Expr *getTaskReductionRefExpr() const { |
| return const_cast<OMPTeamsDistributeParallelForDirective *>(this) |
| ->getTaskReductionRefExpr(); |
| } |
| |
| /// Return true if current directive has inner cancel directive. |
| bool hasCancel() const { return HasCancel; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp target teams' directive. |
| /// |
| /// \code |
| /// #pragma omp target teams if(a>0) |
| /// \endcode |
| /// In this example directive '#pragma omp target teams' has clause 'if' with |
| /// condition 'a>0'. |
| /// |
| class OMPTargetTeamsDirective final : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPTargetTeamsDirectiveClass, |
| llvm::omp::OMPD_target_teams, StartLoc, EndLoc) { |
| } |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPTargetTeamsDirective() |
| : OMPExecutableDirective(OMPTargetTeamsDirectiveClass, |
| llvm::omp::OMPD_target_teams, SourceLocation(), |
| SourceLocation()) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// |
| static OMPTargetTeamsDirective *Create(const ASTContext &C, |
| SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt); |
| |
| /// Creates an empty directive with the place for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTargetTeamsDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp target teams distribute' combined directive. |
| /// |
| /// \code |
| /// #pragma omp target teams distribute private(x) |
| /// \endcode |
| /// In this example directive '#pragma omp target teams distribute' has clause |
| /// 'private' with the variables 'x' |
| /// |
| class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPTargetTeamsDistributeDirective(SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass, |
| llvm::omp::OMPD_target_teams_distribute, StartLoc, |
| EndLoc, CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass, |
| llvm::omp::OMPD_target_teams_distribute, |
| SourceLocation(), SourceLocation(), CollapsedNum) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// |
| static OMPTargetTeamsDistributeDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs); |
| |
| /// Creates an empty directive with the place for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPTargetTeamsDistributeDirective * |
| CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, |
| EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp target teams distribute parallel for' combined |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp target teams distribute parallel for private(x) |
| /// \endcode |
| /// In this example directive '#pragma omp target teams distribute parallel |
| /// for' has clause 'private' with the variables 'x' |
| /// |
| class OMPTargetTeamsDistributeParallelForDirective final |
| : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// true if the construct has inner cancel directive. |
| bool HasCancel = false; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass, |
| llvm::omp::OMPD_target_teams_distribute_parallel_for, |
| StartLoc, EndLoc, CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass, |
| llvm::omp::OMPD_target_teams_distribute_parallel_for, |
| SourceLocation(), SourceLocation(), CollapsedNum) {} |
| |
| /// Sets special task reduction descriptor. |
| void setTaskReductionRefExpr(Expr *E) { |
| Data->getChildren()[numLoopChildren( |
| getLoopsNumber(), |
| llvm::omp::OMPD_target_teams_distribute_parallel_for)] = E; |
| } |
| |
| /// Set cancel state. |
| void setHasCancel(bool Has) { HasCancel = Has; } |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// \param TaskRedRef Task reduction special reference expression to handle |
| /// taskgroup descriptor. |
| /// \param HasCancel true if this directive has inner cancel directive. |
| /// |
| static OMPTargetTeamsDistributeParallelForDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, |
| bool HasCancel); |
| |
| /// Creates an empty directive with the place for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPTargetTeamsDistributeParallelForDirective * |
| CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, |
| EmptyShell); |
| |
| /// Returns special task reduction reference expression. |
| Expr *getTaskReductionRefExpr() { |
| return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( |
| getLoopsNumber(), |
| llvm::omp::OMPD_target_teams_distribute_parallel_for)]); |
| } |
| const Expr *getTaskReductionRefExpr() const { |
| return const_cast<OMPTargetTeamsDistributeParallelForDirective *>(this) |
| ->getTaskReductionRefExpr(); |
| } |
| |
| /// Return true if current directive has inner cancel directive. |
| bool hasCancel() const { return HasCancel; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == |
| OMPTargetTeamsDistributeParallelForDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp target teams distribute parallel for simd' |
| /// combined directive. |
| /// |
| /// \code |
| /// #pragma omp target teams distribute parallel for simd private(x) |
| /// \endcode |
| /// In this example directive '#pragma omp target teams distribute parallel |
| /// for simd' has clause 'private' with the variables 'x' |
| /// |
| class OMPTargetTeamsDistributeParallelForSimdDirective final |
| : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective( |
| OMPTargetTeamsDistributeParallelForSimdDirectiveClass, |
| llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, StartLoc, |
| EndLoc, CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPTargetTeamsDistributeParallelForSimdDirective( |
| unsigned CollapsedNum) |
| : OMPLoopDirective( |
| OMPTargetTeamsDistributeParallelForSimdDirectiveClass, |
| llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, |
| SourceLocation(), SourceLocation(), CollapsedNum) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// |
| static OMPTargetTeamsDistributeParallelForSimdDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs); |
| |
| /// Creates an empty directive with the place for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPTargetTeamsDistributeParallelForSimdDirective * |
| CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, |
| EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == |
| OMPTargetTeamsDistributeParallelForSimdDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp target teams distribute simd' combined |
| /// directive. |
| /// |
| /// \code |
| /// #pragma omp target teams distribute simd private(x) |
| /// \endcode |
| /// In this example directive '#pragma omp target teams distribute simd' |
| /// has clause 'private' with the variables 'x' |
| /// |
| class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass, |
| llvm::omp::OMPD_target_teams_distribute_simd, StartLoc, |
| EndLoc, CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass, |
| llvm::omp::OMPD_target_teams_distribute_simd, |
| SourceLocation(), SourceLocation(), CollapsedNum) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// |
| static OMPTargetTeamsDistributeSimdDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs); |
| |
| /// Creates an empty directive with the place for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPTargetTeamsDistributeSimdDirective * |
| CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, |
| EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass; |
| } |
| }; |
| |
| /// This represents the '#pragma omp tile' loop transformation directive. |
| class OMPTileDirective final : public OMPLoopTransformationDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// Default list of offsets. |
| enum { |
| PreInitsOffset = 0, |
| TransformedStmtOffset, |
| }; |
| |
| explicit OMPTileDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned NumLoops) |
| : OMPLoopTransformationDirective(OMPTileDirectiveClass, |
| llvm::omp::OMPD_tile, StartLoc, EndLoc, |
| NumLoops) { |
| setNumGeneratedLoops(3 * NumLoops); |
| } |
| |
| void setPreInits(Stmt *PreInits) { |
| Data->getChildren()[PreInitsOffset] = PreInits; |
| } |
| |
| void setTransformedStmt(Stmt *S) { |
| Data->getChildren()[TransformedStmtOffset] = S; |
| } |
| |
| public: |
| /// Create a new AST node representation for '#pragma omp tile'. |
| /// |
| /// \param C Context of the AST. |
| /// \param StartLoc Location of the introducer (e.g. the 'omp' token). |
| /// \param EndLoc Location of the directive's end (e.g. the tok::eod). |
| /// \param Clauses The directive's clauses. |
| /// \param NumLoops Number of associated loops (number of items in the |
| /// 'sizes' clause). |
| /// \param AssociatedStmt The outermost associated loop. |
| /// \param TransformedStmt The loop nest after tiling, or nullptr in |
| /// dependent contexts. |
| /// \param PreInits Helper preinits statements for the loop nest. |
| static OMPTileDirective *Create(const ASTContext &C, SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, |
| unsigned NumLoops, Stmt *AssociatedStmt, |
| Stmt *TransformedStmt, Stmt *PreInits); |
| |
| /// Build an empty '#pragma omp tile' AST node for deserialization. |
| /// |
| /// \param C Context of the AST. |
| /// \param NumClauses Number of clauses to allocate. |
| /// \param NumLoops Number of associated loops to allocate. |
| static OMPTileDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, |
| unsigned NumLoops); |
| |
| /// Gets/sets the associated loops after tiling. |
| /// |
| /// This is in de-sugared format stored as a CompoundStmt. |
| /// |
| /// \code |
| /// for (...) |
| /// ... |
| /// \endcode |
| /// |
| /// Note that if the generated loops a become associated loops of another |
| /// directive, they may need to be hoisted before them. |
| Stmt *getTransformedStmt() const { |
| return Data->getChildren()[TransformedStmtOffset]; |
| } |
| |
| /// Return preinits statement. |
| Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPTileDirectiveClass; |
| } |
| }; |
| |
| /// This represents the '#pragma omp unroll' loop transformation directive. |
| /// |
| /// \code |
| /// #pragma omp unroll |
| /// for (int i = 0; i < 64; ++i) |
| /// \endcode |
| class OMPUnrollDirective final : public OMPLoopTransformationDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// Default list of offsets. |
| enum { |
| PreInitsOffset = 0, |
| TransformedStmtOffset, |
| }; |
| |
| explicit OMPUnrollDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPLoopTransformationDirective(OMPUnrollDirectiveClass, |
| llvm::omp::OMPD_unroll, StartLoc, EndLoc, |
| 1) {} |
| |
| /// Set the pre-init statements. |
| void setPreInits(Stmt *PreInits) { |
| Data->getChildren()[PreInitsOffset] = PreInits; |
| } |
| |
| /// Set the de-sugared statement. |
| void setTransformedStmt(Stmt *S) { |
| Data->getChildren()[TransformedStmtOffset] = S; |
| } |
| |
| public: |
| /// Create a new AST node representation for '#pragma omp unroll'. |
| /// |
| /// \param C Context of the AST. |
| /// \param StartLoc Location of the introducer (e.g. the 'omp' token). |
| /// \param EndLoc Location of the directive's end (e.g. the tok::eod). |
| /// \param Clauses The directive's clauses. |
| /// \param AssociatedStmt The outermost associated loop. |
| /// \param TransformedStmt The loop nest after tiling, or nullptr in |
| /// dependent contexts. |
| /// \param PreInits Helper preinits statements for the loop nest. |
| static OMPUnrollDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, |
| unsigned NumGeneratedLoops, Stmt *TransformedStmt, Stmt *PreInits); |
| |
| /// Build an empty '#pragma omp unroll' AST node for deserialization. |
| /// |
| /// \param C Context of the AST. |
| /// \param NumClauses Number of clauses to allocate. |
| static OMPUnrollDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses); |
| |
| /// Get the de-sugared associated loops after unrolling. |
| /// |
| /// This is only used if the unrolled loop becomes an associated loop of |
| /// another directive, otherwise the loop is emitted directly using loop |
| /// transformation metadata. When the unrolled loop cannot be used by another |
| /// directive (e.g. because of the full clause), the transformed stmt can also |
| /// be nullptr. |
| Stmt *getTransformedStmt() const { |
| return Data->getChildren()[TransformedStmtOffset]; |
| } |
| |
| /// Return the pre-init statements. |
| Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPUnrollDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp scan' directive. |
| /// |
| /// \code |
| /// #pragma omp scan inclusive(a) |
| /// \endcode |
| /// In this example directive '#pragma omp scan' has clause 'inclusive' with |
| /// list item 'a'. |
| class OMPScanDirective final : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPScanDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan, |
| StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPScanDirective() |
| : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan, |
| SourceLocation(), SourceLocation()) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses (only single OMPFlushClause clause is |
| /// allowed). |
| /// |
| static OMPScanDirective *Create(const ASTContext &C, SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses); |
| |
| /// Creates an empty directive with the place for \a NumClauses |
| /// clauses. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPScanDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, |
| EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPScanDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp interop' directive. |
| /// |
| /// \code |
| /// #pragma omp interop init(target:obj) device(x) depend(inout:y) nowait |
| /// \endcode |
| /// In this example directive '#pragma omp interop' has |
| /// clauses 'init', 'device', 'depend' and 'nowait'. |
| /// |
| class OMPInteropDirective final : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPInteropDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPInteropDirectiveClass, |
| llvm::omp::OMPD_interop, StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPInteropDirective() |
| : OMPExecutableDirective(OMPInteropDirectiveClass, |
| llvm::omp::OMPD_interop, SourceLocation(), |
| SourceLocation()) {} |
| |
| public: |
| /// Creates directive. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses The directive's clauses. |
| /// |
| static OMPInteropDirective *Create(const ASTContext &C, |
| SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses); |
| |
| /// Creates an empty directive. |
| /// |
| /// \param C AST context. |
| /// |
| static OMPInteropDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPInteropDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp dispatch' directive. |
| /// |
| /// \code |
| /// #pragma omp dispatch device(dnum) |
| /// \endcode |
| /// This example shows a directive '#pragma omp dispatch' with a |
| /// device clause with variable 'dnum'. |
| /// |
| class OMPDispatchDirective final : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// The location of the target-call. |
| SourceLocation TargetCallLoc; |
| |
| /// Set the location of the target-call. |
| void setTargetCallLoc(SourceLocation Loc) { TargetCallLoc = Loc; } |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPDispatchDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPDispatchDirectiveClass, |
| llvm::omp::OMPD_dispatch, StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPDispatchDirective() |
| : OMPExecutableDirective(OMPDispatchDirectiveClass, |
| llvm::omp::OMPD_dispatch, SourceLocation(), |
| SourceLocation()) {} |
| |
| public: |
| /// Creates directive with a list of \a Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param TargetCallLoc Location of the target-call. |
| /// |
| static OMPDispatchDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, |
| SourceLocation TargetCallLoc); |
| |
| /// Creates an empty directive with the place for \a NumClauses |
| /// clauses. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses Number of clauses. |
| /// |
| static OMPDispatchDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, EmptyShell); |
| |
| /// Return location of target-call. |
| SourceLocation getTargetCallLoc() const { return TargetCallLoc; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPDispatchDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp masked' directive. |
| /// \code |
| /// #pragma omp masked filter(tid) |
| /// \endcode |
| /// This example shows a directive '#pragma omp masked' with a filter clause |
| /// with variable 'tid'. |
| /// |
| class OMPMaskedDirective final : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// |
| OMPMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked, |
| StartLoc, EndLoc) {} |
| |
| /// Build an empty directive. |
| /// |
| explicit OMPMaskedDirective() |
| : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked, |
| SourceLocation(), SourceLocation()) {} |
| |
| public: |
| /// Creates directive. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// |
| static OMPMaskedDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); |
| |
| /// Creates an empty directive. |
| /// |
| /// \param C AST context. |
| /// |
| static OMPMaskedDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPMaskedDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp metadirective' directive. |
| /// |
| /// \code |
| /// #pragma omp metadirective when(user={condition(N>10)}: parallel for) |
| /// \endcode |
| /// In this example directive '#pragma omp metadirective' has clauses 'when' |
| /// with a dynamic user condition to check if a variable 'N > 10' |
| /// |
| class OMPMetaDirective final : public OMPExecutableDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| Stmt *IfStmt; |
| |
| OMPMetaDirective(SourceLocation StartLoc, SourceLocation EndLoc) |
| : OMPExecutableDirective(OMPMetaDirectiveClass, |
| llvm::omp::OMPD_metadirective, StartLoc, |
| EndLoc) {} |
| explicit OMPMetaDirective() |
| : OMPExecutableDirective(OMPMetaDirectiveClass, |
| llvm::omp::OMPD_metadirective, SourceLocation(), |
| SourceLocation()) {} |
| |
| void setIfStmt(Stmt *S) { IfStmt = S; } |
| |
| public: |
| static OMPMetaDirective *Create(const ASTContext &C, SourceLocation StartLoc, |
| SourceLocation EndLoc, |
| ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, Stmt *IfStmt); |
| static OMPMetaDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, |
| EmptyShell); |
| Stmt *getIfStmt() const { return IfStmt; } |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPMetaDirectiveClass; |
| } |
| }; |
| |
| /// This represents '#pragma omp loop' directive. |
| /// |
| /// \code |
| /// #pragma omp loop private(a,b) binding(parallel) order(concurrent) |
| /// \endcode |
| /// In this example directive '#pragma omp loop' has |
| /// clauses 'private' with the variables 'a' and 'b', 'binding' with |
| /// modifier 'parallel' and 'order(concurrent). |
| /// |
| class OMPGenericLoopDirective final : public OMPLoopDirective { |
| friend class ASTStmtReader; |
| friend class OMPExecutableDirective; |
| /// Build directive with the given start and end location. |
| /// |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending location of the directive. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| OMPGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum) |
| : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop, |
| StartLoc, EndLoc, CollapsedNum) {} |
| |
| /// Build an empty directive. |
| /// |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| explicit OMPGenericLoopDirective(unsigned CollapsedNum) |
| : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop, |
| SourceLocation(), SourceLocation(), CollapsedNum) {} |
| |
| public: |
| /// Creates directive with a list of \p Clauses. |
| /// |
| /// \param C AST context. |
| /// \param StartLoc Starting location of the directive kind. |
| /// \param EndLoc Ending Location of the directive. |
| /// \param CollapsedNum Number of collapsed loops. |
| /// \param Clauses List of clauses. |
| /// \param AssociatedStmt Statement, associated with the directive. |
| /// \param Exprs Helper expressions for CodeGen. |
| /// |
| static OMPGenericLoopDirective * |
| Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, |
| unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, |
| Stmt *AssociatedStmt, const HelperExprs &Exprs); |
| |
| /// Creates an empty directive with a place for \a NumClauses clauses. |
| /// |
| /// \param C AST context. |
| /// \param NumClauses Number of clauses. |
| /// \param CollapsedNum Number of collapsed nested loops. |
| /// |
| static OMPGenericLoopDirective *CreateEmpty(const ASTContext &C, |
| unsigned NumClauses, |
| unsigned CollapsedNum, |
| EmptyShell); |
| |
| static bool classof(const Stmt *T) { |
| return T->getStmtClass() == OMPGenericLoopDirectiveClass; |
| } |
| }; |
| |
| } // end namespace clang |
| |
| #endif |