10b57cec5SDimitry Andric //===- StmtOpenMP.h - Classes for OpenMP directives ------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric /// \file 90b57cec5SDimitry Andric /// This file defines OpenMP AST classes for executable directives and 100b57cec5SDimitry Andric /// clauses. 110b57cec5SDimitry Andric /// 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #ifndef LLVM_CLANG_AST_STMTOPENMP_H 150b57cec5SDimitry Andric #define LLVM_CLANG_AST_STMTOPENMP_H 160b57cec5SDimitry Andric 17e8d8bef9SDimitry Andric #include "clang/AST/ASTContext.h" 180b57cec5SDimitry Andric #include "clang/AST/Expr.h" 190b57cec5SDimitry Andric #include "clang/AST/OpenMPClause.h" 200b57cec5SDimitry Andric #include "clang/AST/Stmt.h" 21a7dea167SDimitry Andric #include "clang/AST/StmtCXX.h" 220b57cec5SDimitry Andric #include "clang/Basic/OpenMPKinds.h" 230b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h" 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric namespace clang { 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 280b57cec5SDimitry Andric // AST classes for directives. 290b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 300b57cec5SDimitry Andric 31fe6060f1SDimitry Andric /// Representation of an OpenMP canonical loop. 32fe6060f1SDimitry Andric /// 33fe6060f1SDimitry Andric /// OpenMP 1.0 C/C++, section 2.4.1 for Construct; canonical-shape 34fe6060f1SDimitry Andric /// OpenMP 2.0 C/C++, section 2.4.1 for Construct; canonical-shape 35fe6060f1SDimitry Andric /// OpenMP 2.5, section 2.5.1 Loop Construct; canonical form 36fe6060f1SDimitry Andric /// OpenMP 3.1, section 2.5.1 Loop Construct; canonical form 37fe6060f1SDimitry Andric /// OpenMP 4.0, section 2.6 Canonical Loop Form 38fe6060f1SDimitry Andric /// OpenMP 4.5, section 2.6 Canonical Loop Form 39fe6060f1SDimitry Andric /// OpenMP 5.0, section 2.9.1 Canonical Loop Form 40fe6060f1SDimitry Andric /// OpenMP 5.1, section 2.11.1 Canonical Loop Nest Form 41fe6060f1SDimitry Andric /// 42fe6060f1SDimitry Andric /// An OpenMP canonical loop is a for-statement or range-based for-statement 43fe6060f1SDimitry Andric /// with additional requirements that ensure that the number of iterations is 44fe6060f1SDimitry Andric /// known before entering the loop and allow skipping to an arbitrary iteration. 45fe6060f1SDimitry Andric /// The OMPCanonicalLoop AST node wraps a ForStmt or CXXForRangeStmt that is 46fe6060f1SDimitry Andric /// known to fulfill OpenMP's canonical loop requirements because of being 47fe6060f1SDimitry Andric /// associated to an OMPLoopBasedDirective. That is, the general structure is: 48fe6060f1SDimitry Andric /// 49fe6060f1SDimitry Andric /// OMPLoopBasedDirective 50fe6060f1SDimitry Andric /// [`- CapturedStmt ] 51fe6060f1SDimitry Andric /// [ `- CapturedDecl] 52fe6060f1SDimitry Andric /// ` OMPCanonicalLoop 53fe6060f1SDimitry Andric /// `- ForStmt/CXXForRangeStmt 54fe6060f1SDimitry Andric /// `- Stmt 55fe6060f1SDimitry Andric /// 56fe6060f1SDimitry Andric /// One or multiple CapturedStmt/CapturedDecl pairs may be inserted by some 57fe6060f1SDimitry Andric /// directives such as OMPParallelForDirective, but others do not need them 58fe6060f1SDimitry Andric /// (such as OMPTileDirective). In The OMPCanonicalLoop and 59fe6060f1SDimitry Andric /// ForStmt/CXXForRangeStmt pair is repeated for loop associated with the 60fe6060f1SDimitry Andric /// directive. A OMPCanonicalLoop must not appear in the AST unless associated 61fe6060f1SDimitry Andric /// with a OMPLoopBasedDirective. In an imperfectly nested loop nest, the 62fe6060f1SDimitry Andric /// OMPCanonicalLoop may also be wrapped in a CompoundStmt: 63fe6060f1SDimitry Andric /// 64fe6060f1SDimitry Andric /// [...] 65fe6060f1SDimitry Andric /// ` OMPCanonicalLoop 66fe6060f1SDimitry Andric /// `- ForStmt/CXXForRangeStmt 67fe6060f1SDimitry Andric /// `- CompoundStmt 68fe6060f1SDimitry Andric /// |- Leading in-between code (if any) 69fe6060f1SDimitry Andric /// |- OMPCanonicalLoop 70fe6060f1SDimitry Andric /// | `- ForStmt/CXXForRangeStmt 71fe6060f1SDimitry Andric /// | `- ... 72fe6060f1SDimitry Andric /// `- Trailing in-between code (if any) 73fe6060f1SDimitry Andric /// 74fe6060f1SDimitry Andric /// The leading/trailing in-between code must not itself be a OMPCanonicalLoop 75fe6060f1SDimitry Andric /// to avoid confusion which loop belongs to the nesting. 76fe6060f1SDimitry Andric /// 77fe6060f1SDimitry Andric /// There are three different kinds of iteration variables for different 78fe6060f1SDimitry Andric /// purposes: 79fe6060f1SDimitry Andric /// * Loop user variable: The user-accessible variable with different value for 80fe6060f1SDimitry Andric /// each iteration. 81fe6060f1SDimitry Andric /// * Loop iteration variable: The variable used to identify a loop iteration; 82fe6060f1SDimitry Andric /// for range-based for-statement, this is the hidden iterator '__begin'. For 83fe6060f1SDimitry Andric /// other loops, it is identical to the loop user variable. Must be a 84fe6060f1SDimitry Andric /// random-access iterator, pointer or integer type. 85fe6060f1SDimitry Andric /// * Logical iteration counter: Normalized loop counter starting at 0 and 86fe6060f1SDimitry Andric /// incrementing by one at each iteration. Allows abstracting over the type 87fe6060f1SDimitry Andric /// of the loop iteration variable and is always an unsigned integer type 88fe6060f1SDimitry Andric /// appropriate to represent the range of the loop iteration variable. Its 89fe6060f1SDimitry Andric /// value corresponds to the logical iteration number in the OpenMP 90fe6060f1SDimitry Andric /// specification. 91fe6060f1SDimitry Andric /// 92fe6060f1SDimitry Andric /// This AST node provides two captured statements: 93fe6060f1SDimitry Andric /// * The distance function which computes the number of iterations. 94fe6060f1SDimitry Andric /// * The loop user variable function that computes the loop user variable when 95fe6060f1SDimitry Andric /// given a logical iteration number. 96fe6060f1SDimitry Andric /// 97fe6060f1SDimitry Andric /// These captured statements provide the link between C/C++ semantics and the 98fe6060f1SDimitry Andric /// logical iteration counters used by the OpenMPIRBuilder which is 99fe6060f1SDimitry Andric /// language-agnostic and therefore does not know e.g. how to advance a 100fe6060f1SDimitry Andric /// random-access iterator. The OpenMPIRBuilder will use this information to 101fe6060f1SDimitry Andric /// apply simd, workshare-loop, distribute, taskloop and loop directives to the 102fe6060f1SDimitry Andric /// loop. For compatibility with the non-OpenMPIRBuilder codegen path, an 103fe6060f1SDimitry Andric /// OMPCanonicalLoop can itself also be wrapped into the CapturedStmts of an 104fe6060f1SDimitry Andric /// OMPLoopDirective and skipped when searching for the associated syntactical 105fe6060f1SDimitry Andric /// loop. 106fe6060f1SDimitry Andric /// 107fe6060f1SDimitry Andric /// Example: 108fe6060f1SDimitry Andric /// <code> 109fe6060f1SDimitry Andric /// std::vector<std::string> Container{1,2,3}; 110fe6060f1SDimitry Andric /// for (std::string Str : Container) 111fe6060f1SDimitry Andric /// Body(Str); 112fe6060f1SDimitry Andric /// </code> 113fe6060f1SDimitry Andric /// which is syntactic sugar for approximately: 114fe6060f1SDimitry Andric /// <code> 115fe6060f1SDimitry Andric /// auto &&__range = Container; 116fe6060f1SDimitry Andric /// auto __begin = std::begin(__range); 117fe6060f1SDimitry Andric /// auto __end = std::end(__range); 118fe6060f1SDimitry Andric /// for (; __begin != __end; ++__begin) { 119fe6060f1SDimitry Andric /// std::String Str = *__begin; 120fe6060f1SDimitry Andric /// Body(Str); 121fe6060f1SDimitry Andric /// } 122fe6060f1SDimitry Andric /// </code> 123fe6060f1SDimitry Andric /// In this example, the loop user variable is `Str`, the loop iteration 124fe6060f1SDimitry Andric /// variable is `__begin` of type `std::vector<std::string>::iterator` and the 125fe6060f1SDimitry Andric /// logical iteration number type is `size_t` (unsigned version of 126fe6060f1SDimitry Andric /// `std::vector<std::string>::iterator::difference_type` aka `ptrdiff_t`). 127fe6060f1SDimitry Andric /// Therefore, the distance function will be 128fe6060f1SDimitry Andric /// <code> 129fe6060f1SDimitry Andric /// [&](size_t &Result) { Result = __end - __begin; } 130fe6060f1SDimitry Andric /// </code> 131fe6060f1SDimitry Andric /// and the loop variable function is 132fe6060f1SDimitry Andric /// <code> 133fe6060f1SDimitry Andric /// [&,__begin](std::vector<std::string>::iterator &Result, size_t Logical) { 134fe6060f1SDimitry Andric /// Result = __begin + Logical; 135fe6060f1SDimitry Andric /// } 136fe6060f1SDimitry Andric /// </code> 137fe6060f1SDimitry Andric /// The variable `__begin`, aka the loop iteration variable, is captured by 138fe6060f1SDimitry Andric /// value because it is modified in the loop body, but both functions require 139fe6060f1SDimitry Andric /// the initial value. The OpenMP specification explicitly leaves unspecified 140fe6060f1SDimitry Andric /// when the loop expressions are evaluated such that a capture by reference is 141fe6060f1SDimitry Andric /// sufficient. 142fe6060f1SDimitry Andric class OMPCanonicalLoop : public Stmt { 143fe6060f1SDimitry Andric friend class ASTStmtReader; 144fe6060f1SDimitry Andric friend class ASTStmtWriter; 145fe6060f1SDimitry Andric 146fe6060f1SDimitry Andric /// Children of this AST node. 147fe6060f1SDimitry Andric enum { 148fe6060f1SDimitry Andric LOOP_STMT, 149fe6060f1SDimitry Andric DISTANCE_FUNC, 150fe6060f1SDimitry Andric LOOPVAR_FUNC, 151fe6060f1SDimitry Andric LOOPVAR_REF, 152fe6060f1SDimitry Andric LastSubStmt = LOOPVAR_REF 153fe6060f1SDimitry Andric }; 154fe6060f1SDimitry Andric 155fe6060f1SDimitry Andric private: 156fe6060f1SDimitry Andric /// This AST node's children. 157fe6060f1SDimitry Andric Stmt *SubStmts[LastSubStmt + 1] = {}; 158fe6060f1SDimitry Andric OMPCanonicalLoop()159fe6060f1SDimitry Andric OMPCanonicalLoop() : Stmt(StmtClass::OMPCanonicalLoopClass) {} 160fe6060f1SDimitry Andric 161fe6060f1SDimitry Andric public: 162fe6060f1SDimitry Andric /// Create a new OMPCanonicalLoop. create(const ASTContext & Ctx,Stmt * LoopStmt,CapturedStmt * DistanceFunc,CapturedStmt * LoopVarFunc,DeclRefExpr * LoopVarRef)163fe6060f1SDimitry Andric static OMPCanonicalLoop *create(const ASTContext &Ctx, Stmt *LoopStmt, 164fe6060f1SDimitry Andric CapturedStmt *DistanceFunc, 165fe6060f1SDimitry Andric CapturedStmt *LoopVarFunc, 166fe6060f1SDimitry Andric DeclRefExpr *LoopVarRef) { 167fe6060f1SDimitry Andric OMPCanonicalLoop *S = new (Ctx) OMPCanonicalLoop(); 168fe6060f1SDimitry Andric S->setLoopStmt(LoopStmt); 169fe6060f1SDimitry Andric S->setDistanceFunc(DistanceFunc); 170fe6060f1SDimitry Andric S->setLoopVarFunc(LoopVarFunc); 171fe6060f1SDimitry Andric S->setLoopVarRef(LoopVarRef); 172fe6060f1SDimitry Andric return S; 173fe6060f1SDimitry Andric } 174fe6060f1SDimitry Andric 175fe6060f1SDimitry Andric /// Create an empty OMPCanonicalLoop for deserialization. createEmpty(const ASTContext & Ctx)176fe6060f1SDimitry Andric static OMPCanonicalLoop *createEmpty(const ASTContext &Ctx) { 177fe6060f1SDimitry Andric return new (Ctx) OMPCanonicalLoop(); 178fe6060f1SDimitry Andric } 179fe6060f1SDimitry Andric classof(const Stmt * S)180fe6060f1SDimitry Andric static bool classof(const Stmt *S) { 181fe6060f1SDimitry Andric return S->getStmtClass() == StmtClass::OMPCanonicalLoopClass; 182fe6060f1SDimitry Andric } 183fe6060f1SDimitry Andric getBeginLoc()184fe6060f1SDimitry Andric SourceLocation getBeginLoc() const { return getLoopStmt()->getBeginLoc(); } getEndLoc()185fe6060f1SDimitry Andric SourceLocation getEndLoc() const { return getLoopStmt()->getEndLoc(); } 186fe6060f1SDimitry Andric 187fe6060f1SDimitry Andric /// Return this AST node's children. 188fe6060f1SDimitry Andric /// @{ children()189fe6060f1SDimitry Andric child_range children() { 190fe6060f1SDimitry Andric return child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1); 191fe6060f1SDimitry Andric } children()192fe6060f1SDimitry Andric const_child_range children() const { 193fe6060f1SDimitry Andric return const_child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1); 194fe6060f1SDimitry Andric } 195fe6060f1SDimitry Andric /// @} 196fe6060f1SDimitry Andric 197fe6060f1SDimitry Andric /// The wrapped syntactic loop statement (ForStmt or CXXForRangeStmt). 198fe6060f1SDimitry Andric /// @{ getLoopStmt()199fe6060f1SDimitry Andric Stmt *getLoopStmt() { return SubStmts[LOOP_STMT]; } getLoopStmt()200fe6060f1SDimitry Andric const Stmt *getLoopStmt() const { return SubStmts[LOOP_STMT]; } setLoopStmt(Stmt * S)201fe6060f1SDimitry Andric void setLoopStmt(Stmt *S) { 202fe6060f1SDimitry Andric assert((isa<ForStmt>(S) || isa<CXXForRangeStmt>(S)) && 203fe6060f1SDimitry Andric "Canonical loop must be a for loop (range-based or otherwise)"); 204fe6060f1SDimitry Andric SubStmts[LOOP_STMT] = S; 205fe6060f1SDimitry Andric } 206fe6060f1SDimitry Andric /// @} 207fe6060f1SDimitry Andric 208fe6060f1SDimitry Andric /// The function that computes the number of loop iterations. Can be evaluated 209fe6060f1SDimitry Andric /// before entering the loop but after the syntactical loop's init 210fe6060f1SDimitry Andric /// statement(s). 211fe6060f1SDimitry Andric /// 212fe6060f1SDimitry Andric /// Function signature: void(LogicalTy &Result) 213fe6060f1SDimitry Andric /// Any values necessary to compute the distance are captures of the closure. 214fe6060f1SDimitry Andric /// @{ getDistanceFunc()215fe6060f1SDimitry Andric CapturedStmt *getDistanceFunc() { 216fe6060f1SDimitry Andric return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]); 217fe6060f1SDimitry Andric } getDistanceFunc()218fe6060f1SDimitry Andric const CapturedStmt *getDistanceFunc() const { 219fe6060f1SDimitry Andric return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]); 220fe6060f1SDimitry Andric } setDistanceFunc(CapturedStmt * S)221fe6060f1SDimitry Andric void setDistanceFunc(CapturedStmt *S) { 222fe6060f1SDimitry Andric assert(S && "Expected non-null captured statement"); 223fe6060f1SDimitry Andric SubStmts[DISTANCE_FUNC] = S; 224fe6060f1SDimitry Andric } 225fe6060f1SDimitry Andric /// @} 226fe6060f1SDimitry Andric 227fe6060f1SDimitry Andric /// The function that computes the loop user variable from a logical iteration 228fe6060f1SDimitry Andric /// counter. Can be evaluated as first statement in the loop. 229fe6060f1SDimitry Andric /// 230fe6060f1SDimitry Andric /// Function signature: void(LoopVarTy &Result, LogicalTy Number) 231fe6060f1SDimitry Andric /// Any other values required to compute the loop user variable (such as start 232fe6060f1SDimitry Andric /// value, step size) are captured by the closure. In particular, the initial 233fe6060f1SDimitry Andric /// value of loop iteration variable is captured by value to be unaffected by 234fe6060f1SDimitry Andric /// previous iterations. 235fe6060f1SDimitry Andric /// @{ getLoopVarFunc()236fe6060f1SDimitry Andric CapturedStmt *getLoopVarFunc() { 237fe6060f1SDimitry Andric return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]); 238fe6060f1SDimitry Andric } getLoopVarFunc()239fe6060f1SDimitry Andric const CapturedStmt *getLoopVarFunc() const { 240fe6060f1SDimitry Andric return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]); 241fe6060f1SDimitry Andric } setLoopVarFunc(CapturedStmt * S)242fe6060f1SDimitry Andric void setLoopVarFunc(CapturedStmt *S) { 243fe6060f1SDimitry Andric assert(S && "Expected non-null captured statement"); 244fe6060f1SDimitry Andric SubStmts[LOOPVAR_FUNC] = S; 245fe6060f1SDimitry Andric } 246fe6060f1SDimitry Andric /// @} 247fe6060f1SDimitry Andric 248fe6060f1SDimitry Andric /// Reference to the loop user variable as accessed in the loop body. 249fe6060f1SDimitry Andric /// @{ getLoopVarRef()250fe6060f1SDimitry Andric DeclRefExpr *getLoopVarRef() { 251fe6060f1SDimitry Andric return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]); 252fe6060f1SDimitry Andric } getLoopVarRef()253fe6060f1SDimitry Andric const DeclRefExpr *getLoopVarRef() const { 254fe6060f1SDimitry Andric return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]); 255fe6060f1SDimitry Andric } setLoopVarRef(DeclRefExpr * E)256fe6060f1SDimitry Andric void setLoopVarRef(DeclRefExpr *E) { 257fe6060f1SDimitry Andric assert(E && "Expected non-null loop variable"); 258fe6060f1SDimitry Andric SubStmts[LOOPVAR_REF] = E; 259fe6060f1SDimitry Andric } 260fe6060f1SDimitry Andric /// @} 261fe6060f1SDimitry Andric }; 262fe6060f1SDimitry Andric 2630b57cec5SDimitry Andric /// This is a basic class for representing single OpenMP executable 2640b57cec5SDimitry Andric /// directive. 2650b57cec5SDimitry Andric /// 2660b57cec5SDimitry Andric class OMPExecutableDirective : public Stmt { 2670b57cec5SDimitry Andric friend class ASTStmtReader; 268e8d8bef9SDimitry Andric friend class ASTStmtWriter; 269e8d8bef9SDimitry Andric 2700b57cec5SDimitry Andric /// Kind of the directive. 271e8d8bef9SDimitry Andric OpenMPDirectiveKind Kind = llvm::omp::OMPD_unknown; 2720b57cec5SDimitry Andric /// Starting location of the directive (directive keyword). 2730b57cec5SDimitry Andric SourceLocation StartLoc; 2740b57cec5SDimitry Andric /// Ending location of the directive. 2750b57cec5SDimitry Andric SourceLocation EndLoc; 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric /// Get the clauses storage. getClauses()2780b57cec5SDimitry Andric MutableArrayRef<OMPClause *> getClauses() { 279e8d8bef9SDimitry Andric if (!Data) 280bdd1243dSDimitry Andric return std::nullopt; 281e8d8bef9SDimitry Andric return Data->getClauses(); 2820b57cec5SDimitry Andric } 2830b57cec5SDimitry Andric 2845f757f3fSDimitry Andric /// Was this directive mapped from an another directive? 2855f757f3fSDimitry Andric /// e.g. 1) omp loop bind(parallel) is mapped to OMPD_for 2865f757f3fSDimitry Andric /// 2) omp loop bind(teams) is mapped to OMPD_distribute 2875f757f3fSDimitry Andric /// 3) omp loop bind(thread) is mapped to OMPD_simd 2885f757f3fSDimitry Andric /// It was necessary to note it down in the Directive because of 2895f757f3fSDimitry Andric /// clang::TreeTransform::TransformOMPExecutableDirective() pass in 2905f757f3fSDimitry Andric /// the frontend. 2915f757f3fSDimitry Andric OpenMPDirectiveKind PrevMappedDirective = llvm::omp::OMPD_unknown; 2925f757f3fSDimitry Andric 2930b57cec5SDimitry Andric protected: 294e8d8bef9SDimitry Andric /// Data, associated with the directive. 295e8d8bef9SDimitry Andric OMPChildren *Data = nullptr; 296e8d8bef9SDimitry Andric 2970b57cec5SDimitry Andric /// Build instance of directive of class \a K. 2980b57cec5SDimitry Andric /// 2990b57cec5SDimitry Andric /// \param SC Statement class. 3000b57cec5SDimitry Andric /// \param K Kind of OpenMP directive. 3010b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive (directive keyword). 3020b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 3030b57cec5SDimitry Andric /// OMPExecutableDirective(StmtClass SC,OpenMPDirectiveKind K,SourceLocation StartLoc,SourceLocation EndLoc)304e8d8bef9SDimitry Andric OMPExecutableDirective(StmtClass SC, OpenMPDirectiveKind K, 305e8d8bef9SDimitry Andric SourceLocation StartLoc, SourceLocation EndLoc) 3060b57cec5SDimitry Andric : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)), 307e8d8bef9SDimitry Andric EndLoc(std::move(EndLoc)) {} 3080b57cec5SDimitry Andric 309e8d8bef9SDimitry Andric template <typename T, typename... Params> createDirective(const ASTContext & C,ArrayRef<OMPClause * > Clauses,Stmt * AssociatedStmt,unsigned NumChildren,Params &&...P)310e8d8bef9SDimitry Andric static T *createDirective(const ASTContext &C, ArrayRef<OMPClause *> Clauses, 311e8d8bef9SDimitry Andric Stmt *AssociatedStmt, unsigned NumChildren, 312e8d8bef9SDimitry Andric Params &&... P) { 313e8d8bef9SDimitry Andric void *Mem = 314e8d8bef9SDimitry Andric C.Allocate(sizeof(T) + OMPChildren::size(Clauses.size(), AssociatedStmt, 315e8d8bef9SDimitry Andric NumChildren), 316e8d8bef9SDimitry Andric alignof(T)); 3170b57cec5SDimitry Andric 318e8d8bef9SDimitry Andric auto *Data = OMPChildren::Create(reinterpret_cast<T *>(Mem) + 1, Clauses, 319e8d8bef9SDimitry Andric AssociatedStmt, NumChildren); 320e8d8bef9SDimitry Andric auto *Inst = new (Mem) T(std::forward<Params>(P)...); 321e8d8bef9SDimitry Andric Inst->Data = Data; 322e8d8bef9SDimitry Andric return Inst; 323e8d8bef9SDimitry Andric } 324e8d8bef9SDimitry Andric 325e8d8bef9SDimitry Andric template <typename T, typename... Params> createEmptyDirective(const ASTContext & C,unsigned NumClauses,bool HasAssociatedStmt,unsigned NumChildren,Params &&...P)326e8d8bef9SDimitry Andric static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses, 327e8d8bef9SDimitry Andric bool HasAssociatedStmt, unsigned NumChildren, 328e8d8bef9SDimitry Andric Params &&... P) { 329e8d8bef9SDimitry Andric void *Mem = 330e8d8bef9SDimitry Andric C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt, 331e8d8bef9SDimitry Andric NumChildren), 332e8d8bef9SDimitry Andric alignof(T)); 333e8d8bef9SDimitry Andric auto *Data = 334e8d8bef9SDimitry Andric OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses, 335e8d8bef9SDimitry Andric HasAssociatedStmt, NumChildren); 336e8d8bef9SDimitry Andric auto *Inst = new (Mem) T(std::forward<Params>(P)...); 337e8d8bef9SDimitry Andric Inst->Data = Data; 338e8d8bef9SDimitry Andric return Inst; 339e8d8bef9SDimitry Andric } 340e8d8bef9SDimitry Andric 341e8d8bef9SDimitry Andric template <typename T> 342e8d8bef9SDimitry Andric static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses, 343e8d8bef9SDimitry Andric bool HasAssociatedStmt = false, 344e8d8bef9SDimitry Andric unsigned NumChildren = 0) { 345e8d8bef9SDimitry Andric void *Mem = 346e8d8bef9SDimitry Andric C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt, 347e8d8bef9SDimitry Andric NumChildren), 348e8d8bef9SDimitry Andric alignof(T)); 349e8d8bef9SDimitry Andric auto *Data = 350e8d8bef9SDimitry Andric OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses, 351e8d8bef9SDimitry Andric HasAssociatedStmt, NumChildren); 352e8d8bef9SDimitry Andric auto *Inst = new (Mem) T; 353e8d8bef9SDimitry Andric Inst->Data = Data; 354e8d8bef9SDimitry Andric return Inst; 3550b57cec5SDimitry Andric } 3560b57cec5SDimitry Andric setMappedDirective(OpenMPDirectiveKind MappedDirective)3575f757f3fSDimitry Andric void setMappedDirective(OpenMPDirectiveKind MappedDirective) { 3585f757f3fSDimitry Andric PrevMappedDirective = MappedDirective; 3595f757f3fSDimitry Andric } 3605f757f3fSDimitry Andric 3610b57cec5SDimitry Andric public: 3620b57cec5SDimitry Andric /// Iterates over expressions/statements used in the construct. 3630b57cec5SDimitry Andric class used_clauses_child_iterator 3640b57cec5SDimitry Andric : public llvm::iterator_adaptor_base< 3650b57cec5SDimitry Andric used_clauses_child_iterator, ArrayRef<OMPClause *>::iterator, 3660b57cec5SDimitry Andric std::forward_iterator_tag, Stmt *, ptrdiff_t, Stmt *, Stmt *> { 3670b57cec5SDimitry Andric ArrayRef<OMPClause *>::iterator End; 3680b57cec5SDimitry Andric OMPClause::child_iterator ChildI, ChildEnd; 3690b57cec5SDimitry Andric MoveToNext()3700b57cec5SDimitry Andric void MoveToNext() { 3710b57cec5SDimitry Andric if (ChildI != ChildEnd) 3720b57cec5SDimitry Andric return; 3730b57cec5SDimitry Andric while (this->I != End) { 3740b57cec5SDimitry Andric ++this->I; 3750b57cec5SDimitry Andric if (this->I != End) { 3760b57cec5SDimitry Andric ChildI = (*this->I)->used_children().begin(); 3770b57cec5SDimitry Andric ChildEnd = (*this->I)->used_children().end(); 3780b57cec5SDimitry Andric if (ChildI != ChildEnd) 3790b57cec5SDimitry Andric return; 3800b57cec5SDimitry Andric } 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric } 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andric public: used_clauses_child_iterator(ArrayRef<OMPClause * > Clauses)3850b57cec5SDimitry Andric explicit used_clauses_child_iterator(ArrayRef<OMPClause *> Clauses) 3860b57cec5SDimitry Andric : used_clauses_child_iterator::iterator_adaptor_base(Clauses.begin()), 3870b57cec5SDimitry Andric End(Clauses.end()) { 3880b57cec5SDimitry Andric if (this->I != End) { 3890b57cec5SDimitry Andric ChildI = (*this->I)->used_children().begin(); 3900b57cec5SDimitry Andric ChildEnd = (*this->I)->used_children().end(); 3910b57cec5SDimitry Andric MoveToNext(); 3920b57cec5SDimitry Andric } 3930b57cec5SDimitry Andric } 3940b57cec5SDimitry Andric Stmt *operator*() const { return *ChildI; } 3950b57cec5SDimitry Andric Stmt *operator->() const { return **this; } 3960b57cec5SDimitry Andric 3970b57cec5SDimitry Andric used_clauses_child_iterator &operator++() { 3980b57cec5SDimitry Andric ++ChildI; 3990b57cec5SDimitry Andric if (ChildI != ChildEnd) 4000b57cec5SDimitry Andric return *this; 4010b57cec5SDimitry Andric if (this->I != End) { 4020b57cec5SDimitry Andric ++this->I; 4030b57cec5SDimitry Andric if (this->I != End) { 4040b57cec5SDimitry Andric ChildI = (*this->I)->used_children().begin(); 4050b57cec5SDimitry Andric ChildEnd = (*this->I)->used_children().end(); 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric } 4080b57cec5SDimitry Andric MoveToNext(); 4090b57cec5SDimitry Andric return *this; 4100b57cec5SDimitry Andric } 4110b57cec5SDimitry Andric }; 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric static llvm::iterator_range<used_clauses_child_iterator> used_clauses_children(ArrayRef<OMPClause * > Clauses)4140b57cec5SDimitry Andric used_clauses_children(ArrayRef<OMPClause *> Clauses) { 415bdd1243dSDimitry Andric return { 416bdd1243dSDimitry Andric used_clauses_child_iterator(Clauses), 417bdd1243dSDimitry Andric used_clauses_child_iterator(llvm::ArrayRef(Clauses.end(), (size_t)0))}; 4180b57cec5SDimitry Andric } 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andric /// Iterates over a filtered subrange of clauses applied to a 4210b57cec5SDimitry Andric /// directive. 4220b57cec5SDimitry Andric /// 4230b57cec5SDimitry Andric /// This iterator visits only clauses of type SpecificClause. 4240b57cec5SDimitry Andric template <typename SpecificClause> 4250b57cec5SDimitry Andric class specific_clause_iterator 4260b57cec5SDimitry Andric : public llvm::iterator_adaptor_base< 4270b57cec5SDimitry Andric specific_clause_iterator<SpecificClause>, 4280b57cec5SDimitry Andric ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag, 4290b57cec5SDimitry Andric const SpecificClause *, ptrdiff_t, const SpecificClause *, 4300b57cec5SDimitry Andric const SpecificClause *> { 4310b57cec5SDimitry Andric ArrayRef<OMPClause *>::const_iterator End; 4320b57cec5SDimitry Andric SkipToNextClause()4330b57cec5SDimitry Andric void SkipToNextClause() { 4340b57cec5SDimitry Andric while (this->I != End && !isa<SpecificClause>(*this->I)) 4350b57cec5SDimitry Andric ++this->I; 4360b57cec5SDimitry Andric } 4370b57cec5SDimitry Andric 4380b57cec5SDimitry Andric public: specific_clause_iterator(ArrayRef<OMPClause * > Clauses)4390b57cec5SDimitry Andric explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses) 4400b57cec5SDimitry Andric : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()), 4410b57cec5SDimitry Andric End(Clauses.end()) { 4420b57cec5SDimitry Andric SkipToNextClause(); 4430b57cec5SDimitry Andric } 4440b57cec5SDimitry Andric 4450b57cec5SDimitry Andric const SpecificClause *operator*() const { 4460b57cec5SDimitry Andric return cast<SpecificClause>(*this->I); 4470b57cec5SDimitry Andric } 4480b57cec5SDimitry Andric const SpecificClause *operator->() const { return **this; } 4490b57cec5SDimitry Andric 4500b57cec5SDimitry Andric specific_clause_iterator &operator++() { 4510b57cec5SDimitry Andric ++this->I; 4520b57cec5SDimitry Andric SkipToNextClause(); 4530b57cec5SDimitry Andric return *this; 4540b57cec5SDimitry Andric } 4550b57cec5SDimitry Andric }; 4560b57cec5SDimitry Andric 4570b57cec5SDimitry Andric template <typename SpecificClause> 4580b57cec5SDimitry Andric static llvm::iterator_range<specific_clause_iterator<SpecificClause>> getClausesOfKind(ArrayRef<OMPClause * > Clauses)4590b57cec5SDimitry Andric getClausesOfKind(ArrayRef<OMPClause *> Clauses) { 4600b57cec5SDimitry Andric return {specific_clause_iterator<SpecificClause>(Clauses), 4610b57cec5SDimitry Andric specific_clause_iterator<SpecificClause>( 462bdd1243dSDimitry Andric llvm::ArrayRef(Clauses.end(), (size_t)0))}; 4630b57cec5SDimitry Andric } 4640b57cec5SDimitry Andric 4650b57cec5SDimitry Andric template <typename SpecificClause> 4660b57cec5SDimitry Andric llvm::iterator_range<specific_clause_iterator<SpecificClause>> getClausesOfKind()4670b57cec5SDimitry Andric getClausesOfKind() const { 4680b57cec5SDimitry Andric return getClausesOfKind<SpecificClause>(clauses()); 4690b57cec5SDimitry Andric } 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric /// Gets a single clause of the specified kind associated with the 4720b57cec5SDimitry Andric /// current directive iff there is only one clause of this kind (and assertion 4730b57cec5SDimitry Andric /// is fired if there is more than one clause is associated with the 4740b57cec5SDimitry Andric /// directive). Returns nullptr if no clause of this kind is associated with 4750b57cec5SDimitry Andric /// the directive. 4760b57cec5SDimitry Andric template <typename SpecificClause> getSingleClause(ArrayRef<OMPClause * > Clauses)477fe6060f1SDimitry Andric static const SpecificClause *getSingleClause(ArrayRef<OMPClause *> Clauses) { 478fe6060f1SDimitry Andric auto ClausesOfKind = getClausesOfKind<SpecificClause>(Clauses); 4790b57cec5SDimitry Andric 480fe6060f1SDimitry Andric if (ClausesOfKind.begin() != ClausesOfKind.end()) { 481fe6060f1SDimitry Andric assert(std::next(ClausesOfKind.begin()) == ClausesOfKind.end() && 4820b57cec5SDimitry Andric "There are at least 2 clauses of the specified kind"); 483fe6060f1SDimitry Andric return *ClausesOfKind.begin(); 4840b57cec5SDimitry Andric } 4850b57cec5SDimitry Andric return nullptr; 4860b57cec5SDimitry Andric } 4870b57cec5SDimitry Andric 488fe6060f1SDimitry Andric template <typename SpecificClause> getSingleClause()489fe6060f1SDimitry Andric const SpecificClause *getSingleClause() const { 490fe6060f1SDimitry Andric return getSingleClause<SpecificClause>(clauses()); 491fe6060f1SDimitry Andric } 492fe6060f1SDimitry Andric 4930b57cec5SDimitry Andric /// Returns true if the current directive has one or more clauses of a 4940b57cec5SDimitry Andric /// specific kind. 4950b57cec5SDimitry Andric template <typename SpecificClause> hasClausesOfKind()4960b57cec5SDimitry Andric bool hasClausesOfKind() const { 4970b57cec5SDimitry Andric auto Clauses = getClausesOfKind<SpecificClause>(); 4980b57cec5SDimitry Andric return Clauses.begin() != Clauses.end(); 4990b57cec5SDimitry Andric } 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric /// Returns starting location of directive kind. getBeginLoc()5020b57cec5SDimitry Andric SourceLocation getBeginLoc() const { return StartLoc; } 5030b57cec5SDimitry Andric /// Returns ending location of directive. getEndLoc()5040b57cec5SDimitry Andric SourceLocation getEndLoc() const { return EndLoc; } 5050b57cec5SDimitry Andric 5060b57cec5SDimitry Andric /// Set starting location of directive kind. 5070b57cec5SDimitry Andric /// 5080b57cec5SDimitry Andric /// \param Loc New starting location of directive. 5090b57cec5SDimitry Andric /// setLocStart(SourceLocation Loc)5100b57cec5SDimitry Andric void setLocStart(SourceLocation Loc) { StartLoc = Loc; } 5110b57cec5SDimitry Andric /// Set ending location of directive. 5120b57cec5SDimitry Andric /// 5130b57cec5SDimitry Andric /// \param Loc New ending location of directive. 5140b57cec5SDimitry Andric /// setLocEnd(SourceLocation Loc)5150b57cec5SDimitry Andric void setLocEnd(SourceLocation Loc) { EndLoc = Loc; } 5160b57cec5SDimitry Andric 5170b57cec5SDimitry Andric /// Get number of clauses. getNumClauses()518e8d8bef9SDimitry Andric unsigned getNumClauses() const { 519e8d8bef9SDimitry Andric if (!Data) 520e8d8bef9SDimitry Andric return 0; 521e8d8bef9SDimitry Andric return Data->getNumClauses(); 522e8d8bef9SDimitry Andric } 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric /// Returns specified clause. 5250b57cec5SDimitry Andric /// 526e8d8bef9SDimitry Andric /// \param I Number of clause. 5270b57cec5SDimitry Andric /// getClause(unsigned I)528e8d8bef9SDimitry Andric OMPClause *getClause(unsigned I) const { return clauses()[I]; } 5290b57cec5SDimitry Andric 5300b57cec5SDimitry Andric /// Returns true if directive has associated statement. hasAssociatedStmt()531e8d8bef9SDimitry Andric bool hasAssociatedStmt() const { return Data && Data->hasAssociatedStmt(); } 5320b57cec5SDimitry Andric 5330b57cec5SDimitry Andric /// Returns statement associated with the directive. getAssociatedStmt()5340b57cec5SDimitry Andric const Stmt *getAssociatedStmt() const { 535e8d8bef9SDimitry Andric return const_cast<OMPExecutableDirective *>(this)->getAssociatedStmt(); 5360b57cec5SDimitry Andric } getAssociatedStmt()5370b57cec5SDimitry Andric Stmt *getAssociatedStmt() { 538e8d8bef9SDimitry Andric assert(hasAssociatedStmt() && 539e8d8bef9SDimitry Andric "Expected directive with the associated statement."); 540e8d8bef9SDimitry Andric return Data->getAssociatedStmt(); 5410b57cec5SDimitry Andric } 5420b57cec5SDimitry Andric 5430b57cec5SDimitry Andric /// Returns the captured statement associated with the 5440b57cec5SDimitry Andric /// component region within the (combined) directive. 545e8d8bef9SDimitry Andric /// 546e8d8bef9SDimitry Andric /// \param RegionKind Component region kind. getCapturedStmt(OpenMPDirectiveKind RegionKind)5470b57cec5SDimitry Andric const CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const { 548e8d8bef9SDimitry Andric assert(hasAssociatedStmt() && 549e8d8bef9SDimitry Andric "Expected directive with the associated statement."); 5500b57cec5SDimitry Andric SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 5510b57cec5SDimitry Andric getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind()); 552e8d8bef9SDimitry Andric return Data->getCapturedStmt(RegionKind, CaptureRegions); 5530b57cec5SDimitry Andric } 5540b57cec5SDimitry Andric 5550b57cec5SDimitry Andric /// Get innermost captured statement for the construct. getInnermostCapturedStmt()5560b57cec5SDimitry Andric CapturedStmt *getInnermostCapturedStmt() { 557e8d8bef9SDimitry Andric assert(hasAssociatedStmt() && 558e8d8bef9SDimitry Andric "Expected directive with the associated statement."); 5590b57cec5SDimitry Andric SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 5600b57cec5SDimitry Andric getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind()); 561e8d8bef9SDimitry Andric return Data->getInnermostCapturedStmt(CaptureRegions); 5620b57cec5SDimitry Andric } 5630b57cec5SDimitry Andric getInnermostCapturedStmt()5640b57cec5SDimitry Andric const CapturedStmt *getInnermostCapturedStmt() const { 5650b57cec5SDimitry Andric return const_cast<OMPExecutableDirective *>(this) 5660b57cec5SDimitry Andric ->getInnermostCapturedStmt(); 5670b57cec5SDimitry Andric } 5680b57cec5SDimitry Andric getDirectiveKind()5690b57cec5SDimitry Andric OpenMPDirectiveKind getDirectiveKind() const { return Kind; } 5700b57cec5SDimitry Andric classof(const Stmt * S)5710b57cec5SDimitry Andric static bool classof(const Stmt *S) { 5720b57cec5SDimitry Andric return S->getStmtClass() >= firstOMPExecutableDirectiveConstant && 5730b57cec5SDimitry Andric S->getStmtClass() <= lastOMPExecutableDirectiveConstant; 5740b57cec5SDimitry Andric } 5750b57cec5SDimitry Andric children()5760b57cec5SDimitry Andric child_range children() { 577e8d8bef9SDimitry Andric if (!Data) 5780b57cec5SDimitry Andric return child_range(child_iterator(), child_iterator()); 579e8d8bef9SDimitry Andric return Data->getAssociatedStmtAsRange(); 5800b57cec5SDimitry Andric } 5810b57cec5SDimitry Andric children()5820b57cec5SDimitry Andric const_child_range children() const { 583e8d8bef9SDimitry Andric return const_cast<OMPExecutableDirective *>(this)->children(); 5840b57cec5SDimitry Andric } 5850b57cec5SDimitry Andric clauses()5860b57cec5SDimitry Andric ArrayRef<OMPClause *> clauses() const { 587e8d8bef9SDimitry Andric if (!Data) 588bdd1243dSDimitry Andric return std::nullopt; 589e8d8bef9SDimitry Andric return Data->getClauses(); 5900b57cec5SDimitry Andric } 5910b57cec5SDimitry Andric 5920b57cec5SDimitry Andric /// Returns whether or not this is a Standalone directive. 5930b57cec5SDimitry Andric /// 5940b57cec5SDimitry Andric /// Stand-alone directives are executable directives 5950b57cec5SDimitry Andric /// that have no associated user code. 5960b57cec5SDimitry Andric bool isStandaloneDirective() const; 5970b57cec5SDimitry Andric 5980b57cec5SDimitry Andric /// Returns the AST node representing OpenMP structured-block of this 5990b57cec5SDimitry Andric /// OpenMP executable directive, 6000b57cec5SDimitry Andric /// Prerequisite: Executable Directive must not be Standalone directive. getStructuredBlock()601e8d8bef9SDimitry Andric const Stmt *getStructuredBlock() const { 602e8d8bef9SDimitry Andric return const_cast<OMPExecutableDirective *>(this)->getStructuredBlock(); 603e8d8bef9SDimitry Andric } 604e8d8bef9SDimitry Andric Stmt *getStructuredBlock(); 6050b57cec5SDimitry Andric getRawStmt()606e8d8bef9SDimitry Andric const Stmt *getRawStmt() const { 607e8d8bef9SDimitry Andric return const_cast<OMPExecutableDirective *>(this)->getRawStmt(); 608e8d8bef9SDimitry Andric } getRawStmt()609e8d8bef9SDimitry Andric Stmt *getRawStmt() { 610e8d8bef9SDimitry Andric assert(hasAssociatedStmt() && 611e8d8bef9SDimitry Andric "Expected directive with the associated statement."); 612e8d8bef9SDimitry Andric return Data->getRawStmt(); 6130b57cec5SDimitry Andric } 6145f757f3fSDimitry Andric getMappedDirective()6155f757f3fSDimitry Andric OpenMPDirectiveKind getMappedDirective() const { return PrevMappedDirective; } 6160b57cec5SDimitry Andric }; 6170b57cec5SDimitry Andric 6180b57cec5SDimitry Andric /// This represents '#pragma omp parallel' directive. 6190b57cec5SDimitry Andric /// 6200b57cec5SDimitry Andric /// \code 6210b57cec5SDimitry Andric /// #pragma omp parallel private(a,b) reduction(+: c,d) 6220b57cec5SDimitry Andric /// \endcode 6230b57cec5SDimitry Andric /// In this example directive '#pragma omp parallel' has clauses 'private' 6240b57cec5SDimitry Andric /// with the variables 'a' and 'b' and 'reduction' with operator '+' and 6250b57cec5SDimitry Andric /// variables 'c' and 'd'. 6260b57cec5SDimitry Andric /// 6270b57cec5SDimitry Andric class OMPParallelDirective : public OMPExecutableDirective { 6280b57cec5SDimitry Andric friend class ASTStmtReader; 629e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 6300b57cec5SDimitry Andric /// true if the construct has inner cancel directive. 631e8d8bef9SDimitry Andric bool HasCancel = false; 6320b57cec5SDimitry Andric 6330b57cec5SDimitry Andric /// Build directive with the given start and end location. 6340b57cec5SDimitry Andric /// 6350b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive (directive keyword). 6360b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 6370b57cec5SDimitry Andric /// OMPParallelDirective(SourceLocation StartLoc,SourceLocation EndLoc)638e8d8bef9SDimitry Andric OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc) 639e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPParallelDirectiveClass, 640e8d8bef9SDimitry Andric llvm::omp::OMPD_parallel, StartLoc, EndLoc) {} 6410b57cec5SDimitry Andric 6420b57cec5SDimitry Andric /// Build an empty directive. 6430b57cec5SDimitry Andric /// OMPParallelDirective()644e8d8bef9SDimitry Andric explicit OMPParallelDirective() 645e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPParallelDirectiveClass, 646480093f4SDimitry Andric llvm::omp::OMPD_parallel, SourceLocation(), 647e8d8bef9SDimitry Andric SourceLocation()) {} 6480b57cec5SDimitry Andric 6495ffd83dbSDimitry Andric /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)650e8d8bef9SDimitry Andric void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 6515ffd83dbSDimitry Andric 6520b57cec5SDimitry Andric /// Set cancel state. setHasCancel(bool Has)6530b57cec5SDimitry Andric void setHasCancel(bool Has) { HasCancel = Has; } 6540b57cec5SDimitry Andric 6550b57cec5SDimitry Andric public: 6560b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 6570b57cec5SDimitry Andric /// 6580b57cec5SDimitry Andric /// \param C AST context. 6590b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 6600b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 6610b57cec5SDimitry Andric /// \param Clauses List of clauses. 6620b57cec5SDimitry Andric /// \param AssociatedStmt Statement associated with the directive. 6635ffd83dbSDimitry Andric /// \param TaskRedRef Task reduction special reference expression to handle 6645ffd83dbSDimitry Andric /// taskgroup descriptor. 6650b57cec5SDimitry Andric /// \param HasCancel true if this directive has inner cancel directive. 6660b57cec5SDimitry Andric /// 6670b57cec5SDimitry Andric static OMPParallelDirective * 6680b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 6695ffd83dbSDimitry Andric ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 6705ffd83dbSDimitry Andric bool HasCancel); 6710b57cec5SDimitry Andric 6720b57cec5SDimitry Andric /// Creates an empty directive with the place for \a N clauses. 6730b57cec5SDimitry Andric /// 6740b57cec5SDimitry Andric /// \param C AST context. 6750b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 6760b57cec5SDimitry Andric /// 6770b57cec5SDimitry Andric static OMPParallelDirective *CreateEmpty(const ASTContext &C, 6780b57cec5SDimitry Andric unsigned NumClauses, EmptyShell); 6790b57cec5SDimitry Andric 6805ffd83dbSDimitry Andric /// Returns special task reduction reference expression. getTaskReductionRefExpr()681e8d8bef9SDimitry Andric Expr *getTaskReductionRefExpr() { 682e8d8bef9SDimitry Andric return cast_or_null<Expr>(Data->getChildren()[0]); 683e8d8bef9SDimitry Andric } getTaskReductionRefExpr()684e8d8bef9SDimitry Andric const Expr *getTaskReductionRefExpr() const { 685e8d8bef9SDimitry Andric return const_cast<OMPParallelDirective *>(this)->getTaskReductionRefExpr(); 686e8d8bef9SDimitry Andric } 6875ffd83dbSDimitry Andric 6880b57cec5SDimitry Andric /// Return true if current directive has inner cancel directive. hasCancel()6890b57cec5SDimitry Andric bool hasCancel() const { return HasCancel; } 6900b57cec5SDimitry Andric classof(const Stmt * T)6910b57cec5SDimitry Andric static bool classof(const Stmt *T) { 6920b57cec5SDimitry Andric return T->getStmtClass() == OMPParallelDirectiveClass; 6930b57cec5SDimitry Andric } 6940b57cec5SDimitry Andric }; 6950b57cec5SDimitry Andric 696fe6060f1SDimitry Andric /// The base class for all loop-based directives, including loop transformation 697fe6060f1SDimitry Andric /// directives. 698fe6060f1SDimitry Andric class OMPLoopBasedDirective : public OMPExecutableDirective { 699fe6060f1SDimitry Andric friend class ASTStmtReader; 700fe6060f1SDimitry Andric 701fe6060f1SDimitry Andric protected: 702fe6060f1SDimitry Andric /// Number of collapsed loops as specified by 'collapse' clause. 703fe6060f1SDimitry Andric unsigned NumAssociatedLoops = 0; 704fe6060f1SDimitry Andric 705fe6060f1SDimitry Andric /// Build instance of loop directive of class \a Kind. 706fe6060f1SDimitry Andric /// 707fe6060f1SDimitry Andric /// \param SC Statement class. 708fe6060f1SDimitry Andric /// \param Kind Kind of OpenMP directive. 709fe6060f1SDimitry Andric /// \param StartLoc Starting location of the directive (directive keyword). 710fe6060f1SDimitry Andric /// \param EndLoc Ending location of the directive. 711fe6060f1SDimitry Andric /// \param NumAssociatedLoops Number of loops associated with the construct. 712fe6060f1SDimitry Andric /// OMPLoopBasedDirective(StmtClass SC,OpenMPDirectiveKind Kind,SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumAssociatedLoops)713fe6060f1SDimitry Andric OMPLoopBasedDirective(StmtClass SC, OpenMPDirectiveKind Kind, 714fe6060f1SDimitry Andric SourceLocation StartLoc, SourceLocation EndLoc, 715fe6060f1SDimitry Andric unsigned NumAssociatedLoops) 716fe6060f1SDimitry Andric : OMPExecutableDirective(SC, Kind, StartLoc, EndLoc), 717fe6060f1SDimitry Andric NumAssociatedLoops(NumAssociatedLoops) {} 718fe6060f1SDimitry Andric 719fe6060f1SDimitry Andric public: 720fe6060f1SDimitry Andric /// The expressions built to support OpenMP loops in combined/composite 721fe6060f1SDimitry Andric /// pragmas (e.g. pragma omp distribute parallel for) 722fe6060f1SDimitry Andric struct DistCombinedHelperExprs { 723fe6060f1SDimitry Andric /// DistributeLowerBound - used when composing 'omp distribute' with 724fe6060f1SDimitry Andric /// 'omp for' in a same construct. 725fe6060f1SDimitry Andric Expr *LB; 726fe6060f1SDimitry Andric /// DistributeUpperBound - used when composing 'omp distribute' with 727fe6060f1SDimitry Andric /// 'omp for' in a same construct. 728fe6060f1SDimitry Andric Expr *UB; 729fe6060f1SDimitry Andric /// DistributeEnsureUpperBound - used when composing 'omp distribute' 730fe6060f1SDimitry Andric /// with 'omp for' in a same construct, EUB depends on DistUB 731fe6060f1SDimitry Andric Expr *EUB; 732fe6060f1SDimitry Andric /// Distribute loop iteration variable init used when composing 'omp 733fe6060f1SDimitry Andric /// distribute' 734fe6060f1SDimitry Andric /// with 'omp for' in a same construct 735fe6060f1SDimitry Andric Expr *Init; 736fe6060f1SDimitry Andric /// Distribute Loop condition used when composing 'omp distribute' 737fe6060f1SDimitry Andric /// with 'omp for' in a same construct 738fe6060f1SDimitry Andric Expr *Cond; 739fe6060f1SDimitry Andric /// Update of LowerBound for statically scheduled omp loops for 740fe6060f1SDimitry Andric /// outer loop in combined constructs (e.g. 'distribute parallel for') 741fe6060f1SDimitry Andric Expr *NLB; 742fe6060f1SDimitry Andric /// Update of UpperBound for statically scheduled omp loops for 743fe6060f1SDimitry Andric /// outer loop in combined constructs (e.g. 'distribute parallel for') 744fe6060f1SDimitry Andric Expr *NUB; 745fe6060f1SDimitry Andric /// Distribute Loop condition used when composing 'omp distribute' 746fe6060f1SDimitry Andric /// with 'omp for' in a same construct when schedule is chunked. 747fe6060f1SDimitry Andric Expr *DistCond; 748fe6060f1SDimitry Andric /// 'omp parallel for' loop condition used when composed with 749fe6060f1SDimitry Andric /// 'omp distribute' in the same construct and when schedule is 750fe6060f1SDimitry Andric /// chunked and the chunk size is 1. 751fe6060f1SDimitry Andric Expr *ParForInDistCond; 752fe6060f1SDimitry Andric }; 753fe6060f1SDimitry Andric 754fe6060f1SDimitry Andric /// The expressions built for the OpenMP loop CodeGen for the 755fe6060f1SDimitry Andric /// whole collapsed loop nest. 756fe6060f1SDimitry Andric struct HelperExprs { 757fe6060f1SDimitry Andric /// Loop iteration variable. 758fe6060f1SDimitry Andric Expr *IterationVarRef; 759fe6060f1SDimitry Andric /// Loop last iteration number. 760fe6060f1SDimitry Andric Expr *LastIteration; 761fe6060f1SDimitry Andric /// Loop number of iterations. 762fe6060f1SDimitry Andric Expr *NumIterations; 763fe6060f1SDimitry Andric /// Calculation of last iteration. 764fe6060f1SDimitry Andric Expr *CalcLastIteration; 765fe6060f1SDimitry Andric /// Loop pre-condition. 766fe6060f1SDimitry Andric Expr *PreCond; 767fe6060f1SDimitry Andric /// Loop condition. 768fe6060f1SDimitry Andric Expr *Cond; 769fe6060f1SDimitry Andric /// Loop iteration variable init. 770fe6060f1SDimitry Andric Expr *Init; 771fe6060f1SDimitry Andric /// Loop increment. 772fe6060f1SDimitry Andric Expr *Inc; 773fe6060f1SDimitry Andric /// IsLastIteration - local flag variable passed to runtime. 774fe6060f1SDimitry Andric Expr *IL; 775fe6060f1SDimitry Andric /// LowerBound - local variable passed to runtime. 776fe6060f1SDimitry Andric Expr *LB; 777fe6060f1SDimitry Andric /// UpperBound - local variable passed to runtime. 778fe6060f1SDimitry Andric Expr *UB; 779fe6060f1SDimitry Andric /// Stride - local variable passed to runtime. 780fe6060f1SDimitry Andric Expr *ST; 781fe6060f1SDimitry Andric /// EnsureUpperBound -- expression UB = min(UB, NumIterations). 782fe6060f1SDimitry Andric Expr *EUB; 783fe6060f1SDimitry Andric /// Update of LowerBound for statically scheduled 'omp for' loops. 784fe6060f1SDimitry Andric Expr *NLB; 785fe6060f1SDimitry Andric /// Update of UpperBound for statically scheduled 'omp for' loops. 786fe6060f1SDimitry Andric Expr *NUB; 787fe6060f1SDimitry Andric /// PreviousLowerBound - local variable passed to runtime in the 788fe6060f1SDimitry Andric /// enclosing schedule or null if that does not apply. 789fe6060f1SDimitry Andric Expr *PrevLB; 790fe6060f1SDimitry Andric /// PreviousUpperBound - local variable passed to runtime in the 791fe6060f1SDimitry Andric /// enclosing schedule or null if that does not apply. 792fe6060f1SDimitry Andric Expr *PrevUB; 793fe6060f1SDimitry Andric /// DistInc - increment expression for distribute loop when found 794fe6060f1SDimitry Andric /// combined with a further loop level (e.g. in 'distribute parallel for') 795fe6060f1SDimitry Andric /// expression IV = IV + ST 796fe6060f1SDimitry Andric Expr *DistInc; 797fe6060f1SDimitry Andric /// PrevEUB - expression similar to EUB but to be used when loop 798fe6060f1SDimitry Andric /// scheduling uses PrevLB and PrevUB (e.g. in 'distribute parallel for' 799fe6060f1SDimitry Andric /// when ensuring that the UB is either the calculated UB by the runtime or 800fe6060f1SDimitry Andric /// the end of the assigned distribute chunk) 801fe6060f1SDimitry Andric /// expression UB = min (UB, PrevUB) 802fe6060f1SDimitry Andric Expr *PrevEUB; 803fe6060f1SDimitry Andric /// Counters Loop counters. 804fe6060f1SDimitry Andric SmallVector<Expr *, 4> Counters; 805fe6060f1SDimitry Andric /// PrivateCounters Loop counters. 806fe6060f1SDimitry Andric SmallVector<Expr *, 4> PrivateCounters; 807fe6060f1SDimitry Andric /// Expressions for loop counters inits for CodeGen. 808fe6060f1SDimitry Andric SmallVector<Expr *, 4> Inits; 809fe6060f1SDimitry Andric /// Expressions for loop counters update for CodeGen. 810fe6060f1SDimitry Andric SmallVector<Expr *, 4> Updates; 811fe6060f1SDimitry Andric /// Final loop counter values for GodeGen. 812fe6060f1SDimitry Andric SmallVector<Expr *, 4> Finals; 813fe6060f1SDimitry Andric /// List of counters required for the generation of the non-rectangular 814fe6060f1SDimitry Andric /// loops. 815fe6060f1SDimitry Andric SmallVector<Expr *, 4> DependentCounters; 816fe6060f1SDimitry Andric /// List of initializers required for the generation of the non-rectangular 817fe6060f1SDimitry Andric /// loops. 818fe6060f1SDimitry Andric SmallVector<Expr *, 4> DependentInits; 819fe6060f1SDimitry Andric /// List of final conditions required for the generation of the 820fe6060f1SDimitry Andric /// non-rectangular loops. 821fe6060f1SDimitry Andric SmallVector<Expr *, 4> FinalsConditions; 822fe6060f1SDimitry Andric /// Init statement for all captured expressions. 823fe6060f1SDimitry Andric Stmt *PreInits; 824fe6060f1SDimitry Andric 825fe6060f1SDimitry Andric /// Expressions used when combining OpenMP loop pragmas 826fe6060f1SDimitry Andric DistCombinedHelperExprs DistCombinedFields; 827fe6060f1SDimitry Andric 828fe6060f1SDimitry Andric /// Check if all the expressions are built (does not check the 829fe6060f1SDimitry Andric /// worksharing ones). builtAllHelperExprs830fe6060f1SDimitry Andric bool builtAll() { 831fe6060f1SDimitry Andric return IterationVarRef != nullptr && LastIteration != nullptr && 832fe6060f1SDimitry Andric NumIterations != nullptr && PreCond != nullptr && 833fe6060f1SDimitry Andric Cond != nullptr && Init != nullptr && Inc != nullptr; 834fe6060f1SDimitry Andric } 835fe6060f1SDimitry Andric 836fe6060f1SDimitry Andric /// Initialize all the fields to null. 837fe6060f1SDimitry Andric /// \param Size Number of elements in the 838fe6060f1SDimitry Andric /// counters/finals/updates/dependent_counters/dependent_inits/finals_conditions 839fe6060f1SDimitry Andric /// arrays. clearHelperExprs840fe6060f1SDimitry Andric void clear(unsigned Size) { 841fe6060f1SDimitry Andric IterationVarRef = nullptr; 842fe6060f1SDimitry Andric LastIteration = nullptr; 843fe6060f1SDimitry Andric CalcLastIteration = nullptr; 844fe6060f1SDimitry Andric PreCond = nullptr; 845fe6060f1SDimitry Andric Cond = nullptr; 846fe6060f1SDimitry Andric Init = nullptr; 847fe6060f1SDimitry Andric Inc = nullptr; 848fe6060f1SDimitry Andric IL = nullptr; 849fe6060f1SDimitry Andric LB = nullptr; 850fe6060f1SDimitry Andric UB = nullptr; 851fe6060f1SDimitry Andric ST = nullptr; 852fe6060f1SDimitry Andric EUB = nullptr; 853fe6060f1SDimitry Andric NLB = nullptr; 854fe6060f1SDimitry Andric NUB = nullptr; 855fe6060f1SDimitry Andric NumIterations = nullptr; 856fe6060f1SDimitry Andric PrevLB = nullptr; 857fe6060f1SDimitry Andric PrevUB = nullptr; 858fe6060f1SDimitry Andric DistInc = nullptr; 859fe6060f1SDimitry Andric PrevEUB = nullptr; 860fe6060f1SDimitry Andric Counters.resize(Size); 861fe6060f1SDimitry Andric PrivateCounters.resize(Size); 862fe6060f1SDimitry Andric Inits.resize(Size); 863fe6060f1SDimitry Andric Updates.resize(Size); 864fe6060f1SDimitry Andric Finals.resize(Size); 865fe6060f1SDimitry Andric DependentCounters.resize(Size); 866fe6060f1SDimitry Andric DependentInits.resize(Size); 867fe6060f1SDimitry Andric FinalsConditions.resize(Size); 868fe6060f1SDimitry Andric for (unsigned I = 0; I < Size; ++I) { 869fe6060f1SDimitry Andric Counters[I] = nullptr; 870fe6060f1SDimitry Andric PrivateCounters[I] = nullptr; 871fe6060f1SDimitry Andric Inits[I] = nullptr; 872fe6060f1SDimitry Andric Updates[I] = nullptr; 873fe6060f1SDimitry Andric Finals[I] = nullptr; 874fe6060f1SDimitry Andric DependentCounters[I] = nullptr; 875fe6060f1SDimitry Andric DependentInits[I] = nullptr; 876fe6060f1SDimitry Andric FinalsConditions[I] = nullptr; 877fe6060f1SDimitry Andric } 878fe6060f1SDimitry Andric PreInits = nullptr; 879fe6060f1SDimitry Andric DistCombinedFields.LB = nullptr; 880fe6060f1SDimitry Andric DistCombinedFields.UB = nullptr; 881fe6060f1SDimitry Andric DistCombinedFields.EUB = nullptr; 882fe6060f1SDimitry Andric DistCombinedFields.Init = nullptr; 883fe6060f1SDimitry Andric DistCombinedFields.Cond = nullptr; 884fe6060f1SDimitry Andric DistCombinedFields.NLB = nullptr; 885fe6060f1SDimitry Andric DistCombinedFields.NUB = nullptr; 886fe6060f1SDimitry Andric DistCombinedFields.DistCond = nullptr; 887fe6060f1SDimitry Andric DistCombinedFields.ParForInDistCond = nullptr; 888fe6060f1SDimitry Andric } 889fe6060f1SDimitry Andric }; 890fe6060f1SDimitry Andric 891fe6060f1SDimitry Andric /// Get number of collapsed loops. getLoopsNumber()892fe6060f1SDimitry Andric unsigned getLoopsNumber() const { return NumAssociatedLoops; } 893fe6060f1SDimitry Andric 894fe6060f1SDimitry Andric /// Try to find the next loop sub-statement in the specified statement \p 895fe6060f1SDimitry Andric /// CurStmt. 896fe6060f1SDimitry Andric /// \param TryImperfectlyNestedLoops true, if we need to try to look for the 897fe6060f1SDimitry Andric /// imperfectly nested loop. 898fe6060f1SDimitry Andric static Stmt *tryToFindNextInnerLoop(Stmt *CurStmt, 899fe6060f1SDimitry Andric bool TryImperfectlyNestedLoops); tryToFindNextInnerLoop(const Stmt * CurStmt,bool TryImperfectlyNestedLoops)900fe6060f1SDimitry Andric static const Stmt *tryToFindNextInnerLoop(const Stmt *CurStmt, 901fe6060f1SDimitry Andric bool TryImperfectlyNestedLoops) { 902fe6060f1SDimitry Andric return tryToFindNextInnerLoop(const_cast<Stmt *>(CurStmt), 903fe6060f1SDimitry Andric TryImperfectlyNestedLoops); 904fe6060f1SDimitry Andric } 905fe6060f1SDimitry Andric 906fe6060f1SDimitry Andric /// Calls the specified callback function for all the loops in \p CurStmt, 907fe6060f1SDimitry Andric /// from the outermost to the innermost. 908349cc55cSDimitry Andric static bool 909349cc55cSDimitry Andric doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops, 910fe6060f1SDimitry Andric unsigned NumLoops, 911fe6060f1SDimitry Andric llvm::function_ref<bool(unsigned, Stmt *)> Callback, 912349cc55cSDimitry Andric llvm::function_ref<void(OMPLoopTransformationDirective *)> 913fe6060f1SDimitry Andric OnTransformationCallback); 914fe6060f1SDimitry Andric 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)915fe6060f1SDimitry Andric doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops, 916fe6060f1SDimitry Andric unsigned NumLoops, 917fe6060f1SDimitry Andric llvm::function_ref<bool(unsigned, const Stmt *)> Callback, 918349cc55cSDimitry Andric llvm::function_ref<void(const OMPLoopTransformationDirective *)> 919fe6060f1SDimitry Andric OnTransformationCallback) { 920fe6060f1SDimitry Andric auto &&NewCallback = [Callback](unsigned Cnt, Stmt *CurStmt) { 921fe6060f1SDimitry Andric return Callback(Cnt, CurStmt); 922fe6060f1SDimitry Andric }; 923fe6060f1SDimitry Andric auto &&NewTransformCb = 924349cc55cSDimitry Andric [OnTransformationCallback](OMPLoopTransformationDirective *A) { 925fe6060f1SDimitry Andric OnTransformationCallback(A); 926fe6060f1SDimitry Andric }; 927fe6060f1SDimitry Andric return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops, 928fe6060f1SDimitry Andric NumLoops, NewCallback, NewTransformCb); 929fe6060f1SDimitry Andric } 930fe6060f1SDimitry Andric 931fe6060f1SDimitry Andric /// Calls the specified callback function for all the loops in \p CurStmt, 932fe6060f1SDimitry Andric /// from the outermost to the innermost. 933fe6060f1SDimitry Andric static bool doForAllLoops(Stmt * CurStmt,bool TryImperfectlyNestedLoops,unsigned NumLoops,llvm::function_ref<bool (unsigned,Stmt *)> Callback)934fe6060f1SDimitry Andric doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops, 935fe6060f1SDimitry Andric unsigned NumLoops, 936fe6060f1SDimitry Andric llvm::function_ref<bool(unsigned, Stmt *)> Callback) { 937349cc55cSDimitry Andric auto &&TransformCb = [](OMPLoopTransformationDirective *) {}; 938fe6060f1SDimitry Andric return doForAllLoops(CurStmt, TryImperfectlyNestedLoops, NumLoops, Callback, 939fe6060f1SDimitry Andric TransformCb); 940fe6060f1SDimitry Andric } 941fe6060f1SDimitry Andric static bool doForAllLoops(const Stmt * CurStmt,bool TryImperfectlyNestedLoops,unsigned NumLoops,llvm::function_ref<bool (unsigned,const Stmt *)> Callback)942fe6060f1SDimitry Andric doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops, 943fe6060f1SDimitry Andric unsigned NumLoops, 944fe6060f1SDimitry Andric llvm::function_ref<bool(unsigned, const Stmt *)> Callback) { 945fe6060f1SDimitry Andric auto &&NewCallback = [Callback](unsigned Cnt, const Stmt *CurStmt) { 946fe6060f1SDimitry Andric return Callback(Cnt, CurStmt); 947fe6060f1SDimitry Andric }; 948fe6060f1SDimitry Andric return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops, 949fe6060f1SDimitry Andric NumLoops, NewCallback); 950fe6060f1SDimitry Andric } 951fe6060f1SDimitry Andric 952fe6060f1SDimitry Andric /// Calls the specified callback function for all the loop bodies in \p 953fe6060f1SDimitry Andric /// CurStmt, from the outermost loop to the innermost. 954fe6060f1SDimitry Andric static void doForAllLoopsBodies( 955fe6060f1SDimitry Andric Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops, 956fe6060f1SDimitry Andric llvm::function_ref<void(unsigned, Stmt *, Stmt *)> Callback); doForAllLoopsBodies(const Stmt * CurStmt,bool TryImperfectlyNestedLoops,unsigned NumLoops,llvm::function_ref<void (unsigned,const Stmt *,const Stmt *)> Callback)957fe6060f1SDimitry Andric static void doForAllLoopsBodies( 958fe6060f1SDimitry Andric const Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops, 959fe6060f1SDimitry Andric llvm::function_ref<void(unsigned, const Stmt *, const Stmt *)> Callback) { 960fe6060f1SDimitry Andric auto &&NewCallback = [Callback](unsigned Cnt, Stmt *Loop, Stmt *Body) { 961fe6060f1SDimitry Andric Callback(Cnt, Loop, Body); 962fe6060f1SDimitry Andric }; 963fe6060f1SDimitry Andric doForAllLoopsBodies(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops, 964fe6060f1SDimitry Andric NumLoops, NewCallback); 965fe6060f1SDimitry Andric } 966fe6060f1SDimitry Andric classof(const Stmt * T)967fe6060f1SDimitry Andric static bool classof(const Stmt *T) { 968fe6060f1SDimitry Andric if (auto *D = dyn_cast<OMPExecutableDirective>(T)) 969fe6060f1SDimitry Andric return isOpenMPLoopDirective(D->getDirectiveKind()); 970fe6060f1SDimitry Andric return false; 971fe6060f1SDimitry Andric } 972fe6060f1SDimitry Andric }; 973fe6060f1SDimitry Andric 974349cc55cSDimitry Andric /// The base class for all loop transformation directives. 975349cc55cSDimitry Andric class OMPLoopTransformationDirective : public OMPLoopBasedDirective { 976349cc55cSDimitry Andric friend class ASTStmtReader; 977349cc55cSDimitry Andric 978349cc55cSDimitry Andric /// Number of loops generated by this loop transformation. 979349cc55cSDimitry Andric unsigned NumGeneratedLoops = 0; 980349cc55cSDimitry Andric 981349cc55cSDimitry Andric protected: OMPLoopTransformationDirective(StmtClass SC,OpenMPDirectiveKind Kind,SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumAssociatedLoops)982349cc55cSDimitry Andric explicit OMPLoopTransformationDirective(StmtClass SC, 983349cc55cSDimitry Andric OpenMPDirectiveKind Kind, 984349cc55cSDimitry Andric SourceLocation StartLoc, 985349cc55cSDimitry Andric SourceLocation EndLoc, 986349cc55cSDimitry Andric unsigned NumAssociatedLoops) 987349cc55cSDimitry Andric : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, NumAssociatedLoops) {} 988349cc55cSDimitry Andric 989349cc55cSDimitry Andric /// Set the number of loops generated by this loop transformation. setNumGeneratedLoops(unsigned Num)990349cc55cSDimitry Andric void setNumGeneratedLoops(unsigned Num) { NumGeneratedLoops = Num; } 991349cc55cSDimitry Andric 992349cc55cSDimitry Andric public: 993349cc55cSDimitry Andric /// Return the number of associated (consumed) loops. getNumAssociatedLoops()994349cc55cSDimitry Andric unsigned getNumAssociatedLoops() const { return getLoopsNumber(); } 995349cc55cSDimitry Andric 996349cc55cSDimitry Andric /// Return the number of loops generated by this loop transformation. getNumGeneratedLoops()9975f757f3fSDimitry Andric unsigned getNumGeneratedLoops() const { return NumGeneratedLoops; } 998349cc55cSDimitry Andric 999bdd1243dSDimitry Andric /// Get the de-sugared statements after the loop transformation. 1000349cc55cSDimitry Andric /// 1001349cc55cSDimitry Andric /// Might be nullptr if either the directive generates no loops and is handled 1002349cc55cSDimitry Andric /// directly in CodeGen, or resolving a template-dependence context is 1003349cc55cSDimitry Andric /// required. 1004349cc55cSDimitry Andric Stmt *getTransformedStmt() const; 1005349cc55cSDimitry Andric 1006349cc55cSDimitry Andric /// Return preinits statement. 1007349cc55cSDimitry Andric Stmt *getPreInits() const; 1008349cc55cSDimitry Andric classof(const Stmt * T)1009349cc55cSDimitry Andric static bool classof(const Stmt *T) { 1010349cc55cSDimitry Andric return T->getStmtClass() == OMPTileDirectiveClass || 1011349cc55cSDimitry Andric T->getStmtClass() == OMPUnrollDirectiveClass; 1012349cc55cSDimitry Andric } 1013349cc55cSDimitry Andric }; 1014349cc55cSDimitry Andric 10150b57cec5SDimitry Andric /// This is a common base class for loop directives ('omp simd', 'omp 10160b57cec5SDimitry Andric /// for', 'omp for simd' etc.). It is responsible for the loop code generation. 10170b57cec5SDimitry Andric /// 1018fe6060f1SDimitry Andric class OMPLoopDirective : public OMPLoopBasedDirective { 10190b57cec5SDimitry Andric friend class ASTStmtReader; 10200b57cec5SDimitry Andric 10210b57cec5SDimitry Andric /// Offsets to the stored exprs. 10220b57cec5SDimitry Andric /// This enumeration contains offsets to all the pointers to children 10230b57cec5SDimitry Andric /// expressions stored in OMPLoopDirective. 10240b57cec5SDimitry Andric /// The first 9 children are necessary for all the loop directives, 10250b57cec5SDimitry Andric /// the next 8 are specific to the worksharing ones, and the next 11 are 10260b57cec5SDimitry Andric /// used for combined constructs containing two pragmas associated to loops. 1027fe6060f1SDimitry Andric /// After the fixed children, three arrays of length NumAssociatedLoops are 10280b57cec5SDimitry Andric /// allocated: loop counters, their updates and final values. 10290b57cec5SDimitry Andric /// PrevLowerBound and PrevUpperBound are used to communicate blocking 10300b57cec5SDimitry Andric /// information in composite constructs which require loop blocking 10310b57cec5SDimitry Andric /// DistInc is used to generate the increment expression for the distribute 10320b57cec5SDimitry Andric /// loop when combined with a further nested loop 10330b57cec5SDimitry Andric /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the 10340b57cec5SDimitry Andric /// for loop when combined with a previous distribute loop in the same pragma 10350b57cec5SDimitry Andric /// (e.g. 'distribute parallel for') 10360b57cec5SDimitry Andric /// 10370b57cec5SDimitry Andric enum { 1038e8d8bef9SDimitry Andric IterationVariableOffset = 0, 1039e8d8bef9SDimitry Andric LastIterationOffset = 1, 1040e8d8bef9SDimitry Andric CalcLastIterationOffset = 2, 1041e8d8bef9SDimitry Andric PreConditionOffset = 3, 1042e8d8bef9SDimitry Andric CondOffset = 4, 1043e8d8bef9SDimitry Andric InitOffset = 5, 1044e8d8bef9SDimitry Andric IncOffset = 6, 1045e8d8bef9SDimitry Andric PreInitsOffset = 7, 10460b57cec5SDimitry Andric // The '...End' enumerators do not correspond to child expressions - they 10470b57cec5SDimitry Andric // specify the offset to the end (and start of the following counters/ 1048a7dea167SDimitry Andric // updates/finals/dependent_counters/dependent_inits/finals_conditions 1049a7dea167SDimitry Andric // arrays). 1050e8d8bef9SDimitry Andric DefaultEnd = 8, 10510b57cec5SDimitry Andric // The following 8 exprs are used by worksharing and distribute loops only. 1052e8d8bef9SDimitry Andric IsLastIterVariableOffset = 8, 1053e8d8bef9SDimitry Andric LowerBoundVariableOffset = 9, 1054e8d8bef9SDimitry Andric UpperBoundVariableOffset = 10, 1055e8d8bef9SDimitry Andric StrideVariableOffset = 11, 1056e8d8bef9SDimitry Andric EnsureUpperBoundOffset = 12, 1057e8d8bef9SDimitry Andric NextLowerBoundOffset = 13, 1058e8d8bef9SDimitry Andric NextUpperBoundOffset = 14, 1059e8d8bef9SDimitry Andric NumIterationsOffset = 15, 10600b57cec5SDimitry Andric // Offset to the end for worksharing loop directives. 1061e8d8bef9SDimitry Andric WorksharingEnd = 16, 1062e8d8bef9SDimitry Andric PrevLowerBoundVariableOffset = 16, 1063e8d8bef9SDimitry Andric PrevUpperBoundVariableOffset = 17, 1064e8d8bef9SDimitry Andric DistIncOffset = 18, 1065e8d8bef9SDimitry Andric PrevEnsureUpperBoundOffset = 19, 1066e8d8bef9SDimitry Andric CombinedLowerBoundVariableOffset = 20, 1067e8d8bef9SDimitry Andric CombinedUpperBoundVariableOffset = 21, 1068e8d8bef9SDimitry Andric CombinedEnsureUpperBoundOffset = 22, 1069e8d8bef9SDimitry Andric CombinedInitOffset = 23, 1070e8d8bef9SDimitry Andric CombinedConditionOffset = 24, 1071e8d8bef9SDimitry Andric CombinedNextLowerBoundOffset = 25, 1072e8d8bef9SDimitry Andric CombinedNextUpperBoundOffset = 26, 1073e8d8bef9SDimitry Andric CombinedDistConditionOffset = 27, 1074e8d8bef9SDimitry Andric CombinedParForInDistConditionOffset = 28, 1075a7dea167SDimitry Andric // Offset to the end (and start of the following 1076a7dea167SDimitry Andric // counters/updates/finals/dependent_counters/dependent_inits/finals_conditions 10770b57cec5SDimitry Andric // arrays) for combined distribute loop directives. 1078e8d8bef9SDimitry Andric CombinedDistributeEnd = 29, 10790b57cec5SDimitry Andric }; 10800b57cec5SDimitry Andric 10810b57cec5SDimitry Andric /// Get the counters storage. getCounters()10820b57cec5SDimitry Andric MutableArrayRef<Expr *> getCounters() { 1083e8d8bef9SDimitry Andric auto **Storage = reinterpret_cast<Expr **>( 1084e8d8bef9SDimitry Andric &Data->getChildren()[getArraysOffset(getDirectiveKind())]); 1085bdd1243dSDimitry Andric return llvm::MutableArrayRef(Storage, getLoopsNumber()); 10860b57cec5SDimitry Andric } 10870b57cec5SDimitry Andric 10880b57cec5SDimitry Andric /// Get the private counters storage. getPrivateCounters()10890b57cec5SDimitry Andric MutableArrayRef<Expr *> getPrivateCounters() { 1090e8d8bef9SDimitry Andric auto **Storage = reinterpret_cast<Expr **>( 1091e8d8bef9SDimitry Andric &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1092fe6060f1SDimitry Andric getLoopsNumber()]); 1093bdd1243dSDimitry Andric return llvm::MutableArrayRef(Storage, getLoopsNumber()); 10940b57cec5SDimitry Andric } 10950b57cec5SDimitry Andric 10960b57cec5SDimitry Andric /// Get the updates storage. getInits()10970b57cec5SDimitry Andric MutableArrayRef<Expr *> getInits() { 1098e8d8bef9SDimitry Andric auto **Storage = reinterpret_cast<Expr **>( 1099e8d8bef9SDimitry Andric &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1100fe6060f1SDimitry Andric 2 * getLoopsNumber()]); 1101bdd1243dSDimitry Andric return llvm::MutableArrayRef(Storage, getLoopsNumber()); 11020b57cec5SDimitry Andric } 11030b57cec5SDimitry Andric 11040b57cec5SDimitry Andric /// Get the updates storage. getUpdates()11050b57cec5SDimitry Andric MutableArrayRef<Expr *> getUpdates() { 1106e8d8bef9SDimitry Andric auto **Storage = reinterpret_cast<Expr **>( 1107e8d8bef9SDimitry Andric &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1108fe6060f1SDimitry Andric 3 * getLoopsNumber()]); 1109bdd1243dSDimitry Andric return llvm::MutableArrayRef(Storage, getLoopsNumber()); 11100b57cec5SDimitry Andric } 11110b57cec5SDimitry Andric 11120b57cec5SDimitry Andric /// Get the final counter updates storage. getFinals()11130b57cec5SDimitry Andric MutableArrayRef<Expr *> getFinals() { 1114e8d8bef9SDimitry Andric auto **Storage = reinterpret_cast<Expr **>( 1115e8d8bef9SDimitry Andric &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1116fe6060f1SDimitry Andric 4 * getLoopsNumber()]); 1117bdd1243dSDimitry Andric return llvm::MutableArrayRef(Storage, getLoopsNumber()); 11180b57cec5SDimitry Andric } 11190b57cec5SDimitry Andric 1120a7dea167SDimitry Andric /// Get the dependent counters storage. getDependentCounters()1121a7dea167SDimitry Andric MutableArrayRef<Expr *> getDependentCounters() { 1122e8d8bef9SDimitry Andric auto **Storage = reinterpret_cast<Expr **>( 1123e8d8bef9SDimitry Andric &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1124fe6060f1SDimitry Andric 5 * getLoopsNumber()]); 1125bdd1243dSDimitry Andric return llvm::MutableArrayRef(Storage, getLoopsNumber()); 1126a7dea167SDimitry Andric } 1127a7dea167SDimitry Andric 1128a7dea167SDimitry Andric /// Get the dependent inits storage. getDependentInits()1129a7dea167SDimitry Andric MutableArrayRef<Expr *> getDependentInits() { 1130e8d8bef9SDimitry Andric auto **Storage = reinterpret_cast<Expr **>( 1131e8d8bef9SDimitry Andric &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1132fe6060f1SDimitry Andric 6 * getLoopsNumber()]); 1133bdd1243dSDimitry Andric return llvm::MutableArrayRef(Storage, getLoopsNumber()); 1134a7dea167SDimitry Andric } 1135a7dea167SDimitry Andric 1136a7dea167SDimitry Andric /// Get the finals conditions storage. getFinalsConditions()1137a7dea167SDimitry Andric MutableArrayRef<Expr *> getFinalsConditions() { 1138e8d8bef9SDimitry Andric auto **Storage = reinterpret_cast<Expr **>( 1139e8d8bef9SDimitry Andric &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1140fe6060f1SDimitry Andric 7 * getLoopsNumber()]); 1141bdd1243dSDimitry Andric return llvm::MutableArrayRef(Storage, getLoopsNumber()); 1142a7dea167SDimitry Andric } 1143a7dea167SDimitry Andric 11440b57cec5SDimitry Andric protected: 11450b57cec5SDimitry Andric /// Build instance of loop directive of class \a Kind. 11460b57cec5SDimitry Andric /// 11470b57cec5SDimitry Andric /// \param SC Statement class. 11480b57cec5SDimitry Andric /// \param Kind Kind of OpenMP directive. 11490b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive (directive keyword). 11500b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 11510b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops from 'collapse' clause. 11520b57cec5SDimitry Andric /// OMPLoopDirective(StmtClass SC,OpenMPDirectiveKind Kind,SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)1153e8d8bef9SDimitry Andric OMPLoopDirective(StmtClass SC, OpenMPDirectiveKind Kind, 11540b57cec5SDimitry Andric SourceLocation StartLoc, SourceLocation EndLoc, 1155e8d8bef9SDimitry Andric unsigned CollapsedNum) 1156fe6060f1SDimitry Andric : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, CollapsedNum) {} 11570b57cec5SDimitry Andric 11580b57cec5SDimitry Andric /// Offset to the start of children expression arrays. getArraysOffset(OpenMPDirectiveKind Kind)11590b57cec5SDimitry Andric static unsigned getArraysOffset(OpenMPDirectiveKind Kind) { 11600b57cec5SDimitry Andric if (isOpenMPLoopBoundSharingDirective(Kind)) 11610b57cec5SDimitry Andric return CombinedDistributeEnd; 11620b57cec5SDimitry Andric if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) || 1163349cc55cSDimitry Andric isOpenMPGenericLoopDirective(Kind) || isOpenMPDistributeDirective(Kind)) 11640b57cec5SDimitry Andric return WorksharingEnd; 11650b57cec5SDimitry Andric return DefaultEnd; 11660b57cec5SDimitry Andric } 11670b57cec5SDimitry Andric 11680b57cec5SDimitry Andric /// Children number. numLoopChildren(unsigned CollapsedNum,OpenMPDirectiveKind Kind)11690b57cec5SDimitry Andric static unsigned numLoopChildren(unsigned CollapsedNum, 11700b57cec5SDimitry Andric OpenMPDirectiveKind Kind) { 1171a7dea167SDimitry Andric return getArraysOffset(Kind) + 1172a7dea167SDimitry Andric 8 * CollapsedNum; // Counters, PrivateCounters, Inits, 1173a7dea167SDimitry Andric // Updates, Finals, DependentCounters, 1174a7dea167SDimitry Andric // DependentInits, FinalsConditions. 11750b57cec5SDimitry Andric } 11760b57cec5SDimitry Andric setIterationVariable(Expr * IV)11770b57cec5SDimitry Andric void setIterationVariable(Expr *IV) { 1178e8d8bef9SDimitry Andric Data->getChildren()[IterationVariableOffset] = IV; 11790b57cec5SDimitry Andric } setLastIteration(Expr * LI)11800b57cec5SDimitry Andric void setLastIteration(Expr *LI) { 1181e8d8bef9SDimitry Andric Data->getChildren()[LastIterationOffset] = LI; 11820b57cec5SDimitry Andric } setCalcLastIteration(Expr * CLI)11830b57cec5SDimitry Andric void setCalcLastIteration(Expr *CLI) { 1184e8d8bef9SDimitry Andric Data->getChildren()[CalcLastIterationOffset] = CLI; 11850b57cec5SDimitry Andric } setPreCond(Expr * PC)1186e8d8bef9SDimitry Andric void setPreCond(Expr *PC) { Data->getChildren()[PreConditionOffset] = PC; } setCond(Expr * Cond)1187e8d8bef9SDimitry Andric void setCond(Expr *Cond) { Data->getChildren()[CondOffset] = Cond; } setInit(Expr * Init)1188e8d8bef9SDimitry Andric void setInit(Expr *Init) { Data->getChildren()[InitOffset] = Init; } setInc(Expr * Inc)1189e8d8bef9SDimitry Andric void setInc(Expr *Inc) { Data->getChildren()[IncOffset] = Inc; } setPreInits(Stmt * PreInits)11900b57cec5SDimitry Andric void setPreInits(Stmt *PreInits) { 1191e8d8bef9SDimitry Andric Data->getChildren()[PreInitsOffset] = PreInits; 11920b57cec5SDimitry Andric } setIsLastIterVariable(Expr * IL)11930b57cec5SDimitry Andric void setIsLastIterVariable(Expr *IL) { 11940b57cec5SDimitry Andric assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1195349cc55cSDimitry Andric isOpenMPGenericLoopDirective(getDirectiveKind()) || 11960b57cec5SDimitry Andric isOpenMPTaskLoopDirective(getDirectiveKind()) || 11970b57cec5SDimitry Andric isOpenMPDistributeDirective(getDirectiveKind())) && 11980b57cec5SDimitry Andric "expected worksharing loop directive"); 1199e8d8bef9SDimitry Andric Data->getChildren()[IsLastIterVariableOffset] = IL; 12000b57cec5SDimitry Andric } setLowerBoundVariable(Expr * LB)12010b57cec5SDimitry Andric void setLowerBoundVariable(Expr *LB) { 12020b57cec5SDimitry Andric assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1203349cc55cSDimitry Andric isOpenMPGenericLoopDirective(getDirectiveKind()) || 12040b57cec5SDimitry Andric isOpenMPTaskLoopDirective(getDirectiveKind()) || 12050b57cec5SDimitry Andric isOpenMPDistributeDirective(getDirectiveKind())) && 12060b57cec5SDimitry Andric "expected worksharing loop directive"); 1207e8d8bef9SDimitry Andric Data->getChildren()[LowerBoundVariableOffset] = LB; 12080b57cec5SDimitry Andric } setUpperBoundVariable(Expr * UB)12090b57cec5SDimitry Andric void setUpperBoundVariable(Expr *UB) { 12100b57cec5SDimitry Andric assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1211349cc55cSDimitry Andric isOpenMPGenericLoopDirective(getDirectiveKind()) || 12120b57cec5SDimitry Andric isOpenMPTaskLoopDirective(getDirectiveKind()) || 12130b57cec5SDimitry Andric isOpenMPDistributeDirective(getDirectiveKind())) && 12140b57cec5SDimitry Andric "expected worksharing loop directive"); 1215e8d8bef9SDimitry Andric Data->getChildren()[UpperBoundVariableOffset] = UB; 12160b57cec5SDimitry Andric } setStrideVariable(Expr * ST)12170b57cec5SDimitry Andric void setStrideVariable(Expr *ST) { 12180b57cec5SDimitry Andric assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1219349cc55cSDimitry Andric isOpenMPGenericLoopDirective(getDirectiveKind()) || 12200b57cec5SDimitry Andric isOpenMPTaskLoopDirective(getDirectiveKind()) || 12210b57cec5SDimitry Andric isOpenMPDistributeDirective(getDirectiveKind())) && 12220b57cec5SDimitry Andric "expected worksharing loop directive"); 1223e8d8bef9SDimitry Andric Data->getChildren()[StrideVariableOffset] = ST; 12240b57cec5SDimitry Andric } setEnsureUpperBound(Expr * EUB)12250b57cec5SDimitry Andric void setEnsureUpperBound(Expr *EUB) { 12260b57cec5SDimitry Andric assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1227349cc55cSDimitry Andric isOpenMPGenericLoopDirective(getDirectiveKind()) || 12280b57cec5SDimitry Andric isOpenMPTaskLoopDirective(getDirectiveKind()) || 12290b57cec5SDimitry Andric isOpenMPDistributeDirective(getDirectiveKind())) && 12300b57cec5SDimitry Andric "expected worksharing loop directive"); 1231e8d8bef9SDimitry Andric Data->getChildren()[EnsureUpperBoundOffset] = EUB; 12320b57cec5SDimitry Andric } setNextLowerBound(Expr * NLB)12330b57cec5SDimitry Andric void setNextLowerBound(Expr *NLB) { 12340b57cec5SDimitry Andric assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1235349cc55cSDimitry Andric isOpenMPGenericLoopDirective(getDirectiveKind()) || 12360b57cec5SDimitry Andric isOpenMPTaskLoopDirective(getDirectiveKind()) || 12370b57cec5SDimitry Andric isOpenMPDistributeDirective(getDirectiveKind())) && 12380b57cec5SDimitry Andric "expected worksharing loop directive"); 1239e8d8bef9SDimitry Andric Data->getChildren()[NextLowerBoundOffset] = NLB; 12400b57cec5SDimitry Andric } setNextUpperBound(Expr * NUB)12410b57cec5SDimitry Andric void setNextUpperBound(Expr *NUB) { 12420b57cec5SDimitry Andric assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1243349cc55cSDimitry Andric isOpenMPGenericLoopDirective(getDirectiveKind()) || 12440b57cec5SDimitry Andric isOpenMPTaskLoopDirective(getDirectiveKind()) || 12450b57cec5SDimitry Andric isOpenMPDistributeDirective(getDirectiveKind())) && 12460b57cec5SDimitry Andric "expected worksharing loop directive"); 1247e8d8bef9SDimitry Andric Data->getChildren()[NextUpperBoundOffset] = NUB; 12480b57cec5SDimitry Andric } setNumIterations(Expr * NI)12490b57cec5SDimitry Andric void setNumIterations(Expr *NI) { 12500b57cec5SDimitry Andric assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1251349cc55cSDimitry Andric isOpenMPGenericLoopDirective(getDirectiveKind()) || 12520b57cec5SDimitry Andric isOpenMPTaskLoopDirective(getDirectiveKind()) || 12530b57cec5SDimitry Andric isOpenMPDistributeDirective(getDirectiveKind())) && 12540b57cec5SDimitry Andric "expected worksharing loop directive"); 1255e8d8bef9SDimitry Andric Data->getChildren()[NumIterationsOffset] = NI; 12560b57cec5SDimitry Andric } setPrevLowerBoundVariable(Expr * PrevLB)12570b57cec5SDimitry Andric void setPrevLowerBoundVariable(Expr *PrevLB) { 12580b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 12590b57cec5SDimitry Andric "expected loop bound sharing directive"); 1260e8d8bef9SDimitry Andric Data->getChildren()[PrevLowerBoundVariableOffset] = PrevLB; 12610b57cec5SDimitry Andric } setPrevUpperBoundVariable(Expr * PrevUB)12620b57cec5SDimitry Andric void setPrevUpperBoundVariable(Expr *PrevUB) { 12630b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 12640b57cec5SDimitry Andric "expected loop bound sharing directive"); 1265e8d8bef9SDimitry Andric Data->getChildren()[PrevUpperBoundVariableOffset] = PrevUB; 12660b57cec5SDimitry Andric } setDistInc(Expr * DistInc)12670b57cec5SDimitry Andric void setDistInc(Expr *DistInc) { 12680b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 12690b57cec5SDimitry Andric "expected loop bound sharing directive"); 1270e8d8bef9SDimitry Andric Data->getChildren()[DistIncOffset] = DistInc; 12710b57cec5SDimitry Andric } setPrevEnsureUpperBound(Expr * PrevEUB)12720b57cec5SDimitry Andric void setPrevEnsureUpperBound(Expr *PrevEUB) { 12730b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 12740b57cec5SDimitry Andric "expected loop bound sharing directive"); 1275e8d8bef9SDimitry Andric Data->getChildren()[PrevEnsureUpperBoundOffset] = PrevEUB; 12760b57cec5SDimitry Andric } setCombinedLowerBoundVariable(Expr * CombLB)12770b57cec5SDimitry Andric void setCombinedLowerBoundVariable(Expr *CombLB) { 12780b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 12790b57cec5SDimitry Andric "expected loop bound sharing directive"); 1280e8d8bef9SDimitry Andric Data->getChildren()[CombinedLowerBoundVariableOffset] = CombLB; 12810b57cec5SDimitry Andric } setCombinedUpperBoundVariable(Expr * CombUB)12820b57cec5SDimitry Andric void setCombinedUpperBoundVariable(Expr *CombUB) { 12830b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 12840b57cec5SDimitry Andric "expected loop bound sharing directive"); 1285e8d8bef9SDimitry Andric Data->getChildren()[CombinedUpperBoundVariableOffset] = CombUB; 12860b57cec5SDimitry Andric } setCombinedEnsureUpperBound(Expr * CombEUB)12870b57cec5SDimitry Andric void setCombinedEnsureUpperBound(Expr *CombEUB) { 12880b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 12890b57cec5SDimitry Andric "expected loop bound sharing directive"); 1290e8d8bef9SDimitry Andric Data->getChildren()[CombinedEnsureUpperBoundOffset] = CombEUB; 12910b57cec5SDimitry Andric } setCombinedInit(Expr * CombInit)12920b57cec5SDimitry Andric void setCombinedInit(Expr *CombInit) { 12930b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 12940b57cec5SDimitry Andric "expected loop bound sharing directive"); 1295e8d8bef9SDimitry Andric Data->getChildren()[CombinedInitOffset] = CombInit; 12960b57cec5SDimitry Andric } setCombinedCond(Expr * CombCond)12970b57cec5SDimitry Andric void setCombinedCond(Expr *CombCond) { 12980b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 12990b57cec5SDimitry Andric "expected loop bound sharing directive"); 1300e8d8bef9SDimitry Andric Data->getChildren()[CombinedConditionOffset] = CombCond; 13010b57cec5SDimitry Andric } setCombinedNextLowerBound(Expr * CombNLB)13020b57cec5SDimitry Andric void setCombinedNextLowerBound(Expr *CombNLB) { 13030b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 13040b57cec5SDimitry Andric "expected loop bound sharing directive"); 1305e8d8bef9SDimitry Andric Data->getChildren()[CombinedNextLowerBoundOffset] = CombNLB; 13060b57cec5SDimitry Andric } setCombinedNextUpperBound(Expr * CombNUB)13070b57cec5SDimitry Andric void setCombinedNextUpperBound(Expr *CombNUB) { 13080b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 13090b57cec5SDimitry Andric "expected loop bound sharing directive"); 1310e8d8bef9SDimitry Andric Data->getChildren()[CombinedNextUpperBoundOffset] = CombNUB; 13110b57cec5SDimitry Andric } setCombinedDistCond(Expr * CombDistCond)13120b57cec5SDimitry Andric void setCombinedDistCond(Expr *CombDistCond) { 13130b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 13140b57cec5SDimitry Andric "expected loop bound distribute sharing directive"); 1315e8d8bef9SDimitry Andric Data->getChildren()[CombinedDistConditionOffset] = CombDistCond; 13160b57cec5SDimitry Andric } setCombinedParForInDistCond(Expr * CombParForInDistCond)13170b57cec5SDimitry Andric void setCombinedParForInDistCond(Expr *CombParForInDistCond) { 13180b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 13190b57cec5SDimitry Andric "expected loop bound distribute sharing directive"); 1320e8d8bef9SDimitry Andric Data->getChildren()[CombinedParForInDistConditionOffset] = 1321e8d8bef9SDimitry Andric CombParForInDistCond; 13220b57cec5SDimitry Andric } 13230b57cec5SDimitry Andric void setCounters(ArrayRef<Expr *> A); 13240b57cec5SDimitry Andric void setPrivateCounters(ArrayRef<Expr *> A); 13250b57cec5SDimitry Andric void setInits(ArrayRef<Expr *> A); 13260b57cec5SDimitry Andric void setUpdates(ArrayRef<Expr *> A); 13270b57cec5SDimitry Andric void setFinals(ArrayRef<Expr *> A); 1328a7dea167SDimitry Andric void setDependentCounters(ArrayRef<Expr *> A); 1329a7dea167SDimitry Andric void setDependentInits(ArrayRef<Expr *> A); 1330a7dea167SDimitry Andric void setFinalsConditions(ArrayRef<Expr *> A); 13310b57cec5SDimitry Andric 13320b57cec5SDimitry Andric public: getIterationVariable()13330b57cec5SDimitry Andric Expr *getIterationVariable() const { 1334e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[IterationVariableOffset]); 13350b57cec5SDimitry Andric } getLastIteration()13360b57cec5SDimitry Andric Expr *getLastIteration() const { 1337e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[LastIterationOffset]); 13380b57cec5SDimitry Andric } getCalcLastIteration()13390b57cec5SDimitry Andric Expr *getCalcLastIteration() const { 1340e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[CalcLastIterationOffset]); 13410b57cec5SDimitry Andric } getPreCond()13420b57cec5SDimitry Andric Expr *getPreCond() const { 1343e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[PreConditionOffset]); 13440b57cec5SDimitry Andric } getCond()1345e8d8bef9SDimitry Andric Expr *getCond() const { return cast<Expr>(Data->getChildren()[CondOffset]); } getInit()1346e8d8bef9SDimitry Andric Expr *getInit() const { return cast<Expr>(Data->getChildren()[InitOffset]); } getInc()1347e8d8bef9SDimitry Andric Expr *getInc() const { return cast<Expr>(Data->getChildren()[IncOffset]); } getPreInits()13480b57cec5SDimitry Andric const Stmt *getPreInits() const { 1349e8d8bef9SDimitry Andric return Data->getChildren()[PreInitsOffset]; 13500b57cec5SDimitry Andric } getPreInits()1351e8d8bef9SDimitry Andric Stmt *getPreInits() { return Data->getChildren()[PreInitsOffset]; } getIsLastIterVariable()13520b57cec5SDimitry Andric Expr *getIsLastIterVariable() const { 13530b57cec5SDimitry Andric assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1354349cc55cSDimitry Andric isOpenMPGenericLoopDirective(getDirectiveKind()) || 13550b57cec5SDimitry Andric isOpenMPTaskLoopDirective(getDirectiveKind()) || 13560b57cec5SDimitry Andric isOpenMPDistributeDirective(getDirectiveKind())) && 13570b57cec5SDimitry Andric "expected worksharing loop directive"); 1358e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[IsLastIterVariableOffset]); 13590b57cec5SDimitry Andric } getLowerBoundVariable()13600b57cec5SDimitry Andric Expr *getLowerBoundVariable() const { 13610b57cec5SDimitry Andric assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1362349cc55cSDimitry Andric isOpenMPGenericLoopDirective(getDirectiveKind()) || 13630b57cec5SDimitry Andric isOpenMPTaskLoopDirective(getDirectiveKind()) || 13640b57cec5SDimitry Andric isOpenMPDistributeDirective(getDirectiveKind())) && 13650b57cec5SDimitry Andric "expected worksharing loop directive"); 1366e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[LowerBoundVariableOffset]); 13670b57cec5SDimitry Andric } getUpperBoundVariable()13680b57cec5SDimitry Andric Expr *getUpperBoundVariable() const { 13690b57cec5SDimitry Andric assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1370349cc55cSDimitry Andric isOpenMPGenericLoopDirective(getDirectiveKind()) || 13710b57cec5SDimitry Andric isOpenMPTaskLoopDirective(getDirectiveKind()) || 13720b57cec5SDimitry Andric isOpenMPDistributeDirective(getDirectiveKind())) && 13730b57cec5SDimitry Andric "expected worksharing loop directive"); 1374e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[UpperBoundVariableOffset]); 13750b57cec5SDimitry Andric } getStrideVariable()13760b57cec5SDimitry Andric Expr *getStrideVariable() const { 13770b57cec5SDimitry Andric assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1378349cc55cSDimitry Andric isOpenMPGenericLoopDirective(getDirectiveKind()) || 13790b57cec5SDimitry Andric isOpenMPTaskLoopDirective(getDirectiveKind()) || 13800b57cec5SDimitry Andric isOpenMPDistributeDirective(getDirectiveKind())) && 13810b57cec5SDimitry Andric "expected worksharing loop directive"); 1382e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[StrideVariableOffset]); 13830b57cec5SDimitry Andric } getEnsureUpperBound()13840b57cec5SDimitry Andric Expr *getEnsureUpperBound() const { 13850b57cec5SDimitry Andric assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1386349cc55cSDimitry Andric isOpenMPGenericLoopDirective(getDirectiveKind()) || 13870b57cec5SDimitry Andric isOpenMPTaskLoopDirective(getDirectiveKind()) || 13880b57cec5SDimitry Andric isOpenMPDistributeDirective(getDirectiveKind())) && 13890b57cec5SDimitry Andric "expected worksharing loop directive"); 1390e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[EnsureUpperBoundOffset]); 13910b57cec5SDimitry Andric } getNextLowerBound()13920b57cec5SDimitry Andric Expr *getNextLowerBound() const { 13930b57cec5SDimitry Andric assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1394349cc55cSDimitry Andric isOpenMPGenericLoopDirective(getDirectiveKind()) || 13950b57cec5SDimitry Andric isOpenMPTaskLoopDirective(getDirectiveKind()) || 13960b57cec5SDimitry Andric isOpenMPDistributeDirective(getDirectiveKind())) && 13970b57cec5SDimitry Andric "expected worksharing loop directive"); 1398e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[NextLowerBoundOffset]); 13990b57cec5SDimitry Andric } getNextUpperBound()14000b57cec5SDimitry Andric Expr *getNextUpperBound() const { 14010b57cec5SDimitry Andric assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1402349cc55cSDimitry Andric isOpenMPGenericLoopDirective(getDirectiveKind()) || 14030b57cec5SDimitry Andric isOpenMPTaskLoopDirective(getDirectiveKind()) || 14040b57cec5SDimitry Andric isOpenMPDistributeDirective(getDirectiveKind())) && 14050b57cec5SDimitry Andric "expected worksharing loop directive"); 1406e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[NextUpperBoundOffset]); 14070b57cec5SDimitry Andric } getNumIterations()14080b57cec5SDimitry Andric Expr *getNumIterations() const { 14090b57cec5SDimitry Andric assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1410349cc55cSDimitry Andric isOpenMPGenericLoopDirective(getDirectiveKind()) || 14110b57cec5SDimitry Andric isOpenMPTaskLoopDirective(getDirectiveKind()) || 14120b57cec5SDimitry Andric isOpenMPDistributeDirective(getDirectiveKind())) && 14130b57cec5SDimitry Andric "expected worksharing loop directive"); 1414e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[NumIterationsOffset]); 14150b57cec5SDimitry Andric } getPrevLowerBoundVariable()14160b57cec5SDimitry Andric Expr *getPrevLowerBoundVariable() const { 14170b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 14180b57cec5SDimitry Andric "expected loop bound sharing directive"); 1419e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[PrevLowerBoundVariableOffset]); 14200b57cec5SDimitry Andric } getPrevUpperBoundVariable()14210b57cec5SDimitry Andric Expr *getPrevUpperBoundVariable() const { 14220b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 14230b57cec5SDimitry Andric "expected loop bound sharing directive"); 1424e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[PrevUpperBoundVariableOffset]); 14250b57cec5SDimitry Andric } getDistInc()14260b57cec5SDimitry Andric Expr *getDistInc() const { 14270b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 14280b57cec5SDimitry Andric "expected loop bound sharing directive"); 1429e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[DistIncOffset]); 14300b57cec5SDimitry Andric } getPrevEnsureUpperBound()14310b57cec5SDimitry Andric Expr *getPrevEnsureUpperBound() const { 14320b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 14330b57cec5SDimitry Andric "expected loop bound sharing directive"); 1434e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[PrevEnsureUpperBoundOffset]); 14350b57cec5SDimitry Andric } getCombinedLowerBoundVariable()14360b57cec5SDimitry Andric Expr *getCombinedLowerBoundVariable() const { 14370b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 14380b57cec5SDimitry Andric "expected loop bound sharing directive"); 1439e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[CombinedLowerBoundVariableOffset]); 14400b57cec5SDimitry Andric } getCombinedUpperBoundVariable()14410b57cec5SDimitry Andric Expr *getCombinedUpperBoundVariable() const { 14420b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 14430b57cec5SDimitry Andric "expected loop bound sharing directive"); 1444e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[CombinedUpperBoundVariableOffset]); 14450b57cec5SDimitry Andric } getCombinedEnsureUpperBound()14460b57cec5SDimitry Andric Expr *getCombinedEnsureUpperBound() const { 14470b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 14480b57cec5SDimitry Andric "expected loop bound sharing directive"); 1449e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[CombinedEnsureUpperBoundOffset]); 14500b57cec5SDimitry Andric } getCombinedInit()14510b57cec5SDimitry Andric Expr *getCombinedInit() const { 14520b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 14530b57cec5SDimitry Andric "expected loop bound sharing directive"); 1454e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[CombinedInitOffset]); 14550b57cec5SDimitry Andric } getCombinedCond()14560b57cec5SDimitry Andric Expr *getCombinedCond() const { 14570b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 14580b57cec5SDimitry Andric "expected loop bound sharing directive"); 1459e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[CombinedConditionOffset]); 14600b57cec5SDimitry Andric } getCombinedNextLowerBound()14610b57cec5SDimitry Andric Expr *getCombinedNextLowerBound() const { 14620b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 14630b57cec5SDimitry Andric "expected loop bound sharing directive"); 1464e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[CombinedNextLowerBoundOffset]); 14650b57cec5SDimitry Andric } getCombinedNextUpperBound()14660b57cec5SDimitry Andric Expr *getCombinedNextUpperBound() const { 14670b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 14680b57cec5SDimitry Andric "expected loop bound sharing directive"); 1469e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[CombinedNextUpperBoundOffset]); 14700b57cec5SDimitry Andric } getCombinedDistCond()14710b57cec5SDimitry Andric Expr *getCombinedDistCond() const { 14720b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 14730b57cec5SDimitry Andric "expected loop bound distribute sharing directive"); 1474e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[CombinedDistConditionOffset]); 14750b57cec5SDimitry Andric } getCombinedParForInDistCond()14760b57cec5SDimitry Andric Expr *getCombinedParForInDistCond() const { 14770b57cec5SDimitry Andric assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 14780b57cec5SDimitry Andric "expected loop bound distribute sharing directive"); 1479e8d8bef9SDimitry Andric return cast<Expr>(Data->getChildren()[CombinedParForInDistConditionOffset]); 14800b57cec5SDimitry Andric } 1481480093f4SDimitry Andric Stmt *getBody(); getBody()14820b57cec5SDimitry Andric const Stmt *getBody() const { 1483480093f4SDimitry Andric return const_cast<OMPLoopDirective *>(this)->getBody(); 14840b57cec5SDimitry Andric } 14850b57cec5SDimitry Andric counters()14860b57cec5SDimitry Andric ArrayRef<Expr *> counters() { return getCounters(); } 14870b57cec5SDimitry Andric counters()14880b57cec5SDimitry Andric ArrayRef<Expr *> counters() const { 14890b57cec5SDimitry Andric return const_cast<OMPLoopDirective *>(this)->getCounters(); 14900b57cec5SDimitry Andric } 14910b57cec5SDimitry Andric private_counters()14920b57cec5SDimitry Andric ArrayRef<Expr *> private_counters() { return getPrivateCounters(); } 14930b57cec5SDimitry Andric private_counters()14940b57cec5SDimitry Andric ArrayRef<Expr *> private_counters() const { 14950b57cec5SDimitry Andric return const_cast<OMPLoopDirective *>(this)->getPrivateCounters(); 14960b57cec5SDimitry Andric } 14970b57cec5SDimitry Andric inits()14980b57cec5SDimitry Andric ArrayRef<Expr *> inits() { return getInits(); } 14990b57cec5SDimitry Andric inits()15000b57cec5SDimitry Andric ArrayRef<Expr *> inits() const { 15010b57cec5SDimitry Andric return const_cast<OMPLoopDirective *>(this)->getInits(); 15020b57cec5SDimitry Andric } 15030b57cec5SDimitry Andric updates()15040b57cec5SDimitry Andric ArrayRef<Expr *> updates() { return getUpdates(); } 15050b57cec5SDimitry Andric updates()15060b57cec5SDimitry Andric ArrayRef<Expr *> updates() const { 15070b57cec5SDimitry Andric return const_cast<OMPLoopDirective *>(this)->getUpdates(); 15080b57cec5SDimitry Andric } 15090b57cec5SDimitry Andric finals()15100b57cec5SDimitry Andric ArrayRef<Expr *> finals() { return getFinals(); } 15110b57cec5SDimitry Andric finals()15120b57cec5SDimitry Andric ArrayRef<Expr *> finals() const { 15130b57cec5SDimitry Andric return const_cast<OMPLoopDirective *>(this)->getFinals(); 15140b57cec5SDimitry Andric } 15150b57cec5SDimitry Andric dependent_counters()1516a7dea167SDimitry Andric ArrayRef<Expr *> dependent_counters() { return getDependentCounters(); } 1517a7dea167SDimitry Andric dependent_counters()1518a7dea167SDimitry Andric ArrayRef<Expr *> dependent_counters() const { 1519a7dea167SDimitry Andric return const_cast<OMPLoopDirective *>(this)->getDependentCounters(); 1520a7dea167SDimitry Andric } 1521a7dea167SDimitry Andric dependent_inits()1522a7dea167SDimitry Andric ArrayRef<Expr *> dependent_inits() { return getDependentInits(); } 1523a7dea167SDimitry Andric dependent_inits()1524a7dea167SDimitry Andric ArrayRef<Expr *> dependent_inits() const { 1525a7dea167SDimitry Andric return const_cast<OMPLoopDirective *>(this)->getDependentInits(); 1526a7dea167SDimitry Andric } 1527a7dea167SDimitry Andric finals_conditions()1528a7dea167SDimitry Andric ArrayRef<Expr *> finals_conditions() { return getFinalsConditions(); } 1529a7dea167SDimitry Andric finals_conditions()1530a7dea167SDimitry Andric ArrayRef<Expr *> finals_conditions() const { 1531a7dea167SDimitry Andric return const_cast<OMPLoopDirective *>(this)->getFinalsConditions(); 1532a7dea167SDimitry Andric } 1533a7dea167SDimitry Andric classof(const Stmt * T)15340b57cec5SDimitry Andric static bool classof(const Stmt *T) { 15350b57cec5SDimitry Andric return T->getStmtClass() == OMPSimdDirectiveClass || 15360b57cec5SDimitry Andric T->getStmtClass() == OMPForDirectiveClass || 15370b57cec5SDimitry Andric T->getStmtClass() == OMPForSimdDirectiveClass || 15380b57cec5SDimitry Andric T->getStmtClass() == OMPParallelForDirectiveClass || 15390b57cec5SDimitry Andric T->getStmtClass() == OMPParallelForSimdDirectiveClass || 15400b57cec5SDimitry Andric T->getStmtClass() == OMPTaskLoopDirectiveClass || 15410b57cec5SDimitry Andric T->getStmtClass() == OMPTaskLoopSimdDirectiveClass || 154281ad6265SDimitry Andric T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass || 154381ad6265SDimitry Andric T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass || 1544a7dea167SDimitry Andric T->getStmtClass() == OMPMasterTaskLoopDirectiveClass || 1545a7dea167SDimitry Andric T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass || 1546349cc55cSDimitry Andric T->getStmtClass() == OMPGenericLoopDirectiveClass || 154781ad6265SDimitry Andric T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass || 154881ad6265SDimitry Andric T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass || 154981ad6265SDimitry Andric T->getStmtClass() == OMPParallelGenericLoopDirectiveClass || 155081ad6265SDimitry Andric T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass || 155181ad6265SDimitry Andric T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass || 155281ad6265SDimitry Andric T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass || 1553a7dea167SDimitry Andric T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass || 1554480093f4SDimitry Andric T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass || 15550b57cec5SDimitry Andric T->getStmtClass() == OMPDistributeDirectiveClass || 15560b57cec5SDimitry Andric T->getStmtClass() == OMPTargetParallelForDirectiveClass || 15570b57cec5SDimitry Andric T->getStmtClass() == OMPDistributeParallelForDirectiveClass || 15580b57cec5SDimitry Andric T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass || 15590b57cec5SDimitry Andric T->getStmtClass() == OMPDistributeSimdDirectiveClass || 15600b57cec5SDimitry Andric T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass || 15610b57cec5SDimitry Andric T->getStmtClass() == OMPTargetSimdDirectiveClass || 15620b57cec5SDimitry Andric T->getStmtClass() == OMPTeamsDistributeDirectiveClass || 15630b57cec5SDimitry Andric T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass || 15640b57cec5SDimitry Andric T->getStmtClass() == 15650b57cec5SDimitry Andric OMPTeamsDistributeParallelForSimdDirectiveClass || 15660b57cec5SDimitry Andric T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass || 15670b57cec5SDimitry Andric T->getStmtClass() == 15680b57cec5SDimitry Andric OMPTargetTeamsDistributeParallelForDirectiveClass || 15690b57cec5SDimitry Andric T->getStmtClass() == 15700b57cec5SDimitry Andric OMPTargetTeamsDistributeParallelForSimdDirectiveClass || 15710b57cec5SDimitry Andric T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass || 15720b57cec5SDimitry Andric T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass; 15730b57cec5SDimitry Andric } 15740b57cec5SDimitry Andric }; 15750b57cec5SDimitry Andric 15760b57cec5SDimitry Andric /// This represents '#pragma omp simd' directive. 15770b57cec5SDimitry Andric /// 15780b57cec5SDimitry Andric /// \code 15790b57cec5SDimitry Andric /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d) 15800b57cec5SDimitry Andric /// \endcode 15810b57cec5SDimitry Andric /// In this example directive '#pragma omp simd' has clauses 'private' 15820b57cec5SDimitry Andric /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and 15830b57cec5SDimitry Andric /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. 15840b57cec5SDimitry Andric /// 15850b57cec5SDimitry Andric class OMPSimdDirective : public OMPLoopDirective { 15860b57cec5SDimitry Andric friend class ASTStmtReader; 1587e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 15880b57cec5SDimitry Andric /// Build directive with the given start and end location. 15890b57cec5SDimitry Andric /// 15900b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 15910b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 15920b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 15930b57cec5SDimitry Andric /// OMPSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)15940b57cec5SDimitry Andric OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1595e8d8bef9SDimitry Andric unsigned CollapsedNum) 1596e8d8bef9SDimitry Andric : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, StartLoc, 1597e8d8bef9SDimitry Andric EndLoc, CollapsedNum) {} 15980b57cec5SDimitry Andric 15990b57cec5SDimitry Andric /// Build an empty directive. 16000b57cec5SDimitry Andric /// 16010b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 16020b57cec5SDimitry Andric /// OMPSimdDirective(unsigned CollapsedNum)1603e8d8bef9SDimitry Andric explicit OMPSimdDirective(unsigned CollapsedNum) 1604e8d8bef9SDimitry Andric : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, 1605e8d8bef9SDimitry Andric SourceLocation(), SourceLocation(), CollapsedNum) {} 16060b57cec5SDimitry Andric 16070b57cec5SDimitry Andric public: 16080b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 16090b57cec5SDimitry Andric /// 16100b57cec5SDimitry Andric /// \param C AST context. 16110b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 16120b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 16130b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 16140b57cec5SDimitry Andric /// \param Clauses List of clauses. 16150b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 16160b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 16170b57cec5SDimitry Andric /// 16180b57cec5SDimitry Andric static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc, 16190b57cec5SDimitry Andric SourceLocation EndLoc, unsigned CollapsedNum, 16200b57cec5SDimitry Andric ArrayRef<OMPClause *> Clauses, 16210b57cec5SDimitry Andric Stmt *AssociatedStmt, 16225f757f3fSDimitry Andric const HelperExprs &Exprs, 16235f757f3fSDimitry Andric OpenMPDirectiveKind ParamPrevMappedDirective); 16240b57cec5SDimitry Andric 16250b57cec5SDimitry Andric /// Creates an empty directive with the place 16260b57cec5SDimitry Andric /// for \a NumClauses clauses. 16270b57cec5SDimitry Andric /// 16280b57cec5SDimitry Andric /// \param C AST context. 16290b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 16300b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 16310b57cec5SDimitry Andric /// 16320b57cec5SDimitry Andric static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 16330b57cec5SDimitry Andric unsigned CollapsedNum, EmptyShell); 16340b57cec5SDimitry Andric classof(const Stmt * T)16350b57cec5SDimitry Andric static bool classof(const Stmt *T) { 16360b57cec5SDimitry Andric return T->getStmtClass() == OMPSimdDirectiveClass; 16370b57cec5SDimitry Andric } 16380b57cec5SDimitry Andric }; 16390b57cec5SDimitry Andric 16400b57cec5SDimitry Andric /// This represents '#pragma omp for' directive. 16410b57cec5SDimitry Andric /// 16420b57cec5SDimitry Andric /// \code 16430b57cec5SDimitry Andric /// #pragma omp for private(a,b) reduction(+:c,d) 16440b57cec5SDimitry Andric /// \endcode 16450b57cec5SDimitry Andric /// In this example directive '#pragma omp for' has clauses 'private' with the 16460b57cec5SDimitry Andric /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c' 16470b57cec5SDimitry Andric /// and 'd'. 16480b57cec5SDimitry Andric /// 16490b57cec5SDimitry Andric class OMPForDirective : public OMPLoopDirective { 16500b57cec5SDimitry Andric friend class ASTStmtReader; 1651e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 16520b57cec5SDimitry Andric /// true if current directive has inner cancel directive. 1653e8d8bef9SDimitry Andric bool HasCancel = false; 16540b57cec5SDimitry Andric 16550b57cec5SDimitry Andric /// Build directive with the given start and end location. 16560b57cec5SDimitry Andric /// 16570b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 16580b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 16590b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 16600b57cec5SDimitry Andric /// OMPForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)16610b57cec5SDimitry Andric OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1662e8d8bef9SDimitry Andric unsigned CollapsedNum) 1663e8d8bef9SDimitry Andric : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, StartLoc, 1664e8d8bef9SDimitry Andric EndLoc, CollapsedNum) {} 16650b57cec5SDimitry Andric 16660b57cec5SDimitry Andric /// Build an empty directive. 16670b57cec5SDimitry Andric /// 16680b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 16690b57cec5SDimitry Andric /// OMPForDirective(unsigned CollapsedNum)1670e8d8bef9SDimitry Andric explicit OMPForDirective(unsigned CollapsedNum) 1671e8d8bef9SDimitry Andric : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, 1672e8d8bef9SDimitry Andric SourceLocation(), SourceLocation(), CollapsedNum) {} 16730b57cec5SDimitry Andric 16745ffd83dbSDimitry Andric /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)1675e8d8bef9SDimitry Andric void setTaskReductionRefExpr(Expr *E) { 1676fe6060f1SDimitry Andric Data->getChildren()[numLoopChildren(getLoopsNumber(), 1677e8d8bef9SDimitry Andric llvm::omp::OMPD_for)] = E; 1678e8d8bef9SDimitry Andric } 16795ffd83dbSDimitry Andric 16800b57cec5SDimitry Andric /// Set cancel state. setHasCancel(bool Has)16810b57cec5SDimitry Andric void setHasCancel(bool Has) { HasCancel = Has; } 16820b57cec5SDimitry Andric 16830b57cec5SDimitry Andric public: 16840b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 16850b57cec5SDimitry Andric /// 16860b57cec5SDimitry Andric /// \param C AST context. 16870b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 16880b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 16890b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 16900b57cec5SDimitry Andric /// \param Clauses List of clauses. 16910b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 16920b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 16935ffd83dbSDimitry Andric /// \param TaskRedRef Task reduction special reference expression to handle 16945ffd83dbSDimitry Andric /// taskgroup descriptor. 16950b57cec5SDimitry Andric /// \param HasCancel true if current directive has inner cancel directive. 16960b57cec5SDimitry Andric /// 16970b57cec5SDimitry Andric static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc, 16980b57cec5SDimitry Andric SourceLocation EndLoc, unsigned CollapsedNum, 16990b57cec5SDimitry Andric ArrayRef<OMPClause *> Clauses, 17000b57cec5SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs, 17015f757f3fSDimitry Andric Expr *TaskRedRef, bool HasCancel, 17025f757f3fSDimitry Andric OpenMPDirectiveKind ParamPrevMappedDirective); 17030b57cec5SDimitry Andric 17040b57cec5SDimitry Andric /// Creates an empty directive with the place 17050b57cec5SDimitry Andric /// for \a NumClauses clauses. 17060b57cec5SDimitry Andric /// 17070b57cec5SDimitry Andric /// \param C AST context. 17080b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 17090b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 17100b57cec5SDimitry Andric /// 17110b57cec5SDimitry Andric static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 17120b57cec5SDimitry Andric unsigned CollapsedNum, EmptyShell); 17130b57cec5SDimitry Andric 17145ffd83dbSDimitry Andric /// Returns special task reduction reference expression. getTaskReductionRefExpr()1715e8d8bef9SDimitry Andric Expr *getTaskReductionRefExpr() { 1716e8d8bef9SDimitry Andric return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 1717fe6060f1SDimitry Andric getLoopsNumber(), llvm::omp::OMPD_for)]); 1718e8d8bef9SDimitry Andric } getTaskReductionRefExpr()1719e8d8bef9SDimitry Andric const Expr *getTaskReductionRefExpr() const { 1720e8d8bef9SDimitry Andric return const_cast<OMPForDirective *>(this)->getTaskReductionRefExpr(); 1721e8d8bef9SDimitry Andric } 17225ffd83dbSDimitry Andric 17230b57cec5SDimitry Andric /// Return true if current directive has inner cancel directive. hasCancel()17240b57cec5SDimitry Andric bool hasCancel() const { return HasCancel; } 17250b57cec5SDimitry Andric classof(const Stmt * T)17260b57cec5SDimitry Andric static bool classof(const Stmt *T) { 17270b57cec5SDimitry Andric return T->getStmtClass() == OMPForDirectiveClass; 17280b57cec5SDimitry Andric } 17290b57cec5SDimitry Andric }; 17300b57cec5SDimitry Andric 17310b57cec5SDimitry Andric /// This represents '#pragma omp for simd' directive. 17320b57cec5SDimitry Andric /// 17330b57cec5SDimitry Andric /// \code 17340b57cec5SDimitry Andric /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d) 17350b57cec5SDimitry Andric /// \endcode 17360b57cec5SDimitry Andric /// In this example directive '#pragma omp for simd' has clauses 'private' 17370b57cec5SDimitry Andric /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and 17380b57cec5SDimitry Andric /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. 17390b57cec5SDimitry Andric /// 17400b57cec5SDimitry Andric class OMPForSimdDirective : public OMPLoopDirective { 17410b57cec5SDimitry Andric friend class ASTStmtReader; 1742e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 17430b57cec5SDimitry Andric /// Build directive with the given start and end location. 17440b57cec5SDimitry Andric /// 17450b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 17460b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 17470b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 17480b57cec5SDimitry Andric /// OMPForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)17490b57cec5SDimitry Andric OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1750e8d8bef9SDimitry Andric unsigned CollapsedNum) 1751e8d8bef9SDimitry Andric : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd, 1752e8d8bef9SDimitry Andric StartLoc, EndLoc, CollapsedNum) {} 17530b57cec5SDimitry Andric 17540b57cec5SDimitry Andric /// Build an empty directive. 17550b57cec5SDimitry Andric /// 17560b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 17570b57cec5SDimitry Andric /// OMPForSimdDirective(unsigned CollapsedNum)1758e8d8bef9SDimitry Andric explicit OMPForSimdDirective(unsigned CollapsedNum) 1759e8d8bef9SDimitry Andric : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd, 1760e8d8bef9SDimitry Andric SourceLocation(), SourceLocation(), CollapsedNum) {} 17610b57cec5SDimitry Andric 17620b57cec5SDimitry Andric public: 17630b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 17640b57cec5SDimitry Andric /// 17650b57cec5SDimitry Andric /// \param C AST context. 17660b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 17670b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 17680b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 17690b57cec5SDimitry Andric /// \param Clauses List of clauses. 17700b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 17710b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 17720b57cec5SDimitry Andric /// 17730b57cec5SDimitry Andric static OMPForSimdDirective * 17740b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 17750b57cec5SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 17760b57cec5SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 17770b57cec5SDimitry Andric 17780b57cec5SDimitry Andric /// Creates an empty directive with the place 17790b57cec5SDimitry Andric /// for \a NumClauses clauses. 17800b57cec5SDimitry Andric /// 17810b57cec5SDimitry Andric /// \param C AST context. 17820b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 17830b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 17840b57cec5SDimitry Andric /// 17850b57cec5SDimitry Andric static OMPForSimdDirective *CreateEmpty(const ASTContext &C, 17860b57cec5SDimitry Andric unsigned NumClauses, 17870b57cec5SDimitry Andric unsigned CollapsedNum, EmptyShell); 17880b57cec5SDimitry Andric classof(const Stmt * T)17890b57cec5SDimitry Andric static bool classof(const Stmt *T) { 17900b57cec5SDimitry Andric return T->getStmtClass() == OMPForSimdDirectiveClass; 17910b57cec5SDimitry Andric } 17920b57cec5SDimitry Andric }; 17930b57cec5SDimitry Andric 17940b57cec5SDimitry Andric /// This represents '#pragma omp sections' directive. 17950b57cec5SDimitry Andric /// 17960b57cec5SDimitry Andric /// \code 17970b57cec5SDimitry Andric /// #pragma omp sections private(a,b) reduction(+:c,d) 17980b57cec5SDimitry Andric /// \endcode 17990b57cec5SDimitry Andric /// In this example directive '#pragma omp sections' has clauses 'private' with 18000b57cec5SDimitry Andric /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables 18010b57cec5SDimitry Andric /// 'c' and 'd'. 18020b57cec5SDimitry Andric /// 18030b57cec5SDimitry Andric class OMPSectionsDirective : public OMPExecutableDirective { 18040b57cec5SDimitry Andric friend class ASTStmtReader; 1805e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 18060b57cec5SDimitry Andric 18070b57cec5SDimitry Andric /// true if current directive has inner cancel directive. 1808e8d8bef9SDimitry Andric bool HasCancel = false; 18090b57cec5SDimitry Andric 18100b57cec5SDimitry Andric /// Build directive with the given start and end location. 18110b57cec5SDimitry Andric /// 18120b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 18130b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 18140b57cec5SDimitry Andric /// OMPSectionsDirective(SourceLocation StartLoc,SourceLocation EndLoc)1815e8d8bef9SDimitry Andric OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1816e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPSectionsDirectiveClass, 1817e8d8bef9SDimitry Andric llvm::omp::OMPD_sections, StartLoc, EndLoc) {} 18180b57cec5SDimitry Andric 18190b57cec5SDimitry Andric /// Build an empty directive. 18200b57cec5SDimitry Andric /// OMPSectionsDirective()1821e8d8bef9SDimitry Andric explicit OMPSectionsDirective() 1822e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPSectionsDirectiveClass, 1823480093f4SDimitry Andric llvm::omp::OMPD_sections, SourceLocation(), 1824e8d8bef9SDimitry Andric SourceLocation()) {} 18250b57cec5SDimitry Andric 18265ffd83dbSDimitry Andric /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)1827e8d8bef9SDimitry Andric void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 18285ffd83dbSDimitry Andric 18290b57cec5SDimitry Andric /// Set cancel state. setHasCancel(bool Has)18300b57cec5SDimitry Andric void setHasCancel(bool Has) { HasCancel = Has; } 18310b57cec5SDimitry Andric 18320b57cec5SDimitry Andric public: 18330b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 18340b57cec5SDimitry Andric /// 18350b57cec5SDimitry Andric /// \param C AST context. 18360b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 18370b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 18380b57cec5SDimitry Andric /// \param Clauses List of clauses. 18390b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 18405ffd83dbSDimitry Andric /// \param TaskRedRef Task reduction special reference expression to handle 18415ffd83dbSDimitry Andric /// taskgroup descriptor. 18420b57cec5SDimitry Andric /// \param HasCancel true if current directive has inner directive. 18430b57cec5SDimitry Andric /// 18440b57cec5SDimitry Andric static OMPSectionsDirective * 18450b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 18465ffd83dbSDimitry Andric ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 18475ffd83dbSDimitry Andric bool HasCancel); 18480b57cec5SDimitry Andric 18490b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses 18500b57cec5SDimitry Andric /// clauses. 18510b57cec5SDimitry Andric /// 18520b57cec5SDimitry Andric /// \param C AST context. 18530b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 18540b57cec5SDimitry Andric /// 18550b57cec5SDimitry Andric static OMPSectionsDirective *CreateEmpty(const ASTContext &C, 18560b57cec5SDimitry Andric unsigned NumClauses, EmptyShell); 18570b57cec5SDimitry Andric 18585ffd83dbSDimitry Andric /// Returns special task reduction reference expression. getTaskReductionRefExpr()1859e8d8bef9SDimitry Andric Expr *getTaskReductionRefExpr() { 1860e8d8bef9SDimitry Andric return cast_or_null<Expr>(Data->getChildren()[0]); 1861e8d8bef9SDimitry Andric } getTaskReductionRefExpr()1862e8d8bef9SDimitry Andric const Expr *getTaskReductionRefExpr() const { 1863e8d8bef9SDimitry Andric return const_cast<OMPSectionsDirective *>(this)->getTaskReductionRefExpr(); 1864e8d8bef9SDimitry Andric } 18655ffd83dbSDimitry Andric 18660b57cec5SDimitry Andric /// Return true if current directive has inner cancel directive. hasCancel()18670b57cec5SDimitry Andric bool hasCancel() const { return HasCancel; } 18680b57cec5SDimitry Andric classof(const Stmt * T)18690b57cec5SDimitry Andric static bool classof(const Stmt *T) { 18700b57cec5SDimitry Andric return T->getStmtClass() == OMPSectionsDirectiveClass; 18710b57cec5SDimitry Andric } 18720b57cec5SDimitry Andric }; 18730b57cec5SDimitry Andric 18740b57cec5SDimitry Andric /// This represents '#pragma omp section' directive. 18750b57cec5SDimitry Andric /// 18760b57cec5SDimitry Andric /// \code 18770b57cec5SDimitry Andric /// #pragma omp section 18780b57cec5SDimitry Andric /// \endcode 18790b57cec5SDimitry Andric /// 18800b57cec5SDimitry Andric class OMPSectionDirective : public OMPExecutableDirective { 18810b57cec5SDimitry Andric friend class ASTStmtReader; 1882e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 18830b57cec5SDimitry Andric 18840b57cec5SDimitry Andric /// true if current directive has inner cancel directive. 1885e8d8bef9SDimitry Andric bool HasCancel = false; 18860b57cec5SDimitry Andric 18870b57cec5SDimitry Andric /// Build directive with the given start and end location. 18880b57cec5SDimitry Andric /// 18890b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 18900b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 18910b57cec5SDimitry Andric /// OMPSectionDirective(SourceLocation StartLoc,SourceLocation EndLoc)18920b57cec5SDimitry Andric OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1893e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPSectionDirectiveClass, 1894e8d8bef9SDimitry Andric llvm::omp::OMPD_section, StartLoc, EndLoc) {} 18950b57cec5SDimitry Andric 18960b57cec5SDimitry Andric /// Build an empty directive. 18970b57cec5SDimitry Andric /// OMPSectionDirective()18980b57cec5SDimitry Andric explicit OMPSectionDirective() 1899e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPSectionDirectiveClass, 1900480093f4SDimitry Andric llvm::omp::OMPD_section, SourceLocation(), 1901e8d8bef9SDimitry Andric SourceLocation()) {} 19020b57cec5SDimitry Andric 19030b57cec5SDimitry Andric public: 19040b57cec5SDimitry Andric /// Creates directive. 19050b57cec5SDimitry Andric /// 19060b57cec5SDimitry Andric /// \param C AST context. 19070b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 19080b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 19090b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 19100b57cec5SDimitry Andric /// \param HasCancel true if current directive has inner directive. 19110b57cec5SDimitry Andric /// 19120b57cec5SDimitry Andric static OMPSectionDirective *Create(const ASTContext &C, 19130b57cec5SDimitry Andric SourceLocation StartLoc, 19140b57cec5SDimitry Andric SourceLocation EndLoc, 19150b57cec5SDimitry Andric Stmt *AssociatedStmt, bool HasCancel); 19160b57cec5SDimitry Andric 19170b57cec5SDimitry Andric /// Creates an empty directive. 19180b57cec5SDimitry Andric /// 19190b57cec5SDimitry Andric /// \param C AST context. 19200b57cec5SDimitry Andric /// 19210b57cec5SDimitry Andric static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell); 19220b57cec5SDimitry Andric 19230b57cec5SDimitry Andric /// Set cancel state. setHasCancel(bool Has)19240b57cec5SDimitry Andric void setHasCancel(bool Has) { HasCancel = Has; } 19250b57cec5SDimitry Andric 19260b57cec5SDimitry Andric /// Return true if current directive has inner cancel directive. hasCancel()19270b57cec5SDimitry Andric bool hasCancel() const { return HasCancel; } 19280b57cec5SDimitry Andric classof(const Stmt * T)19290b57cec5SDimitry Andric static bool classof(const Stmt *T) { 19300b57cec5SDimitry Andric return T->getStmtClass() == OMPSectionDirectiveClass; 19310b57cec5SDimitry Andric } 19320b57cec5SDimitry Andric }; 19330b57cec5SDimitry Andric 19345f757f3fSDimitry Andric /// This represents '#pragma omp scope' directive. 19355f757f3fSDimitry Andric /// \code 19365f757f3fSDimitry Andric /// #pragma omp scope private(a,b) nowait 19375f757f3fSDimitry Andric /// \endcode 19385f757f3fSDimitry Andric /// In this example directive '#pragma omp scope' has clauses 'private' with 19395f757f3fSDimitry Andric /// the variables 'a' and 'b' and nowait. 19405f757f3fSDimitry Andric /// 19415f757f3fSDimitry Andric class OMPScopeDirective final : public OMPExecutableDirective { 19425f757f3fSDimitry Andric friend class ASTStmtReader; 19435f757f3fSDimitry Andric friend class OMPExecutableDirective; 19445f757f3fSDimitry Andric 19455f757f3fSDimitry Andric /// Build directive with the given start and end location. 19465f757f3fSDimitry Andric /// 19475f757f3fSDimitry Andric /// \param StartLoc Starting location of the directive kind. 19485f757f3fSDimitry Andric /// \param EndLoc Ending location of the directive. 19495f757f3fSDimitry Andric /// OMPScopeDirective(SourceLocation StartLoc,SourceLocation EndLoc)19505f757f3fSDimitry Andric OMPScopeDirective(SourceLocation StartLoc, SourceLocation EndLoc) 19515f757f3fSDimitry Andric : OMPExecutableDirective(OMPScopeDirectiveClass, llvm::omp::OMPD_scope, 19525f757f3fSDimitry Andric StartLoc, EndLoc) {} 19535f757f3fSDimitry Andric 19545f757f3fSDimitry Andric /// Build an empty directive. 19555f757f3fSDimitry Andric /// OMPScopeDirective()19565f757f3fSDimitry Andric explicit OMPScopeDirective() 19575f757f3fSDimitry Andric : OMPExecutableDirective(OMPScopeDirectiveClass, llvm::omp::OMPD_scope, 19585f757f3fSDimitry Andric SourceLocation(), SourceLocation()) {} 19595f757f3fSDimitry Andric 19605f757f3fSDimitry Andric public: 19615f757f3fSDimitry Andric /// Creates directive. 19625f757f3fSDimitry Andric /// 19635f757f3fSDimitry Andric /// \param C AST context. 19645f757f3fSDimitry Andric /// \param StartLoc Starting location of the directive kind. 19655f757f3fSDimitry Andric /// \param EndLoc Ending Location of the directive. 19665f757f3fSDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 19675f757f3fSDimitry Andric /// 19685f757f3fSDimitry Andric static OMPScopeDirective *Create(const ASTContext &C, SourceLocation StartLoc, 19695f757f3fSDimitry Andric SourceLocation EndLoc, 19705f757f3fSDimitry Andric ArrayRef<OMPClause *> Clauses, 19715f757f3fSDimitry Andric Stmt *AssociatedStmt); 19725f757f3fSDimitry Andric 19735f757f3fSDimitry Andric /// Creates an empty directive. 19745f757f3fSDimitry Andric /// 19755f757f3fSDimitry Andric /// \param C AST context. 19765f757f3fSDimitry Andric /// 19775f757f3fSDimitry Andric static OMPScopeDirective *CreateEmpty(const ASTContext &C, 19785f757f3fSDimitry Andric unsigned NumClauses, EmptyShell); 19795f757f3fSDimitry Andric classof(const Stmt * T)19805f757f3fSDimitry Andric static bool classof(const Stmt *T) { 19815f757f3fSDimitry Andric return T->getStmtClass() == OMPScopeDirectiveClass; 19825f757f3fSDimitry Andric } 19835f757f3fSDimitry Andric }; 19845f757f3fSDimitry Andric 19850b57cec5SDimitry Andric /// This represents '#pragma omp single' directive. 19860b57cec5SDimitry Andric /// 19870b57cec5SDimitry Andric /// \code 19880b57cec5SDimitry Andric /// #pragma omp single private(a,b) copyprivate(c,d) 19890b57cec5SDimitry Andric /// \endcode 19900b57cec5SDimitry Andric /// In this example directive '#pragma omp single' has clauses 'private' with 19910b57cec5SDimitry Andric /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'. 19920b57cec5SDimitry Andric /// 19930b57cec5SDimitry Andric class OMPSingleDirective : public OMPExecutableDirective { 19940b57cec5SDimitry Andric friend class ASTStmtReader; 1995e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 19960b57cec5SDimitry Andric /// Build directive with the given start and end location. 19970b57cec5SDimitry Andric /// 19980b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 19990b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 20000b57cec5SDimitry Andric /// OMPSingleDirective(SourceLocation StartLoc,SourceLocation EndLoc)2001e8d8bef9SDimitry Andric OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2002e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single, 2003e8d8bef9SDimitry Andric StartLoc, EndLoc) {} 20040b57cec5SDimitry Andric 20050b57cec5SDimitry Andric /// Build an empty directive. 20060b57cec5SDimitry Andric /// OMPSingleDirective()2007e8d8bef9SDimitry Andric explicit OMPSingleDirective() 2008e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single, 2009e8d8bef9SDimitry Andric SourceLocation(), SourceLocation()) {} 20100b57cec5SDimitry Andric 20110b57cec5SDimitry Andric public: 20120b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 20130b57cec5SDimitry Andric /// 20140b57cec5SDimitry Andric /// \param C AST context. 20150b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 20160b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 20170b57cec5SDimitry Andric /// \param Clauses List of clauses. 20180b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 20190b57cec5SDimitry Andric /// 20200b57cec5SDimitry Andric static OMPSingleDirective * 20210b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 20220b57cec5SDimitry Andric ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 20230b57cec5SDimitry Andric 20240b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses 20250b57cec5SDimitry Andric /// clauses. 20260b57cec5SDimitry Andric /// 20270b57cec5SDimitry Andric /// \param C AST context. 20280b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 20290b57cec5SDimitry Andric /// 20300b57cec5SDimitry Andric static OMPSingleDirective *CreateEmpty(const ASTContext &C, 20310b57cec5SDimitry Andric unsigned NumClauses, EmptyShell); 20320b57cec5SDimitry Andric classof(const Stmt * T)20330b57cec5SDimitry Andric static bool classof(const Stmt *T) { 20340b57cec5SDimitry Andric return T->getStmtClass() == OMPSingleDirectiveClass; 20350b57cec5SDimitry Andric } 20360b57cec5SDimitry Andric }; 20370b57cec5SDimitry Andric 20380b57cec5SDimitry Andric /// This represents '#pragma omp master' directive. 20390b57cec5SDimitry Andric /// 20400b57cec5SDimitry Andric /// \code 20410b57cec5SDimitry Andric /// #pragma omp master 20420b57cec5SDimitry Andric /// \endcode 20430b57cec5SDimitry Andric /// 20440b57cec5SDimitry Andric class OMPMasterDirective : public OMPExecutableDirective { 20450b57cec5SDimitry Andric friend class ASTStmtReader; 2046e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 20470b57cec5SDimitry Andric /// Build directive with the given start and end location. 20480b57cec5SDimitry Andric /// 20490b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 20500b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 20510b57cec5SDimitry Andric /// OMPMasterDirective(SourceLocation StartLoc,SourceLocation EndLoc)20520b57cec5SDimitry Andric OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2053e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master, 2054e8d8bef9SDimitry Andric StartLoc, EndLoc) {} 20550b57cec5SDimitry Andric 20560b57cec5SDimitry Andric /// Build an empty directive. 20570b57cec5SDimitry Andric /// OMPMasterDirective()20580b57cec5SDimitry Andric explicit OMPMasterDirective() 2059e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master, 2060e8d8bef9SDimitry Andric SourceLocation(), SourceLocation()) {} 20610b57cec5SDimitry Andric 20620b57cec5SDimitry Andric public: 20630b57cec5SDimitry Andric /// Creates directive. 20640b57cec5SDimitry Andric /// 20650b57cec5SDimitry Andric /// \param C AST context. 20660b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 20670b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 20680b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 20690b57cec5SDimitry Andric /// 20700b57cec5SDimitry Andric static OMPMasterDirective *Create(const ASTContext &C, 20710b57cec5SDimitry Andric SourceLocation StartLoc, 20720b57cec5SDimitry Andric SourceLocation EndLoc, 20730b57cec5SDimitry Andric Stmt *AssociatedStmt); 20740b57cec5SDimitry Andric 20750b57cec5SDimitry Andric /// Creates an empty directive. 20760b57cec5SDimitry Andric /// 20770b57cec5SDimitry Andric /// \param C AST context. 20780b57cec5SDimitry Andric /// 20790b57cec5SDimitry Andric static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell); 20800b57cec5SDimitry Andric classof(const Stmt * T)20810b57cec5SDimitry Andric static bool classof(const Stmt *T) { 20820b57cec5SDimitry Andric return T->getStmtClass() == OMPMasterDirectiveClass; 20830b57cec5SDimitry Andric } 20840b57cec5SDimitry Andric }; 20850b57cec5SDimitry Andric 20860b57cec5SDimitry Andric /// This represents '#pragma omp critical' directive. 20870b57cec5SDimitry Andric /// 20880b57cec5SDimitry Andric /// \code 20890b57cec5SDimitry Andric /// #pragma omp critical 20900b57cec5SDimitry Andric /// \endcode 20910b57cec5SDimitry Andric /// 20920b57cec5SDimitry Andric class OMPCriticalDirective : public OMPExecutableDirective { 20930b57cec5SDimitry Andric friend class ASTStmtReader; 2094e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 20950b57cec5SDimitry Andric /// Name of the directive. 20960b57cec5SDimitry Andric DeclarationNameInfo DirName; 20970b57cec5SDimitry Andric /// Build directive with the given start and end location. 20980b57cec5SDimitry Andric /// 20990b57cec5SDimitry Andric /// \param Name Name of the directive. 21000b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 21010b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 21020b57cec5SDimitry Andric /// OMPCriticalDirective(const DeclarationNameInfo & Name,SourceLocation StartLoc,SourceLocation EndLoc)21030b57cec5SDimitry Andric OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc, 2104e8d8bef9SDimitry Andric SourceLocation EndLoc) 2105e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPCriticalDirectiveClass, 2106e8d8bef9SDimitry Andric llvm::omp::OMPD_critical, StartLoc, EndLoc), 21070b57cec5SDimitry Andric DirName(Name) {} 21080b57cec5SDimitry Andric 21090b57cec5SDimitry Andric /// Build an empty directive. 21100b57cec5SDimitry Andric /// OMPCriticalDirective()2111e8d8bef9SDimitry Andric explicit OMPCriticalDirective() 2112e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPCriticalDirectiveClass, 2113480093f4SDimitry Andric llvm::omp::OMPD_critical, SourceLocation(), 2114e8d8bef9SDimitry Andric SourceLocation()) {} 21150b57cec5SDimitry Andric 21160b57cec5SDimitry Andric /// Set name of the directive. 21170b57cec5SDimitry Andric /// 21180b57cec5SDimitry Andric /// \param Name Name of the directive. 21190b57cec5SDimitry Andric /// setDirectiveName(const DeclarationNameInfo & Name)21200b57cec5SDimitry Andric void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; } 21210b57cec5SDimitry Andric 21220b57cec5SDimitry Andric public: 21230b57cec5SDimitry Andric /// Creates directive. 21240b57cec5SDimitry Andric /// 21250b57cec5SDimitry Andric /// \param C AST context. 21260b57cec5SDimitry Andric /// \param Name Name of the directive. 21270b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 21280b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 21290b57cec5SDimitry Andric /// \param Clauses List of clauses. 21300b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 21310b57cec5SDimitry Andric /// 21320b57cec5SDimitry Andric static OMPCriticalDirective * 21330b57cec5SDimitry Andric Create(const ASTContext &C, const DeclarationNameInfo &Name, 21340b57cec5SDimitry Andric SourceLocation StartLoc, SourceLocation EndLoc, 21350b57cec5SDimitry Andric ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 21360b57cec5SDimitry Andric 21370b57cec5SDimitry Andric /// Creates an empty directive. 21380b57cec5SDimitry Andric /// 21390b57cec5SDimitry Andric /// \param C AST context. 21400b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 21410b57cec5SDimitry Andric /// 21420b57cec5SDimitry Andric static OMPCriticalDirective *CreateEmpty(const ASTContext &C, 21430b57cec5SDimitry Andric unsigned NumClauses, EmptyShell); 21440b57cec5SDimitry Andric 21450b57cec5SDimitry Andric /// Return name of the directive. 21460b57cec5SDimitry Andric /// getDirectiveName()21470b57cec5SDimitry Andric DeclarationNameInfo getDirectiveName() const { return DirName; } 21480b57cec5SDimitry Andric classof(const Stmt * T)21490b57cec5SDimitry Andric static bool classof(const Stmt *T) { 21500b57cec5SDimitry Andric return T->getStmtClass() == OMPCriticalDirectiveClass; 21510b57cec5SDimitry Andric } 21520b57cec5SDimitry Andric }; 21530b57cec5SDimitry Andric 21540b57cec5SDimitry Andric /// This represents '#pragma omp parallel for' directive. 21550b57cec5SDimitry Andric /// 21560b57cec5SDimitry Andric /// \code 21570b57cec5SDimitry Andric /// #pragma omp parallel for private(a,b) reduction(+:c,d) 21580b57cec5SDimitry Andric /// \endcode 21590b57cec5SDimitry Andric /// In this example directive '#pragma omp parallel for' has clauses 'private' 21600b57cec5SDimitry Andric /// with the variables 'a' and 'b' and 'reduction' with operator '+' and 21610b57cec5SDimitry Andric /// variables 'c' and 'd'. 21620b57cec5SDimitry Andric /// 21630b57cec5SDimitry Andric class OMPParallelForDirective : public OMPLoopDirective { 21640b57cec5SDimitry Andric friend class ASTStmtReader; 2165e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 21660b57cec5SDimitry Andric 21670b57cec5SDimitry Andric /// true if current region has inner cancel directive. 2168e8d8bef9SDimitry Andric bool HasCancel = false; 21690b57cec5SDimitry Andric 21700b57cec5SDimitry Andric /// Build directive with the given start and end location. 21710b57cec5SDimitry Andric /// 21720b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 21730b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 21740b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 21750b57cec5SDimitry Andric /// OMPParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)21760b57cec5SDimitry Andric OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2177e8d8bef9SDimitry Andric unsigned CollapsedNum) 2178e8d8bef9SDimitry Andric : OMPLoopDirective(OMPParallelForDirectiveClass, 2179480093f4SDimitry Andric llvm::omp::OMPD_parallel_for, StartLoc, EndLoc, 2180e8d8bef9SDimitry Andric CollapsedNum) {} 21810b57cec5SDimitry Andric 21820b57cec5SDimitry Andric /// Build an empty directive. 21830b57cec5SDimitry Andric /// 21840b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 21850b57cec5SDimitry Andric /// OMPParallelForDirective(unsigned CollapsedNum)2186e8d8bef9SDimitry Andric explicit OMPParallelForDirective(unsigned CollapsedNum) 2187e8d8bef9SDimitry Andric : OMPLoopDirective(OMPParallelForDirectiveClass, 2188480093f4SDimitry Andric llvm::omp::OMPD_parallel_for, SourceLocation(), 2189e8d8bef9SDimitry Andric SourceLocation(), CollapsedNum) {} 21900b57cec5SDimitry Andric 21915ffd83dbSDimitry Andric /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)2192e8d8bef9SDimitry Andric void setTaskReductionRefExpr(Expr *E) { 2193fe6060f1SDimitry Andric Data->getChildren()[numLoopChildren(getLoopsNumber(), 2194e8d8bef9SDimitry Andric llvm::omp::OMPD_parallel_for)] = E; 2195e8d8bef9SDimitry Andric } 21965ffd83dbSDimitry Andric 21970b57cec5SDimitry Andric /// Set cancel state. setHasCancel(bool Has)21980b57cec5SDimitry Andric void setHasCancel(bool Has) { HasCancel = Has; } 21990b57cec5SDimitry Andric 22000b57cec5SDimitry Andric public: 22010b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 22020b57cec5SDimitry Andric /// 22030b57cec5SDimitry Andric /// \param C AST context. 22040b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 22050b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 22060b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 22070b57cec5SDimitry Andric /// \param Clauses List of clauses. 22080b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 22090b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 22105ffd83dbSDimitry Andric /// \param TaskRedRef Task reduction special reference expression to handle 22115ffd83dbSDimitry Andric /// taskgroup descriptor. 22120b57cec5SDimitry Andric /// \param HasCancel true if current directive has inner cancel directive. 22130b57cec5SDimitry Andric /// 22140b57cec5SDimitry Andric static OMPParallelForDirective * 22150b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 22160b57cec5SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 22175ffd83dbSDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 22185ffd83dbSDimitry Andric bool HasCancel); 22190b57cec5SDimitry Andric 22200b57cec5SDimitry Andric /// Creates an empty directive with the place 22210b57cec5SDimitry Andric /// for \a NumClauses clauses. 22220b57cec5SDimitry Andric /// 22230b57cec5SDimitry Andric /// \param C AST context. 22240b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 22250b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 22260b57cec5SDimitry Andric /// 22270b57cec5SDimitry Andric static OMPParallelForDirective *CreateEmpty(const ASTContext &C, 22280b57cec5SDimitry Andric unsigned NumClauses, 22290b57cec5SDimitry Andric unsigned CollapsedNum, 22300b57cec5SDimitry Andric EmptyShell); 22310b57cec5SDimitry Andric 22325ffd83dbSDimitry Andric /// Returns special task reduction reference expression. getTaskReductionRefExpr()2233e8d8bef9SDimitry Andric Expr *getTaskReductionRefExpr() { 2234e8d8bef9SDimitry Andric return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 2235fe6060f1SDimitry Andric getLoopsNumber(), llvm::omp::OMPD_parallel_for)]); 2236e8d8bef9SDimitry Andric } getTaskReductionRefExpr()2237e8d8bef9SDimitry Andric const Expr *getTaskReductionRefExpr() const { 2238e8d8bef9SDimitry Andric return const_cast<OMPParallelForDirective *>(this) 2239e8d8bef9SDimitry Andric ->getTaskReductionRefExpr(); 2240e8d8bef9SDimitry Andric } 22415ffd83dbSDimitry Andric 22420b57cec5SDimitry Andric /// Return true if current directive has inner cancel directive. hasCancel()22430b57cec5SDimitry Andric bool hasCancel() const { return HasCancel; } 22440b57cec5SDimitry Andric classof(const Stmt * T)22450b57cec5SDimitry Andric static bool classof(const Stmt *T) { 22460b57cec5SDimitry Andric return T->getStmtClass() == OMPParallelForDirectiveClass; 22470b57cec5SDimitry Andric } 22480b57cec5SDimitry Andric }; 22490b57cec5SDimitry Andric 22500b57cec5SDimitry Andric /// This represents '#pragma omp parallel for simd' directive. 22510b57cec5SDimitry Andric /// 22520b57cec5SDimitry Andric /// \code 22530b57cec5SDimitry Andric /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d) 22540b57cec5SDimitry Andric /// \endcode 22550b57cec5SDimitry Andric /// In this example directive '#pragma omp parallel for simd' has clauses 22560b57cec5SDimitry Andric /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j' 22570b57cec5SDimitry Andric /// and linear step 's', 'reduction' with operator '+' and variables 'c' and 22580b57cec5SDimitry Andric /// 'd'. 22590b57cec5SDimitry Andric /// 22600b57cec5SDimitry Andric class OMPParallelForSimdDirective : public OMPLoopDirective { 22610b57cec5SDimitry Andric friend class ASTStmtReader; 2262e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 22630b57cec5SDimitry Andric /// Build directive with the given start and end location. 22640b57cec5SDimitry Andric /// 22650b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 22660b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 22670b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 22680b57cec5SDimitry Andric /// OMPParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)22690b57cec5SDimitry Andric OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2270e8d8bef9SDimitry Andric unsigned CollapsedNum) 2271e8d8bef9SDimitry Andric : OMPLoopDirective(OMPParallelForSimdDirectiveClass, 2272480093f4SDimitry Andric llvm::omp::OMPD_parallel_for_simd, StartLoc, EndLoc, 2273e8d8bef9SDimitry Andric CollapsedNum) {} 22740b57cec5SDimitry Andric 22750b57cec5SDimitry Andric /// Build an empty directive. 22760b57cec5SDimitry Andric /// 22770b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 22780b57cec5SDimitry Andric /// OMPParallelForSimdDirective(unsigned CollapsedNum)2279e8d8bef9SDimitry Andric explicit OMPParallelForSimdDirective(unsigned CollapsedNum) 2280e8d8bef9SDimitry Andric : OMPLoopDirective(OMPParallelForSimdDirectiveClass, 2281480093f4SDimitry Andric llvm::omp::OMPD_parallel_for_simd, SourceLocation(), 2282e8d8bef9SDimitry Andric SourceLocation(), CollapsedNum) {} 22830b57cec5SDimitry Andric 22840b57cec5SDimitry Andric public: 22850b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 22860b57cec5SDimitry Andric /// 22870b57cec5SDimitry Andric /// \param C AST context. 22880b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 22890b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 22900b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 22910b57cec5SDimitry Andric /// \param Clauses List of clauses. 22920b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 22930b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 22940b57cec5SDimitry Andric /// 22950b57cec5SDimitry Andric static OMPParallelForSimdDirective * 22960b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 22970b57cec5SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 22980b57cec5SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 22990b57cec5SDimitry Andric 23000b57cec5SDimitry Andric /// Creates an empty directive with the place 23010b57cec5SDimitry Andric /// for \a NumClauses clauses. 23020b57cec5SDimitry Andric /// 23030b57cec5SDimitry Andric /// \param C AST context. 23040b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 23050b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 23060b57cec5SDimitry Andric /// 23070b57cec5SDimitry Andric static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C, 23080b57cec5SDimitry Andric unsigned NumClauses, 23090b57cec5SDimitry Andric unsigned CollapsedNum, 23100b57cec5SDimitry Andric EmptyShell); 23110b57cec5SDimitry Andric classof(const Stmt * T)23120b57cec5SDimitry Andric static bool classof(const Stmt *T) { 23130b57cec5SDimitry Andric return T->getStmtClass() == OMPParallelForSimdDirectiveClass; 23140b57cec5SDimitry Andric } 23150b57cec5SDimitry Andric }; 23160b57cec5SDimitry Andric 2317480093f4SDimitry Andric /// This represents '#pragma omp parallel master' directive. 2318480093f4SDimitry Andric /// 2319480093f4SDimitry Andric /// \code 2320480093f4SDimitry Andric /// #pragma omp parallel master private(a,b) 2321480093f4SDimitry Andric /// \endcode 2322480093f4SDimitry Andric /// In this example directive '#pragma omp parallel master' has clauses 2323480093f4SDimitry Andric /// 'private' with the variables 'a' and 'b' 2324480093f4SDimitry Andric /// 2325480093f4SDimitry Andric class OMPParallelMasterDirective : public OMPExecutableDirective { 2326480093f4SDimitry Andric friend class ASTStmtReader; 2327e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 2328480093f4SDimitry Andric OMPParallelMasterDirective(SourceLocation StartLoc,SourceLocation EndLoc)2329e8d8bef9SDimitry Andric OMPParallelMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2330e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPParallelMasterDirectiveClass, 2331480093f4SDimitry Andric llvm::omp::OMPD_parallel_master, StartLoc, 2332e8d8bef9SDimitry Andric EndLoc) {} 2333480093f4SDimitry Andric OMPParallelMasterDirective()2334e8d8bef9SDimitry Andric explicit OMPParallelMasterDirective() 2335e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPParallelMasterDirectiveClass, 2336480093f4SDimitry Andric llvm::omp::OMPD_parallel_master, 2337e8d8bef9SDimitry Andric SourceLocation(), SourceLocation()) {} 2338480093f4SDimitry Andric 23395ffd83dbSDimitry Andric /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)2340e8d8bef9SDimitry Andric void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 23415ffd83dbSDimitry Andric 2342480093f4SDimitry Andric public: 2343480093f4SDimitry Andric /// Creates directive with a list of \a Clauses. 2344480093f4SDimitry Andric /// 2345480093f4SDimitry Andric /// \param C AST context. 2346480093f4SDimitry Andric /// \param StartLoc Starting location of the directive kind. 2347480093f4SDimitry Andric /// \param EndLoc Ending Location of the directive. 2348480093f4SDimitry Andric /// \param Clauses List of clauses. 2349480093f4SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 23505ffd83dbSDimitry Andric /// \param TaskRedRef Task reduction special reference expression to handle 23515ffd83dbSDimitry Andric /// taskgroup descriptor. 2352480093f4SDimitry Andric /// 2353480093f4SDimitry Andric static OMPParallelMasterDirective * 2354480093f4SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 23555ffd83dbSDimitry Andric ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef); 2356480093f4SDimitry Andric 2357480093f4SDimitry Andric /// Creates an empty directive with the place for \a NumClauses 2358480093f4SDimitry Andric /// clauses. 2359480093f4SDimitry Andric /// 2360480093f4SDimitry Andric /// \param C AST context. 2361480093f4SDimitry Andric /// \param NumClauses Number of clauses. 2362480093f4SDimitry Andric /// 2363480093f4SDimitry Andric static OMPParallelMasterDirective * 2364480093f4SDimitry Andric CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 2365480093f4SDimitry Andric 23665ffd83dbSDimitry Andric /// Returns special task reduction reference expression. getTaskReductionRefExpr()2367e8d8bef9SDimitry Andric Expr *getTaskReductionRefExpr() { 2368e8d8bef9SDimitry Andric return cast_or_null<Expr>(Data->getChildren()[0]); 2369e8d8bef9SDimitry Andric } getTaskReductionRefExpr()2370e8d8bef9SDimitry Andric const Expr *getTaskReductionRefExpr() const { 2371e8d8bef9SDimitry Andric return const_cast<OMPParallelMasterDirective *>(this) 2372e8d8bef9SDimitry Andric ->getTaskReductionRefExpr(); 2373e8d8bef9SDimitry Andric } 23745ffd83dbSDimitry Andric classof(const Stmt * T)2375480093f4SDimitry Andric static bool classof(const Stmt *T) { 2376480093f4SDimitry Andric return T->getStmtClass() == OMPParallelMasterDirectiveClass; 2377480093f4SDimitry Andric } 2378480093f4SDimitry Andric }; 2379480093f4SDimitry Andric 238081ad6265SDimitry Andric /// This represents '#pragma omp parallel masked' directive. 238181ad6265SDimitry Andric /// 238281ad6265SDimitry Andric /// \code 238381ad6265SDimitry Andric /// #pragma omp parallel masked filter(tid) 238481ad6265SDimitry Andric /// \endcode 238581ad6265SDimitry Andric /// In this example directive '#pragma omp parallel masked' has a clause 238681ad6265SDimitry Andric /// 'filter' with the variable tid 238781ad6265SDimitry Andric /// 238881ad6265SDimitry Andric class OMPParallelMaskedDirective final : public OMPExecutableDirective { 238981ad6265SDimitry Andric friend class ASTStmtReader; 239081ad6265SDimitry Andric friend class OMPExecutableDirective; 239181ad6265SDimitry Andric OMPParallelMaskedDirective(SourceLocation StartLoc,SourceLocation EndLoc)239281ad6265SDimitry Andric OMPParallelMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc) 239381ad6265SDimitry Andric : OMPExecutableDirective(OMPParallelMaskedDirectiveClass, 239481ad6265SDimitry Andric llvm::omp::OMPD_parallel_masked, StartLoc, 239581ad6265SDimitry Andric EndLoc) {} 239681ad6265SDimitry Andric OMPParallelMaskedDirective()239781ad6265SDimitry Andric explicit OMPParallelMaskedDirective() 239881ad6265SDimitry Andric : OMPExecutableDirective(OMPParallelMaskedDirectiveClass, 239981ad6265SDimitry Andric llvm::omp::OMPD_parallel_masked, 240081ad6265SDimitry Andric SourceLocation(), SourceLocation()) {} 240181ad6265SDimitry Andric 240281ad6265SDimitry Andric /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)240381ad6265SDimitry Andric void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 240481ad6265SDimitry Andric 240581ad6265SDimitry Andric public: 240681ad6265SDimitry Andric /// Creates directive with a list of \a Clauses. 240781ad6265SDimitry Andric /// 240881ad6265SDimitry Andric /// \param C AST context. 240981ad6265SDimitry Andric /// \param StartLoc Starting location of the directive kind. 241081ad6265SDimitry Andric /// \param EndLoc Ending Location of the directive. 241181ad6265SDimitry Andric /// \param Clauses List of clauses. 241281ad6265SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 241381ad6265SDimitry Andric /// \param TaskRedRef Task reduction special reference expression to handle 241481ad6265SDimitry Andric /// taskgroup descriptor. 241581ad6265SDimitry Andric /// 241681ad6265SDimitry Andric static OMPParallelMaskedDirective * 241781ad6265SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 241881ad6265SDimitry Andric ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef); 241981ad6265SDimitry Andric 242081ad6265SDimitry Andric /// Creates an empty directive with the place for \a NumClauses 242181ad6265SDimitry Andric /// clauses. 242281ad6265SDimitry Andric /// 242381ad6265SDimitry Andric /// \param C AST context. 242481ad6265SDimitry Andric /// \param NumClauses Number of clauses. 242581ad6265SDimitry Andric /// 242681ad6265SDimitry Andric static OMPParallelMaskedDirective * 242781ad6265SDimitry Andric CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 242881ad6265SDimitry Andric 242981ad6265SDimitry Andric /// Returns special task reduction reference expression. getTaskReductionRefExpr()243081ad6265SDimitry Andric Expr *getTaskReductionRefExpr() { 243181ad6265SDimitry Andric return cast_or_null<Expr>(Data->getChildren()[0]); 243281ad6265SDimitry Andric } getTaskReductionRefExpr()243381ad6265SDimitry Andric const Expr *getTaskReductionRefExpr() const { 243481ad6265SDimitry Andric return const_cast<OMPParallelMaskedDirective *>(this) 243581ad6265SDimitry Andric ->getTaskReductionRefExpr(); 243681ad6265SDimitry Andric } 243781ad6265SDimitry Andric classof(const Stmt * T)243881ad6265SDimitry Andric static bool classof(const Stmt *T) { 243981ad6265SDimitry Andric return T->getStmtClass() == OMPParallelMaskedDirectiveClass; 244081ad6265SDimitry Andric } 244181ad6265SDimitry Andric }; 244281ad6265SDimitry Andric 24430b57cec5SDimitry Andric /// This represents '#pragma omp parallel sections' directive. 24440b57cec5SDimitry Andric /// 24450b57cec5SDimitry Andric /// \code 24460b57cec5SDimitry Andric /// #pragma omp parallel sections private(a,b) reduction(+:c,d) 24470b57cec5SDimitry Andric /// \endcode 24480b57cec5SDimitry Andric /// In this example directive '#pragma omp parallel sections' has clauses 24490b57cec5SDimitry Andric /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' 24500b57cec5SDimitry Andric /// and variables 'c' and 'd'. 24510b57cec5SDimitry Andric /// 24520b57cec5SDimitry Andric class OMPParallelSectionsDirective : public OMPExecutableDirective { 24530b57cec5SDimitry Andric friend class ASTStmtReader; 2454e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 24550b57cec5SDimitry Andric 24560b57cec5SDimitry Andric /// true if current directive has inner cancel directive. 2457e8d8bef9SDimitry Andric bool HasCancel = false; 24580b57cec5SDimitry Andric 24590b57cec5SDimitry Andric /// Build directive with the given start and end location. 24600b57cec5SDimitry Andric /// 24610b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 24620b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 24630b57cec5SDimitry Andric /// OMPParallelSectionsDirective(SourceLocation StartLoc,SourceLocation EndLoc)2464e8d8bef9SDimitry Andric OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2465e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPParallelSectionsDirectiveClass, 2466480093f4SDimitry Andric llvm::omp::OMPD_parallel_sections, StartLoc, 2467e8d8bef9SDimitry Andric EndLoc) {} 24680b57cec5SDimitry Andric 24690b57cec5SDimitry Andric /// Build an empty directive. 24700b57cec5SDimitry Andric /// OMPParallelSectionsDirective()2471e8d8bef9SDimitry Andric explicit OMPParallelSectionsDirective() 2472e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPParallelSectionsDirectiveClass, 2473480093f4SDimitry Andric llvm::omp::OMPD_parallel_sections, 2474e8d8bef9SDimitry Andric SourceLocation(), SourceLocation()) {} 24750b57cec5SDimitry Andric 24765ffd83dbSDimitry Andric /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)2477e8d8bef9SDimitry Andric void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 24785ffd83dbSDimitry Andric 24790b57cec5SDimitry Andric /// Set cancel state. setHasCancel(bool Has)24800b57cec5SDimitry Andric void setHasCancel(bool Has) { HasCancel = Has; } 24810b57cec5SDimitry Andric 24820b57cec5SDimitry Andric public: 24830b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 24840b57cec5SDimitry Andric /// 24850b57cec5SDimitry Andric /// \param C AST context. 24860b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 24870b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 24880b57cec5SDimitry Andric /// \param Clauses List of clauses. 24890b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 24905ffd83dbSDimitry Andric /// \param TaskRedRef Task reduction special reference expression to handle 24915ffd83dbSDimitry Andric /// taskgroup descriptor. 24920b57cec5SDimitry Andric /// \param HasCancel true if current directive has inner cancel directive. 24930b57cec5SDimitry Andric /// 24940b57cec5SDimitry Andric static OMPParallelSectionsDirective * 24950b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 24965ffd83dbSDimitry Andric ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 24975ffd83dbSDimitry Andric bool HasCancel); 24980b57cec5SDimitry Andric 24990b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses 25000b57cec5SDimitry Andric /// clauses. 25010b57cec5SDimitry Andric /// 25020b57cec5SDimitry Andric /// \param C AST context. 25030b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 25040b57cec5SDimitry Andric /// 25050b57cec5SDimitry Andric static OMPParallelSectionsDirective * 25060b57cec5SDimitry Andric CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 25070b57cec5SDimitry Andric 25085ffd83dbSDimitry Andric /// Returns special task reduction reference expression. getTaskReductionRefExpr()2509e8d8bef9SDimitry Andric Expr *getTaskReductionRefExpr() { 2510e8d8bef9SDimitry Andric return cast_or_null<Expr>(Data->getChildren()[0]); 2511e8d8bef9SDimitry Andric } getTaskReductionRefExpr()2512e8d8bef9SDimitry Andric const Expr *getTaskReductionRefExpr() const { 2513e8d8bef9SDimitry Andric return const_cast<OMPParallelSectionsDirective *>(this) 2514e8d8bef9SDimitry Andric ->getTaskReductionRefExpr(); 2515e8d8bef9SDimitry Andric } 25165ffd83dbSDimitry Andric 25170b57cec5SDimitry Andric /// Return true if current directive has inner cancel directive. hasCancel()25180b57cec5SDimitry Andric bool hasCancel() const { return HasCancel; } 25190b57cec5SDimitry Andric classof(const Stmt * T)25200b57cec5SDimitry Andric static bool classof(const Stmt *T) { 25210b57cec5SDimitry Andric return T->getStmtClass() == OMPParallelSectionsDirectiveClass; 25220b57cec5SDimitry Andric } 25230b57cec5SDimitry Andric }; 25240b57cec5SDimitry Andric 25250b57cec5SDimitry Andric /// This represents '#pragma omp task' directive. 25260b57cec5SDimitry Andric /// 25270b57cec5SDimitry Andric /// \code 25280b57cec5SDimitry Andric /// #pragma omp task private(a,b) final(d) 25290b57cec5SDimitry Andric /// \endcode 25300b57cec5SDimitry Andric /// In this example directive '#pragma omp task' has clauses 'private' with the 25310b57cec5SDimitry Andric /// variables 'a' and 'b' and 'final' with condition 'd'. 25320b57cec5SDimitry Andric /// 25330b57cec5SDimitry Andric class OMPTaskDirective : public OMPExecutableDirective { 25340b57cec5SDimitry Andric friend class ASTStmtReader; 2535e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 25360b57cec5SDimitry Andric /// true if this directive has inner cancel directive. 2537e8d8bef9SDimitry Andric bool HasCancel = false; 25380b57cec5SDimitry Andric 25390b57cec5SDimitry Andric /// Build directive with the given start and end location. 25400b57cec5SDimitry Andric /// 25410b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 25420b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 25430b57cec5SDimitry Andric /// OMPTaskDirective(SourceLocation StartLoc,SourceLocation EndLoc)2544e8d8bef9SDimitry Andric OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2545e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task, 2546e8d8bef9SDimitry Andric StartLoc, EndLoc) {} 25470b57cec5SDimitry Andric 25480b57cec5SDimitry Andric /// Build an empty directive. 25490b57cec5SDimitry Andric /// OMPTaskDirective()2550e8d8bef9SDimitry Andric explicit OMPTaskDirective() 2551e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task, 2552e8d8bef9SDimitry Andric SourceLocation(), SourceLocation()) {} 25530b57cec5SDimitry Andric 25540b57cec5SDimitry Andric /// Set cancel state. setHasCancel(bool Has)25550b57cec5SDimitry Andric void setHasCancel(bool Has) { HasCancel = Has; } 25560b57cec5SDimitry Andric 25570b57cec5SDimitry Andric public: 25580b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 25590b57cec5SDimitry Andric /// 25600b57cec5SDimitry Andric /// \param C AST context. 25610b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 25620b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 25630b57cec5SDimitry Andric /// \param Clauses List of clauses. 25640b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 25650b57cec5SDimitry Andric /// \param HasCancel true, if current directive has inner cancel directive. 25660b57cec5SDimitry Andric /// 25670b57cec5SDimitry Andric static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc, 25680b57cec5SDimitry Andric SourceLocation EndLoc, 25690b57cec5SDimitry Andric ArrayRef<OMPClause *> Clauses, 25700b57cec5SDimitry Andric Stmt *AssociatedStmt, bool HasCancel); 25710b57cec5SDimitry Andric 25720b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses 25730b57cec5SDimitry Andric /// clauses. 25740b57cec5SDimitry Andric /// 25750b57cec5SDimitry Andric /// \param C AST context. 25760b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 25770b57cec5SDimitry Andric /// 25780b57cec5SDimitry Andric static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 25790b57cec5SDimitry Andric EmptyShell); 25800b57cec5SDimitry Andric 25810b57cec5SDimitry Andric /// Return true if current directive has inner cancel directive. hasCancel()25820b57cec5SDimitry Andric bool hasCancel() const { return HasCancel; } 25830b57cec5SDimitry Andric classof(const Stmt * T)25840b57cec5SDimitry Andric static bool classof(const Stmt *T) { 25850b57cec5SDimitry Andric return T->getStmtClass() == OMPTaskDirectiveClass; 25860b57cec5SDimitry Andric } 25870b57cec5SDimitry Andric }; 25880b57cec5SDimitry Andric 25890b57cec5SDimitry Andric /// This represents '#pragma omp taskyield' directive. 25900b57cec5SDimitry Andric /// 25910b57cec5SDimitry Andric /// \code 25920b57cec5SDimitry Andric /// #pragma omp taskyield 25930b57cec5SDimitry Andric /// \endcode 25940b57cec5SDimitry Andric /// 25950b57cec5SDimitry Andric class OMPTaskyieldDirective : public OMPExecutableDirective { 25960b57cec5SDimitry Andric friend class ASTStmtReader; 2597e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 25980b57cec5SDimitry Andric /// Build directive with the given start and end location. 25990b57cec5SDimitry Andric /// 26000b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 26010b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 26020b57cec5SDimitry Andric /// OMPTaskyieldDirective(SourceLocation StartLoc,SourceLocation EndLoc)26030b57cec5SDimitry Andric OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2604e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTaskyieldDirectiveClass, 2605e8d8bef9SDimitry Andric llvm::omp::OMPD_taskyield, StartLoc, EndLoc) {} 26060b57cec5SDimitry Andric 26070b57cec5SDimitry Andric /// Build an empty directive. 26080b57cec5SDimitry Andric /// OMPTaskyieldDirective()26090b57cec5SDimitry Andric explicit OMPTaskyieldDirective() 2610e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTaskyieldDirectiveClass, 2611480093f4SDimitry Andric llvm::omp::OMPD_taskyield, SourceLocation(), 2612e8d8bef9SDimitry Andric SourceLocation()) {} 26130b57cec5SDimitry Andric 26140b57cec5SDimitry Andric public: 26150b57cec5SDimitry Andric /// Creates directive. 26160b57cec5SDimitry Andric /// 26170b57cec5SDimitry Andric /// \param C AST context. 26180b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 26190b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 26200b57cec5SDimitry Andric /// 26210b57cec5SDimitry Andric static OMPTaskyieldDirective * 26220b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); 26230b57cec5SDimitry Andric 26240b57cec5SDimitry Andric /// Creates an empty directive. 26250b57cec5SDimitry Andric /// 26260b57cec5SDimitry Andric /// \param C AST context. 26270b57cec5SDimitry Andric /// 26280b57cec5SDimitry Andric static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell); 26290b57cec5SDimitry Andric classof(const Stmt * T)26300b57cec5SDimitry Andric static bool classof(const Stmt *T) { 26310b57cec5SDimitry Andric return T->getStmtClass() == OMPTaskyieldDirectiveClass; 26320b57cec5SDimitry Andric } 26330b57cec5SDimitry Andric }; 26340b57cec5SDimitry Andric 26350b57cec5SDimitry Andric /// This represents '#pragma omp barrier' directive. 26360b57cec5SDimitry Andric /// 26370b57cec5SDimitry Andric /// \code 26380b57cec5SDimitry Andric /// #pragma omp barrier 26390b57cec5SDimitry Andric /// \endcode 26400b57cec5SDimitry Andric /// 26410b57cec5SDimitry Andric class OMPBarrierDirective : public OMPExecutableDirective { 26420b57cec5SDimitry Andric friend class ASTStmtReader; 2643e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 26440b57cec5SDimitry Andric /// Build directive with the given start and end location. 26450b57cec5SDimitry Andric /// 26460b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 26470b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 26480b57cec5SDimitry Andric /// OMPBarrierDirective(SourceLocation StartLoc,SourceLocation EndLoc)26490b57cec5SDimitry Andric OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2650e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPBarrierDirectiveClass, 2651e8d8bef9SDimitry Andric llvm::omp::OMPD_barrier, StartLoc, EndLoc) {} 26520b57cec5SDimitry Andric 26530b57cec5SDimitry Andric /// Build an empty directive. 26540b57cec5SDimitry Andric /// OMPBarrierDirective()26550b57cec5SDimitry Andric explicit OMPBarrierDirective() 2656e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPBarrierDirectiveClass, 2657480093f4SDimitry Andric llvm::omp::OMPD_barrier, SourceLocation(), 2658e8d8bef9SDimitry Andric SourceLocation()) {} 26590b57cec5SDimitry Andric 26600b57cec5SDimitry Andric public: 26610b57cec5SDimitry Andric /// Creates directive. 26620b57cec5SDimitry Andric /// 26630b57cec5SDimitry Andric /// \param C AST context. 26640b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 26650b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 26660b57cec5SDimitry Andric /// 26670b57cec5SDimitry Andric static OMPBarrierDirective * 26680b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); 26690b57cec5SDimitry Andric 26700b57cec5SDimitry Andric /// Creates an empty directive. 26710b57cec5SDimitry Andric /// 26720b57cec5SDimitry Andric /// \param C AST context. 26730b57cec5SDimitry Andric /// 26740b57cec5SDimitry Andric static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell); 26750b57cec5SDimitry Andric classof(const Stmt * T)26760b57cec5SDimitry Andric static bool classof(const Stmt *T) { 26770b57cec5SDimitry Andric return T->getStmtClass() == OMPBarrierDirectiveClass; 26780b57cec5SDimitry Andric } 26790b57cec5SDimitry Andric }; 26800b57cec5SDimitry Andric 26810b57cec5SDimitry Andric /// This represents '#pragma omp taskwait' directive. 26820b57cec5SDimitry Andric /// 26830b57cec5SDimitry Andric /// \code 26840b57cec5SDimitry Andric /// #pragma omp taskwait 26850b57cec5SDimitry Andric /// \endcode 26860b57cec5SDimitry Andric /// 26870b57cec5SDimitry Andric class OMPTaskwaitDirective : public OMPExecutableDirective { 26880b57cec5SDimitry Andric friend class ASTStmtReader; 2689e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 26900b57cec5SDimitry Andric /// Build directive with the given start and end location. 26910b57cec5SDimitry Andric /// 26920b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 26930b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 26940b57cec5SDimitry Andric /// OMPTaskwaitDirective(SourceLocation StartLoc,SourceLocation EndLoc)26950b57cec5SDimitry Andric OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2696e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTaskwaitDirectiveClass, 2697e8d8bef9SDimitry Andric llvm::omp::OMPD_taskwait, StartLoc, EndLoc) {} 26980b57cec5SDimitry Andric 26990b57cec5SDimitry Andric /// Build an empty directive. 27000b57cec5SDimitry Andric /// OMPTaskwaitDirective()27010b57cec5SDimitry Andric explicit OMPTaskwaitDirective() 2702e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTaskwaitDirectiveClass, 2703480093f4SDimitry Andric llvm::omp::OMPD_taskwait, SourceLocation(), 2704e8d8bef9SDimitry Andric SourceLocation()) {} 27050b57cec5SDimitry Andric 27060b57cec5SDimitry Andric public: 27070b57cec5SDimitry Andric /// Creates directive. 27080b57cec5SDimitry Andric /// 27090b57cec5SDimitry Andric /// \param C AST context. 27100b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 27110b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 2712349cc55cSDimitry Andric /// \param Clauses List of clauses. 27130b57cec5SDimitry Andric /// 2714349cc55cSDimitry Andric static OMPTaskwaitDirective *Create(const ASTContext &C, 2715349cc55cSDimitry Andric SourceLocation StartLoc, 2716349cc55cSDimitry Andric SourceLocation EndLoc, 2717349cc55cSDimitry Andric ArrayRef<OMPClause *> Clauses); 27180b57cec5SDimitry Andric 27190b57cec5SDimitry Andric /// Creates an empty directive. 27200b57cec5SDimitry Andric /// 27210b57cec5SDimitry Andric /// \param C AST context. 2722349cc55cSDimitry Andric /// \param NumClauses Number of clauses. 27230b57cec5SDimitry Andric /// 2724349cc55cSDimitry Andric static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, 2725349cc55cSDimitry Andric unsigned NumClauses, EmptyShell); 27260b57cec5SDimitry Andric classof(const Stmt * T)27270b57cec5SDimitry Andric static bool classof(const Stmt *T) { 27280b57cec5SDimitry Andric return T->getStmtClass() == OMPTaskwaitDirectiveClass; 27290b57cec5SDimitry Andric } 27300b57cec5SDimitry Andric }; 27310b57cec5SDimitry Andric 27320b57cec5SDimitry Andric /// This represents '#pragma omp taskgroup' directive. 27330b57cec5SDimitry Andric /// 27340b57cec5SDimitry Andric /// \code 27350b57cec5SDimitry Andric /// #pragma omp taskgroup 27360b57cec5SDimitry Andric /// \endcode 27370b57cec5SDimitry Andric /// 27380b57cec5SDimitry Andric class OMPTaskgroupDirective : public OMPExecutableDirective { 27390b57cec5SDimitry Andric friend class ASTStmtReader; 2740e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 27410b57cec5SDimitry Andric /// Build directive with the given start and end location. 27420b57cec5SDimitry Andric /// 27430b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 27440b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 27450b57cec5SDimitry Andric /// OMPTaskgroupDirective(SourceLocation StartLoc,SourceLocation EndLoc)2746e8d8bef9SDimitry Andric OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2747e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTaskgroupDirectiveClass, 2748e8d8bef9SDimitry Andric llvm::omp::OMPD_taskgroup, StartLoc, EndLoc) {} 27490b57cec5SDimitry Andric 27500b57cec5SDimitry Andric /// Build an empty directive. 27510b57cec5SDimitry Andric /// OMPTaskgroupDirective()2752e8d8bef9SDimitry Andric explicit OMPTaskgroupDirective() 2753e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTaskgroupDirectiveClass, 2754480093f4SDimitry Andric llvm::omp::OMPD_taskgroup, SourceLocation(), 2755e8d8bef9SDimitry Andric SourceLocation()) {} 27560b57cec5SDimitry Andric 27570b57cec5SDimitry Andric /// Sets the task_reduction return variable. setReductionRef(Expr * RR)2758e8d8bef9SDimitry Andric void setReductionRef(Expr *RR) { Data->getChildren()[0] = RR; } 27590b57cec5SDimitry Andric 27600b57cec5SDimitry Andric public: 27610b57cec5SDimitry Andric /// Creates directive. 27620b57cec5SDimitry Andric /// 27630b57cec5SDimitry Andric /// \param C AST context. 27640b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 27650b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 27660b57cec5SDimitry Andric /// \param Clauses List of clauses. 27670b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 27680b57cec5SDimitry Andric /// \param ReductionRef Reference to the task_reduction return variable. 27690b57cec5SDimitry Andric /// 27700b57cec5SDimitry Andric static OMPTaskgroupDirective * 27710b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 27720b57cec5SDimitry Andric ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, 27730b57cec5SDimitry Andric Expr *ReductionRef); 27740b57cec5SDimitry Andric 27750b57cec5SDimitry Andric /// Creates an empty directive. 27760b57cec5SDimitry Andric /// 27770b57cec5SDimitry Andric /// \param C AST context. 27780b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 27790b57cec5SDimitry Andric /// 27800b57cec5SDimitry Andric static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, 27810b57cec5SDimitry Andric unsigned NumClauses, EmptyShell); 27820b57cec5SDimitry Andric 27830b57cec5SDimitry Andric 27840b57cec5SDimitry Andric /// Returns reference to the task_reduction return variable. getReductionRef()27850b57cec5SDimitry Andric const Expr *getReductionRef() const { 2786e8d8bef9SDimitry Andric return const_cast<OMPTaskgroupDirective *>(this)->getReductionRef(); 27870b57cec5SDimitry Andric } getReductionRef()2788e8d8bef9SDimitry Andric Expr *getReductionRef() { return cast_or_null<Expr>(Data->getChildren()[0]); } 27890b57cec5SDimitry Andric classof(const Stmt * T)27900b57cec5SDimitry Andric static bool classof(const Stmt *T) { 27910b57cec5SDimitry Andric return T->getStmtClass() == OMPTaskgroupDirectiveClass; 27920b57cec5SDimitry Andric } 27930b57cec5SDimitry Andric }; 27940b57cec5SDimitry Andric 27950b57cec5SDimitry Andric /// This represents '#pragma omp flush' directive. 27960b57cec5SDimitry Andric /// 27970b57cec5SDimitry Andric /// \code 27980b57cec5SDimitry Andric /// #pragma omp flush(a,b) 27990b57cec5SDimitry Andric /// \endcode 28000b57cec5SDimitry Andric /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a' 28010b57cec5SDimitry Andric /// and 'b'. 28020b57cec5SDimitry Andric /// 'omp flush' directive does not have clauses but have an optional list of 28030b57cec5SDimitry Andric /// variables to flush. This list of variables is stored within some fake clause 28040b57cec5SDimitry Andric /// FlushClause. 28050b57cec5SDimitry Andric class OMPFlushDirective : public OMPExecutableDirective { 28060b57cec5SDimitry Andric friend class ASTStmtReader; 2807e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 28080b57cec5SDimitry Andric /// Build directive with the given start and end location. 28090b57cec5SDimitry Andric /// 28100b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 28110b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 28120b57cec5SDimitry Andric /// OMPFlushDirective(SourceLocation StartLoc,SourceLocation EndLoc)2813e8d8bef9SDimitry Andric OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2814e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush, 2815e8d8bef9SDimitry Andric StartLoc, EndLoc) {} 28160b57cec5SDimitry Andric 28170b57cec5SDimitry Andric /// Build an empty directive. 28180b57cec5SDimitry Andric /// OMPFlushDirective()2819e8d8bef9SDimitry Andric explicit OMPFlushDirective() 2820e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush, 2821e8d8bef9SDimitry Andric SourceLocation(), SourceLocation()) {} 28220b57cec5SDimitry Andric 28230b57cec5SDimitry Andric public: 28240b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 28250b57cec5SDimitry Andric /// 28260b57cec5SDimitry Andric /// \param C AST context. 28270b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 28280b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 28290b57cec5SDimitry Andric /// \param Clauses List of clauses (only single OMPFlushClause clause is 28300b57cec5SDimitry Andric /// allowed). 28310b57cec5SDimitry Andric /// 28320b57cec5SDimitry Andric static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc, 28330b57cec5SDimitry Andric SourceLocation EndLoc, 28340b57cec5SDimitry Andric ArrayRef<OMPClause *> Clauses); 28350b57cec5SDimitry Andric 28360b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses 28370b57cec5SDimitry Andric /// clauses. 28380b57cec5SDimitry Andric /// 28390b57cec5SDimitry Andric /// \param C AST context. 28400b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 28410b57cec5SDimitry Andric /// 28420b57cec5SDimitry Andric static OMPFlushDirective *CreateEmpty(const ASTContext &C, 28430b57cec5SDimitry Andric unsigned NumClauses, EmptyShell); 28440b57cec5SDimitry Andric classof(const Stmt * T)28450b57cec5SDimitry Andric static bool classof(const Stmt *T) { 28460b57cec5SDimitry Andric return T->getStmtClass() == OMPFlushDirectiveClass; 28470b57cec5SDimitry Andric } 28480b57cec5SDimitry Andric }; 28490b57cec5SDimitry Andric 28505ffd83dbSDimitry Andric /// This represents '#pragma omp depobj' directive. 28515ffd83dbSDimitry Andric /// 28525ffd83dbSDimitry Andric /// \code 28535ffd83dbSDimitry Andric /// #pragma omp depobj(a) depend(in:x,y) 28545ffd83dbSDimitry Andric /// \endcode 28555ffd83dbSDimitry Andric /// In this example directive '#pragma omp depobj' initializes a depobj object 28565ffd83dbSDimitry Andric /// 'a' with dependence type 'in' and a list with 'x' and 'y' locators. 28575ffd83dbSDimitry Andric class OMPDepobjDirective final : public OMPExecutableDirective { 28585ffd83dbSDimitry Andric friend class ASTStmtReader; 2859e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 28605ffd83dbSDimitry Andric 28615ffd83dbSDimitry Andric /// Build directive with the given start and end location. 28625ffd83dbSDimitry Andric /// 28635ffd83dbSDimitry Andric /// \param StartLoc Starting location of the directive kind. 28645ffd83dbSDimitry Andric /// \param EndLoc Ending location of the directive. 28655ffd83dbSDimitry Andric /// OMPDepobjDirective(SourceLocation StartLoc,SourceLocation EndLoc)2866e8d8bef9SDimitry Andric OMPDepobjDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2867e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj, 2868e8d8bef9SDimitry Andric StartLoc, EndLoc) {} 28695ffd83dbSDimitry Andric 28705ffd83dbSDimitry Andric /// Build an empty directive. 28715ffd83dbSDimitry Andric /// OMPDepobjDirective()2872e8d8bef9SDimitry Andric explicit OMPDepobjDirective() 2873e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj, 2874e8d8bef9SDimitry Andric SourceLocation(), SourceLocation()) {} 28755ffd83dbSDimitry Andric 28765ffd83dbSDimitry Andric public: 28775ffd83dbSDimitry Andric /// Creates directive with a list of \a Clauses. 28785ffd83dbSDimitry Andric /// 28795ffd83dbSDimitry Andric /// \param C AST context. 28805ffd83dbSDimitry Andric /// \param StartLoc Starting location of the directive kind. 28815ffd83dbSDimitry Andric /// \param EndLoc Ending Location of the directive. 28825ffd83dbSDimitry Andric /// \param Clauses List of clauses. 28835ffd83dbSDimitry Andric /// 28845ffd83dbSDimitry Andric static OMPDepobjDirective *Create(const ASTContext &C, 28855ffd83dbSDimitry Andric SourceLocation StartLoc, 28865ffd83dbSDimitry Andric SourceLocation EndLoc, 28875ffd83dbSDimitry Andric ArrayRef<OMPClause *> Clauses); 28885ffd83dbSDimitry Andric 28895ffd83dbSDimitry Andric /// Creates an empty directive with the place for \a NumClauses 28905ffd83dbSDimitry Andric /// clauses. 28915ffd83dbSDimitry Andric /// 28925ffd83dbSDimitry Andric /// \param C AST context. 28935ffd83dbSDimitry Andric /// \param NumClauses Number of clauses. 28945ffd83dbSDimitry Andric /// 28955ffd83dbSDimitry Andric static OMPDepobjDirective *CreateEmpty(const ASTContext &C, 28965ffd83dbSDimitry Andric unsigned NumClauses, EmptyShell); 28975ffd83dbSDimitry Andric classof(const Stmt * T)28985ffd83dbSDimitry Andric static bool classof(const Stmt *T) { 28995ffd83dbSDimitry Andric return T->getStmtClass() == OMPDepobjDirectiveClass; 29005ffd83dbSDimitry Andric } 29015ffd83dbSDimitry Andric }; 29025ffd83dbSDimitry Andric 29030b57cec5SDimitry Andric /// This represents '#pragma omp ordered' directive. 29040b57cec5SDimitry Andric /// 29050b57cec5SDimitry Andric /// \code 29060b57cec5SDimitry Andric /// #pragma omp ordered 29070b57cec5SDimitry Andric /// \endcode 29080b57cec5SDimitry Andric /// 29090b57cec5SDimitry Andric class OMPOrderedDirective : public OMPExecutableDirective { 29100b57cec5SDimitry Andric friend class ASTStmtReader; 2911e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 29120b57cec5SDimitry Andric /// Build directive with the given start and end location. 29130b57cec5SDimitry Andric /// 29140b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 29150b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 29160b57cec5SDimitry Andric /// OMPOrderedDirective(SourceLocation StartLoc,SourceLocation EndLoc)2917e8d8bef9SDimitry Andric OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2918e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPOrderedDirectiveClass, 2919e8d8bef9SDimitry Andric llvm::omp::OMPD_ordered, StartLoc, EndLoc) {} 29200b57cec5SDimitry Andric 29210b57cec5SDimitry Andric /// Build an empty directive. 29220b57cec5SDimitry Andric /// OMPOrderedDirective()2923e8d8bef9SDimitry Andric explicit OMPOrderedDirective() 2924e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPOrderedDirectiveClass, 2925480093f4SDimitry Andric llvm::omp::OMPD_ordered, SourceLocation(), 2926e8d8bef9SDimitry Andric SourceLocation()) {} 29270b57cec5SDimitry Andric 29280b57cec5SDimitry Andric public: 29290b57cec5SDimitry Andric /// Creates directive. 29300b57cec5SDimitry Andric /// 29310b57cec5SDimitry Andric /// \param C AST context. 29320b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 29330b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 29340b57cec5SDimitry Andric /// \param Clauses List of clauses. 29350b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 29360b57cec5SDimitry Andric /// 29370b57cec5SDimitry Andric static OMPOrderedDirective * 29380b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 29390b57cec5SDimitry Andric ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 29400b57cec5SDimitry Andric 29410b57cec5SDimitry Andric /// Creates an empty directive. 29420b57cec5SDimitry Andric /// 29430b57cec5SDimitry Andric /// \param C AST context. 29440b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 2945bdd1243dSDimitry Andric /// \param IsStandalone true, if the standalone directive is created. 29460b57cec5SDimitry Andric /// 29470b57cec5SDimitry Andric static OMPOrderedDirective *CreateEmpty(const ASTContext &C, 2948e8d8bef9SDimitry Andric unsigned NumClauses, 2949e8d8bef9SDimitry Andric bool IsStandalone, EmptyShell); 29500b57cec5SDimitry Andric classof(const Stmt * T)29510b57cec5SDimitry Andric static bool classof(const Stmt *T) { 29520b57cec5SDimitry Andric return T->getStmtClass() == OMPOrderedDirectiveClass; 29530b57cec5SDimitry Andric } 29540b57cec5SDimitry Andric }; 29550b57cec5SDimitry Andric 29560b57cec5SDimitry Andric /// This represents '#pragma omp atomic' directive. 29570b57cec5SDimitry Andric /// 29580b57cec5SDimitry Andric /// \code 29590b57cec5SDimitry Andric /// #pragma omp atomic capture 29600b57cec5SDimitry Andric /// \endcode 29610b57cec5SDimitry Andric /// In this example directive '#pragma omp atomic' has clause 'capture'. 29620b57cec5SDimitry Andric /// 29630b57cec5SDimitry Andric class OMPAtomicDirective : public OMPExecutableDirective { 29640b57cec5SDimitry Andric friend class ASTStmtReader; 2965e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 296681ad6265SDimitry Andric 296781ad6265SDimitry Andric struct FlagTy { 29680b57cec5SDimitry Andric /// Used for 'atomic update' or 'atomic capture' constructs. They may 296981ad6265SDimitry Andric /// have atomic expressions of forms: 29700b57cec5SDimitry Andric /// \code 29710b57cec5SDimitry Andric /// x = x binop expr; 29720b57cec5SDimitry Andric /// x = expr binop x; 29730b57cec5SDimitry Andric /// \endcode 297481ad6265SDimitry Andric /// This field is 1 for the first form of the expression and 0 for the 29750b57cec5SDimitry Andric /// second. Required for correct codegen of non-associative operations (like 29760b57cec5SDimitry Andric /// << or >>). 297781ad6265SDimitry Andric uint8_t IsXLHSInRHSPart : 1; 29780b57cec5SDimitry Andric /// Used for 'atomic update' or 'atomic capture' constructs. They may 297981ad6265SDimitry Andric /// have atomic expressions of forms: 29800b57cec5SDimitry Andric /// \code 29810b57cec5SDimitry Andric /// v = x; <update x>; 29820b57cec5SDimitry Andric /// <update x>; v = x; 29830b57cec5SDimitry Andric /// \endcode 298481ad6265SDimitry Andric /// This field is 1 for the first(postfix) form of the expression and 0 29850b57cec5SDimitry Andric /// otherwise. 298681ad6265SDimitry Andric uint8_t IsPostfixUpdate : 1; 298781ad6265SDimitry Andric /// 1 if 'v' is updated only when the condition is false (compare capture 298881ad6265SDimitry Andric /// only). 298981ad6265SDimitry Andric uint8_t IsFailOnly : 1; 299081ad6265SDimitry Andric } Flags; 29910b57cec5SDimitry Andric 29920b57cec5SDimitry Andric /// Build directive with the given start and end location. 29930b57cec5SDimitry Andric /// 29940b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 29950b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 29960b57cec5SDimitry Andric /// OMPAtomicDirective(SourceLocation StartLoc,SourceLocation EndLoc)2997e8d8bef9SDimitry Andric OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2998e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic, 2999e8d8bef9SDimitry Andric StartLoc, EndLoc) {} 30000b57cec5SDimitry Andric 30010b57cec5SDimitry Andric /// Build an empty directive. 30020b57cec5SDimitry Andric /// OMPAtomicDirective()3003e8d8bef9SDimitry Andric explicit OMPAtomicDirective() 3004e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic, 3005e8d8bef9SDimitry Andric SourceLocation(), SourceLocation()) {} 30060b57cec5SDimitry Andric 3007349cc55cSDimitry Andric enum DataPositionTy : size_t { 3008349cc55cSDimitry Andric POS_X = 0, 3009349cc55cSDimitry Andric POS_V, 3010349cc55cSDimitry Andric POS_E, 3011349cc55cSDimitry Andric POS_UpdateExpr, 301281ad6265SDimitry Andric POS_D, 301381ad6265SDimitry Andric POS_Cond, 301481ad6265SDimitry Andric POS_R, 3015349cc55cSDimitry Andric }; 3016349cc55cSDimitry Andric 30170b57cec5SDimitry Andric /// Set 'x' part of the associated expression/statement. setX(Expr * X)3018349cc55cSDimitry Andric void setX(Expr *X) { Data->getChildren()[DataPositionTy::POS_X] = X; } 30190b57cec5SDimitry Andric /// Set helper expression of the form 30200b57cec5SDimitry Andric /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 30210b57cec5SDimitry Andric /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. setUpdateExpr(Expr * UE)3022349cc55cSDimitry Andric void setUpdateExpr(Expr *UE) { 3023349cc55cSDimitry Andric Data->getChildren()[DataPositionTy::POS_UpdateExpr] = UE; 3024349cc55cSDimitry Andric } 30250b57cec5SDimitry Andric /// Set 'v' part of the associated expression/statement. setV(Expr * V)3026349cc55cSDimitry Andric void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; } 302781ad6265SDimitry Andric /// Set 'r' part of the associated expression/statement. setR(Expr * R)302881ad6265SDimitry Andric void setR(Expr *R) { Data->getChildren()[DataPositionTy::POS_R] = R; } 30290b57cec5SDimitry Andric /// Set 'expr' part of the associated expression/statement. setExpr(Expr * E)3030349cc55cSDimitry Andric void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; } 303181ad6265SDimitry Andric /// Set 'd' part of the associated expression/statement. setD(Expr * D)303281ad6265SDimitry Andric void setD(Expr *D) { Data->getChildren()[DataPositionTy::POS_D] = D; } 303381ad6265SDimitry Andric /// Set conditional expression in `atomic compare`. setCond(Expr * C)303481ad6265SDimitry Andric void setCond(Expr *C) { Data->getChildren()[DataPositionTy::POS_Cond] = C; } 30350b57cec5SDimitry Andric 30360b57cec5SDimitry Andric public: 303781ad6265SDimitry Andric struct Expressions { 303881ad6265SDimitry Andric /// 'x' part of the associated expression/statement. 303981ad6265SDimitry Andric Expr *X = nullptr; 304081ad6265SDimitry Andric /// 'v' part of the associated expression/statement. 304181ad6265SDimitry Andric Expr *V = nullptr; 304281ad6265SDimitry Andric // 'r' part of the associated expression/statement. 304381ad6265SDimitry Andric Expr *R = nullptr; 304481ad6265SDimitry Andric /// 'expr' part of the associated expression/statement. 304581ad6265SDimitry Andric Expr *E = nullptr; 304681ad6265SDimitry Andric /// UE Helper expression of the form: 304781ad6265SDimitry Andric /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 304881ad6265SDimitry Andric /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 304981ad6265SDimitry Andric Expr *UE = nullptr; 305081ad6265SDimitry Andric /// 'd' part of the associated expression/statement. 305181ad6265SDimitry Andric Expr *D = nullptr; 305281ad6265SDimitry Andric /// Conditional expression in `atomic compare` construct. 305381ad6265SDimitry Andric Expr *Cond = nullptr; 305481ad6265SDimitry Andric /// True if UE has the first form and false if the second. 305581ad6265SDimitry Andric bool IsXLHSInRHSPart; 305681ad6265SDimitry Andric /// True if original value of 'x' must be stored in 'v', not an updated one. 305781ad6265SDimitry Andric bool IsPostfixUpdate; 305881ad6265SDimitry Andric /// True if 'v' is updated only when the condition is false (compare capture 305981ad6265SDimitry Andric /// only). 306081ad6265SDimitry Andric bool IsFailOnly; 306181ad6265SDimitry Andric }; 306281ad6265SDimitry Andric 30630b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr' 30640b57cec5SDimitry Andric /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for 30650b57cec5SDimitry Andric /// detailed description of 'x', 'v' and 'expr'). 30660b57cec5SDimitry Andric /// 30670b57cec5SDimitry Andric /// \param C AST context. 30680b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 30690b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 30700b57cec5SDimitry Andric /// \param Clauses List of clauses. 30710b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 307281ad6265SDimitry Andric /// \param Exprs Associated expressions or statements. 307381ad6265SDimitry Andric static OMPAtomicDirective *Create(const ASTContext &C, 307481ad6265SDimitry Andric SourceLocation StartLoc, 307581ad6265SDimitry Andric SourceLocation EndLoc, 307681ad6265SDimitry Andric ArrayRef<OMPClause *> Clauses, 307781ad6265SDimitry Andric Stmt *AssociatedStmt, Expressions Exprs); 30780b57cec5SDimitry Andric 30790b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses 30800b57cec5SDimitry Andric /// clauses. 30810b57cec5SDimitry Andric /// 30820b57cec5SDimitry Andric /// \param C AST context. 30830b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 30840b57cec5SDimitry Andric /// 30850b57cec5SDimitry Andric static OMPAtomicDirective *CreateEmpty(const ASTContext &C, 30860b57cec5SDimitry Andric unsigned NumClauses, EmptyShell); 30870b57cec5SDimitry Andric 30880b57cec5SDimitry Andric /// Get 'x' part of the associated expression/statement. getX()3089349cc55cSDimitry Andric Expr *getX() { 3090349cc55cSDimitry Andric return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]); 3091349cc55cSDimitry Andric } getX()30920b57cec5SDimitry Andric const Expr *getX() const { 3093349cc55cSDimitry Andric return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]); 30940b57cec5SDimitry Andric } 30950b57cec5SDimitry Andric /// Get helper expression of the form 30960b57cec5SDimitry Andric /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 30970b57cec5SDimitry Andric /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. getUpdateExpr()3098349cc55cSDimitry Andric Expr *getUpdateExpr() { 3099349cc55cSDimitry Andric return cast_or_null<Expr>( 3100349cc55cSDimitry Andric Data->getChildren()[DataPositionTy::POS_UpdateExpr]); 3101349cc55cSDimitry Andric } getUpdateExpr()31020b57cec5SDimitry Andric const Expr *getUpdateExpr() const { 3103349cc55cSDimitry Andric return cast_or_null<Expr>( 3104349cc55cSDimitry Andric Data->getChildren()[DataPositionTy::POS_UpdateExpr]); 31050b57cec5SDimitry Andric } 31060b57cec5SDimitry Andric /// Return true if helper update expression has form 31070b57cec5SDimitry Andric /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form 31080b57cec5SDimitry Andric /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. isXLHSInRHSPart()310981ad6265SDimitry Andric bool isXLHSInRHSPart() const { return Flags.IsXLHSInRHSPart; } 31100b57cec5SDimitry Andric /// Return true if 'v' expression must be updated to original value of 31110b57cec5SDimitry Andric /// 'x', false if 'v' must be updated to the new value of 'x'. isPostfixUpdate()311281ad6265SDimitry Andric bool isPostfixUpdate() const { return Flags.IsPostfixUpdate; } 311381ad6265SDimitry Andric /// Return true if 'v' is updated only when the condition is evaluated false 311481ad6265SDimitry Andric /// (compare capture only). isFailOnly()311581ad6265SDimitry Andric bool isFailOnly() const { return Flags.IsFailOnly; } 31160b57cec5SDimitry Andric /// Get 'v' part of the associated expression/statement. getV()3117349cc55cSDimitry Andric Expr *getV() { 3118349cc55cSDimitry Andric return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]); 3119349cc55cSDimitry Andric } getV()31200b57cec5SDimitry Andric const Expr *getV() const { 3121349cc55cSDimitry Andric return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]); 31220b57cec5SDimitry Andric } 312381ad6265SDimitry Andric /// Get 'r' part of the associated expression/statement. getR()312481ad6265SDimitry Andric Expr *getR() { 312581ad6265SDimitry Andric return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]); 312681ad6265SDimitry Andric } getR()312781ad6265SDimitry Andric const Expr *getR() const { 312881ad6265SDimitry Andric return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]); 312981ad6265SDimitry Andric } 31300b57cec5SDimitry Andric /// Get 'expr' part of the associated expression/statement. getExpr()3131349cc55cSDimitry Andric Expr *getExpr() { 3132349cc55cSDimitry Andric return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]); 3133349cc55cSDimitry Andric } getExpr()31340b57cec5SDimitry Andric const Expr *getExpr() const { 3135349cc55cSDimitry Andric return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]); 31360b57cec5SDimitry Andric } 313781ad6265SDimitry Andric /// Get 'd' part of the associated expression/statement. getD()313881ad6265SDimitry Andric Expr *getD() { 313981ad6265SDimitry Andric return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]); 314081ad6265SDimitry Andric } getD()314181ad6265SDimitry Andric Expr *getD() const { 314281ad6265SDimitry Andric return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]); 314381ad6265SDimitry Andric } 314481ad6265SDimitry Andric /// Get the 'cond' part of the source atomic expression. getCondExpr()314581ad6265SDimitry Andric Expr *getCondExpr() { 314681ad6265SDimitry Andric return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]); 314781ad6265SDimitry Andric } getCondExpr()314881ad6265SDimitry Andric Expr *getCondExpr() const { 314981ad6265SDimitry Andric return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]); 315081ad6265SDimitry Andric } 31510b57cec5SDimitry Andric classof(const Stmt * T)31520b57cec5SDimitry Andric static bool classof(const Stmt *T) { 31530b57cec5SDimitry Andric return T->getStmtClass() == OMPAtomicDirectiveClass; 31540b57cec5SDimitry Andric } 31550b57cec5SDimitry Andric }; 31560b57cec5SDimitry Andric 31570b57cec5SDimitry Andric /// This represents '#pragma omp target' directive. 31580b57cec5SDimitry Andric /// 31590b57cec5SDimitry Andric /// \code 31600b57cec5SDimitry Andric /// #pragma omp target if(a) 31610b57cec5SDimitry Andric /// \endcode 31620b57cec5SDimitry Andric /// In this example directive '#pragma omp target' has clause 'if' with 31630b57cec5SDimitry Andric /// condition 'a'. 31640b57cec5SDimitry Andric /// 31650b57cec5SDimitry Andric class OMPTargetDirective : public OMPExecutableDirective { 31660b57cec5SDimitry Andric friend class ASTStmtReader; 3167e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 31680b57cec5SDimitry Andric /// Build directive with the given start and end location. 31690b57cec5SDimitry Andric /// 31700b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 31710b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 31720b57cec5SDimitry Andric /// OMPTargetDirective(SourceLocation StartLoc,SourceLocation EndLoc)3173e8d8bef9SDimitry Andric OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3174e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target, 3175e8d8bef9SDimitry Andric StartLoc, EndLoc) {} 31760b57cec5SDimitry Andric 31770b57cec5SDimitry Andric /// Build an empty directive. 31780b57cec5SDimitry Andric /// OMPTargetDirective()3179e8d8bef9SDimitry Andric explicit OMPTargetDirective() 3180e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target, 3181e8d8bef9SDimitry Andric SourceLocation(), SourceLocation()) {} 31820b57cec5SDimitry Andric 31830b57cec5SDimitry Andric public: 31840b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 31850b57cec5SDimitry Andric /// 31860b57cec5SDimitry Andric /// \param C AST context. 31870b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 31880b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 31890b57cec5SDimitry Andric /// \param Clauses List of clauses. 31900b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 31910b57cec5SDimitry Andric /// 31920b57cec5SDimitry Andric static OMPTargetDirective * 31930b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 31940b57cec5SDimitry Andric ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 31950b57cec5SDimitry Andric 31960b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses 31970b57cec5SDimitry Andric /// clauses. 31980b57cec5SDimitry Andric /// 31990b57cec5SDimitry Andric /// \param C AST context. 32000b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 32010b57cec5SDimitry Andric /// 32020b57cec5SDimitry Andric static OMPTargetDirective *CreateEmpty(const ASTContext &C, 32030b57cec5SDimitry Andric unsigned NumClauses, EmptyShell); 32040b57cec5SDimitry Andric classof(const Stmt * T)32050b57cec5SDimitry Andric static bool classof(const Stmt *T) { 32060b57cec5SDimitry Andric return T->getStmtClass() == OMPTargetDirectiveClass; 32070b57cec5SDimitry Andric } 32080b57cec5SDimitry Andric }; 32090b57cec5SDimitry Andric 32100b57cec5SDimitry Andric /// This represents '#pragma omp target data' directive. 32110b57cec5SDimitry Andric /// 32120b57cec5SDimitry Andric /// \code 32130b57cec5SDimitry Andric /// #pragma omp target data device(0) if(a) map(b[:]) 32140b57cec5SDimitry Andric /// \endcode 32150b57cec5SDimitry Andric /// In this example directive '#pragma omp target data' has clauses 'device' 32160b57cec5SDimitry Andric /// with the value '0', 'if' with condition 'a' and 'map' with array 32170b57cec5SDimitry Andric /// section 'b[:]'. 32180b57cec5SDimitry Andric /// 32190b57cec5SDimitry Andric class OMPTargetDataDirective : public OMPExecutableDirective { 32200b57cec5SDimitry Andric friend class ASTStmtReader; 3221e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 32220b57cec5SDimitry Andric /// Build directive with the given start and end location. 32230b57cec5SDimitry Andric /// 32240b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 32250b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 32260b57cec5SDimitry Andric /// OMPTargetDataDirective(SourceLocation StartLoc,SourceLocation EndLoc)3227e8d8bef9SDimitry Andric OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3228e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTargetDataDirectiveClass, 3229e8d8bef9SDimitry Andric llvm::omp::OMPD_target_data, StartLoc, EndLoc) {} 32300b57cec5SDimitry Andric 32310b57cec5SDimitry Andric /// Build an empty directive. 32320b57cec5SDimitry Andric /// OMPTargetDataDirective()3233e8d8bef9SDimitry Andric explicit OMPTargetDataDirective() 3234e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTargetDataDirectiveClass, 3235480093f4SDimitry Andric llvm::omp::OMPD_target_data, SourceLocation(), 3236e8d8bef9SDimitry Andric SourceLocation()) {} 32370b57cec5SDimitry Andric 32380b57cec5SDimitry Andric public: 32390b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 32400b57cec5SDimitry Andric /// 32410b57cec5SDimitry Andric /// \param C AST context. 32420b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 32430b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 32440b57cec5SDimitry Andric /// \param Clauses List of clauses. 32450b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 32460b57cec5SDimitry Andric /// 32470b57cec5SDimitry Andric static OMPTargetDataDirective * 32480b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 32490b57cec5SDimitry Andric ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 32500b57cec5SDimitry Andric 32510b57cec5SDimitry Andric /// Creates an empty directive with the place for \a N clauses. 32520b57cec5SDimitry Andric /// 32530b57cec5SDimitry Andric /// \param C AST context. 32540b57cec5SDimitry Andric /// \param N The number of clauses. 32550b57cec5SDimitry Andric /// 32560b57cec5SDimitry Andric static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N, 32570b57cec5SDimitry Andric EmptyShell); 32580b57cec5SDimitry Andric classof(const Stmt * T)32590b57cec5SDimitry Andric static bool classof(const Stmt *T) { 32600b57cec5SDimitry Andric return T->getStmtClass() == OMPTargetDataDirectiveClass; 32610b57cec5SDimitry Andric } 32620b57cec5SDimitry Andric }; 32630b57cec5SDimitry Andric 32640b57cec5SDimitry Andric /// This represents '#pragma omp target enter data' directive. 32650b57cec5SDimitry Andric /// 32660b57cec5SDimitry Andric /// \code 32670b57cec5SDimitry Andric /// #pragma omp target enter data device(0) if(a) map(b[:]) 32680b57cec5SDimitry Andric /// \endcode 32690b57cec5SDimitry Andric /// In this example directive '#pragma omp target enter data' has clauses 32700b57cec5SDimitry Andric /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array 32710b57cec5SDimitry Andric /// section 'b[:]'. 32720b57cec5SDimitry Andric /// 32730b57cec5SDimitry Andric class OMPTargetEnterDataDirective : public OMPExecutableDirective { 32740b57cec5SDimitry Andric friend class ASTStmtReader; 3275e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 32760b57cec5SDimitry Andric /// Build directive with the given start and end location. 32770b57cec5SDimitry Andric /// 32780b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 32790b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 32800b57cec5SDimitry Andric /// OMPTargetEnterDataDirective(SourceLocation StartLoc,SourceLocation EndLoc)3281e8d8bef9SDimitry Andric OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3282e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass, 3283480093f4SDimitry Andric llvm::omp::OMPD_target_enter_data, StartLoc, 3284e8d8bef9SDimitry Andric EndLoc) {} 32850b57cec5SDimitry Andric 32860b57cec5SDimitry Andric /// Build an empty directive. 32870b57cec5SDimitry Andric /// OMPTargetEnterDataDirective()3288e8d8bef9SDimitry Andric explicit OMPTargetEnterDataDirective() 3289e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass, 3290480093f4SDimitry Andric llvm::omp::OMPD_target_enter_data, 3291e8d8bef9SDimitry Andric SourceLocation(), SourceLocation()) {} 32920b57cec5SDimitry Andric 32930b57cec5SDimitry Andric public: 32940b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 32950b57cec5SDimitry Andric /// 32960b57cec5SDimitry Andric /// \param C AST context. 32970b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 32980b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 32990b57cec5SDimitry Andric /// \param Clauses List of clauses. 33000b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 33010b57cec5SDimitry Andric /// 33020b57cec5SDimitry Andric static OMPTargetEnterDataDirective * 33030b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 33040b57cec5SDimitry Andric ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 33050b57cec5SDimitry Andric 33060b57cec5SDimitry Andric /// Creates an empty directive with the place for \a N clauses. 33070b57cec5SDimitry Andric /// 33080b57cec5SDimitry Andric /// \param C AST context. 33090b57cec5SDimitry Andric /// \param N The number of clauses. 33100b57cec5SDimitry Andric /// 33110b57cec5SDimitry Andric static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C, 33120b57cec5SDimitry Andric unsigned N, EmptyShell); 33130b57cec5SDimitry Andric classof(const Stmt * T)33140b57cec5SDimitry Andric static bool classof(const Stmt *T) { 33150b57cec5SDimitry Andric return T->getStmtClass() == OMPTargetEnterDataDirectiveClass; 33160b57cec5SDimitry Andric } 33170b57cec5SDimitry Andric }; 33180b57cec5SDimitry Andric 33190b57cec5SDimitry Andric /// This represents '#pragma omp target exit data' directive. 33200b57cec5SDimitry Andric /// 33210b57cec5SDimitry Andric /// \code 33220b57cec5SDimitry Andric /// #pragma omp target exit data device(0) if(a) map(b[:]) 33230b57cec5SDimitry Andric /// \endcode 33240b57cec5SDimitry Andric /// In this example directive '#pragma omp target exit data' has clauses 33250b57cec5SDimitry Andric /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array 33260b57cec5SDimitry Andric /// section 'b[:]'. 33270b57cec5SDimitry Andric /// 33280b57cec5SDimitry Andric class OMPTargetExitDataDirective : public OMPExecutableDirective { 33290b57cec5SDimitry Andric friend class ASTStmtReader; 3330e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 33310b57cec5SDimitry Andric /// Build directive with the given start and end location. 33320b57cec5SDimitry Andric /// 33330b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 33340b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 33350b57cec5SDimitry Andric /// OMPTargetExitDataDirective(SourceLocation StartLoc,SourceLocation EndLoc)3336e8d8bef9SDimitry Andric OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3337e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTargetExitDataDirectiveClass, 3338480093f4SDimitry Andric llvm::omp::OMPD_target_exit_data, StartLoc, 3339e8d8bef9SDimitry Andric EndLoc) {} 33400b57cec5SDimitry Andric 33410b57cec5SDimitry Andric /// Build an empty directive. 33420b57cec5SDimitry Andric /// OMPTargetExitDataDirective()3343e8d8bef9SDimitry Andric explicit OMPTargetExitDataDirective() 3344e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTargetExitDataDirectiveClass, 3345480093f4SDimitry Andric llvm::omp::OMPD_target_exit_data, 3346e8d8bef9SDimitry Andric SourceLocation(), SourceLocation()) {} 33470b57cec5SDimitry Andric 33480b57cec5SDimitry Andric public: 33490b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 33500b57cec5SDimitry Andric /// 33510b57cec5SDimitry Andric /// \param C AST context. 33520b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 33530b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 33540b57cec5SDimitry Andric /// \param Clauses List of clauses. 33550b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 33560b57cec5SDimitry Andric /// 33570b57cec5SDimitry Andric static OMPTargetExitDataDirective * 33580b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 33590b57cec5SDimitry Andric ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 33600b57cec5SDimitry Andric 33610b57cec5SDimitry Andric /// Creates an empty directive with the place for \a N clauses. 33620b57cec5SDimitry Andric /// 33630b57cec5SDimitry Andric /// \param C AST context. 33640b57cec5SDimitry Andric /// \param N The number of clauses. 33650b57cec5SDimitry Andric /// 33660b57cec5SDimitry Andric static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C, 33670b57cec5SDimitry Andric unsigned N, EmptyShell); 33680b57cec5SDimitry Andric classof(const Stmt * T)33690b57cec5SDimitry Andric static bool classof(const Stmt *T) { 33700b57cec5SDimitry Andric return T->getStmtClass() == OMPTargetExitDataDirectiveClass; 33710b57cec5SDimitry Andric } 33720b57cec5SDimitry Andric }; 33730b57cec5SDimitry Andric 33740b57cec5SDimitry Andric /// This represents '#pragma omp target parallel' directive. 33750b57cec5SDimitry Andric /// 33760b57cec5SDimitry Andric /// \code 33770b57cec5SDimitry Andric /// #pragma omp target parallel if(a) 33780b57cec5SDimitry Andric /// \endcode 33790b57cec5SDimitry Andric /// In this example directive '#pragma omp target parallel' has clause 'if' with 33800b57cec5SDimitry Andric /// condition 'a'. 33810b57cec5SDimitry Andric /// 33820b57cec5SDimitry Andric class OMPTargetParallelDirective : public OMPExecutableDirective { 33830b57cec5SDimitry Andric friend class ASTStmtReader; 3384e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 33855ffd83dbSDimitry Andric /// true if the construct has inner cancel directive. 33865ffd83dbSDimitry Andric bool HasCancel = false; 33875ffd83dbSDimitry Andric 33880b57cec5SDimitry Andric /// Build directive with the given start and end location. 33890b57cec5SDimitry Andric /// 33900b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 33910b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 33920b57cec5SDimitry Andric /// OMPTargetParallelDirective(SourceLocation StartLoc,SourceLocation EndLoc)3393e8d8bef9SDimitry Andric OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3394e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTargetParallelDirectiveClass, 3395480093f4SDimitry Andric llvm::omp::OMPD_target_parallel, StartLoc, 3396e8d8bef9SDimitry Andric EndLoc) {} 33970b57cec5SDimitry Andric 33980b57cec5SDimitry Andric /// Build an empty directive. 33990b57cec5SDimitry Andric /// OMPTargetParallelDirective()3400e8d8bef9SDimitry Andric explicit OMPTargetParallelDirective() 3401e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTargetParallelDirectiveClass, 3402480093f4SDimitry Andric llvm::omp::OMPD_target_parallel, 3403e8d8bef9SDimitry Andric SourceLocation(), SourceLocation()) {} 34040b57cec5SDimitry Andric 34055ffd83dbSDimitry Andric /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)3406e8d8bef9SDimitry Andric void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 34075ffd83dbSDimitry Andric /// Set cancel state. setHasCancel(bool Has)34085ffd83dbSDimitry Andric void setHasCancel(bool Has) { HasCancel = Has; } 34095ffd83dbSDimitry Andric 34100b57cec5SDimitry Andric public: 34110b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 34120b57cec5SDimitry Andric /// 34130b57cec5SDimitry Andric /// \param C AST context. 34140b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 34150b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 34160b57cec5SDimitry Andric /// \param Clauses List of clauses. 34170b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 34185ffd83dbSDimitry Andric /// \param TaskRedRef Task reduction special reference expression to handle 34195ffd83dbSDimitry Andric /// taskgroup descriptor. 34205ffd83dbSDimitry Andric /// \param HasCancel true if this directive has inner cancel directive. 34210b57cec5SDimitry Andric /// 34220b57cec5SDimitry Andric static OMPTargetParallelDirective * 34230b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 34245ffd83dbSDimitry Andric ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 34255ffd83dbSDimitry Andric bool HasCancel); 34260b57cec5SDimitry Andric 34270b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses 34280b57cec5SDimitry Andric /// clauses. 34290b57cec5SDimitry Andric /// 34300b57cec5SDimitry Andric /// \param C AST context. 34310b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 34320b57cec5SDimitry Andric /// 34330b57cec5SDimitry Andric static OMPTargetParallelDirective * 34340b57cec5SDimitry Andric CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 34350b57cec5SDimitry Andric 34365ffd83dbSDimitry Andric /// Returns special task reduction reference expression. getTaskReductionRefExpr()3437e8d8bef9SDimitry Andric Expr *getTaskReductionRefExpr() { 3438e8d8bef9SDimitry Andric return cast_or_null<Expr>(Data->getChildren()[0]); 3439e8d8bef9SDimitry Andric } getTaskReductionRefExpr()3440e8d8bef9SDimitry Andric const Expr *getTaskReductionRefExpr() const { 3441e8d8bef9SDimitry Andric return const_cast<OMPTargetParallelDirective *>(this) 3442e8d8bef9SDimitry Andric ->getTaskReductionRefExpr(); 3443e8d8bef9SDimitry Andric } 34445ffd83dbSDimitry Andric 34455ffd83dbSDimitry Andric /// Return true if current directive has inner cancel directive. hasCancel()34465ffd83dbSDimitry Andric bool hasCancel() const { return HasCancel; } 34475ffd83dbSDimitry Andric classof(const Stmt * T)34480b57cec5SDimitry Andric static bool classof(const Stmt *T) { 34490b57cec5SDimitry Andric return T->getStmtClass() == OMPTargetParallelDirectiveClass; 34500b57cec5SDimitry Andric } 34510b57cec5SDimitry Andric }; 34520b57cec5SDimitry Andric 34530b57cec5SDimitry Andric /// This represents '#pragma omp target parallel for' directive. 34540b57cec5SDimitry Andric /// 34550b57cec5SDimitry Andric /// \code 34560b57cec5SDimitry Andric /// #pragma omp target parallel for private(a,b) reduction(+:c,d) 34570b57cec5SDimitry Andric /// \endcode 34580b57cec5SDimitry Andric /// In this example directive '#pragma omp target parallel for' has clauses 34590b57cec5SDimitry Andric /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' 34600b57cec5SDimitry Andric /// and variables 'c' and 'd'. 34610b57cec5SDimitry Andric /// 34620b57cec5SDimitry Andric class OMPTargetParallelForDirective : public OMPLoopDirective { 34630b57cec5SDimitry Andric friend class ASTStmtReader; 3464e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 34650b57cec5SDimitry Andric 34660b57cec5SDimitry Andric /// true if current region has inner cancel directive. 3467e8d8bef9SDimitry Andric bool HasCancel = false; 34680b57cec5SDimitry Andric 34690b57cec5SDimitry Andric /// Build directive with the given start and end location. 34700b57cec5SDimitry Andric /// 34710b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 34720b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 34730b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 34740b57cec5SDimitry Andric /// OMPTargetParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)34750b57cec5SDimitry Andric OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3476e8d8bef9SDimitry Andric unsigned CollapsedNum) 3477e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTargetParallelForDirectiveClass, 3478480093f4SDimitry Andric llvm::omp::OMPD_target_parallel_for, StartLoc, EndLoc, 3479e8d8bef9SDimitry Andric CollapsedNum) {} 34800b57cec5SDimitry Andric 34810b57cec5SDimitry Andric /// Build an empty directive. 34820b57cec5SDimitry Andric /// 34830b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 34840b57cec5SDimitry Andric /// OMPTargetParallelForDirective(unsigned CollapsedNum)3485e8d8bef9SDimitry Andric explicit OMPTargetParallelForDirective(unsigned CollapsedNum) 3486e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTargetParallelForDirectiveClass, 3487480093f4SDimitry Andric llvm::omp::OMPD_target_parallel_for, SourceLocation(), 3488e8d8bef9SDimitry Andric SourceLocation(), CollapsedNum) {} 34890b57cec5SDimitry Andric 34905ffd83dbSDimitry Andric /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)3491e8d8bef9SDimitry Andric void setTaskReductionRefExpr(Expr *E) { 3492e8d8bef9SDimitry Andric Data->getChildren()[numLoopChildren( 3493fe6060f1SDimitry Andric getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)] = E; 3494e8d8bef9SDimitry Andric } 34955ffd83dbSDimitry Andric 34960b57cec5SDimitry Andric /// Set cancel state. setHasCancel(bool Has)34970b57cec5SDimitry Andric void setHasCancel(bool Has) { HasCancel = Has; } 34980b57cec5SDimitry Andric 34990b57cec5SDimitry Andric public: 35000b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 35010b57cec5SDimitry Andric /// 35020b57cec5SDimitry Andric /// \param C AST context. 35030b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 35040b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 35050b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 35060b57cec5SDimitry Andric /// \param Clauses List of clauses. 35070b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 35080b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 35095ffd83dbSDimitry Andric /// \param TaskRedRef Task reduction special reference expression to handle 35105ffd83dbSDimitry Andric /// taskgroup descriptor. 35110b57cec5SDimitry Andric /// \param HasCancel true if current directive has inner cancel directive. 35120b57cec5SDimitry Andric /// 35130b57cec5SDimitry Andric static OMPTargetParallelForDirective * 35140b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 35150b57cec5SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 35165ffd83dbSDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 35175ffd83dbSDimitry Andric bool HasCancel); 35180b57cec5SDimitry Andric 35190b57cec5SDimitry Andric /// Creates an empty directive with the place 35200b57cec5SDimitry Andric /// for \a NumClauses clauses. 35210b57cec5SDimitry Andric /// 35220b57cec5SDimitry Andric /// \param C AST context. 35230b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 35240b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 35250b57cec5SDimitry Andric /// 35260b57cec5SDimitry Andric static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C, 35270b57cec5SDimitry Andric unsigned NumClauses, 35280b57cec5SDimitry Andric unsigned CollapsedNum, 35290b57cec5SDimitry Andric EmptyShell); 35300b57cec5SDimitry Andric 35315ffd83dbSDimitry Andric /// Returns special task reduction reference expression. getTaskReductionRefExpr()3532e8d8bef9SDimitry Andric Expr *getTaskReductionRefExpr() { 3533e8d8bef9SDimitry Andric return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 3534fe6060f1SDimitry Andric getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)]); 3535e8d8bef9SDimitry Andric } getTaskReductionRefExpr()3536e8d8bef9SDimitry Andric const Expr *getTaskReductionRefExpr() const { 3537e8d8bef9SDimitry Andric return const_cast<OMPTargetParallelForDirective *>(this) 3538e8d8bef9SDimitry Andric ->getTaskReductionRefExpr(); 3539e8d8bef9SDimitry Andric } 35405ffd83dbSDimitry Andric 35410b57cec5SDimitry Andric /// Return true if current directive has inner cancel directive. hasCancel()35420b57cec5SDimitry Andric bool hasCancel() const { return HasCancel; } 35430b57cec5SDimitry Andric classof(const Stmt * T)35440b57cec5SDimitry Andric static bool classof(const Stmt *T) { 35450b57cec5SDimitry Andric return T->getStmtClass() == OMPTargetParallelForDirectiveClass; 35460b57cec5SDimitry Andric } 35470b57cec5SDimitry Andric }; 35480b57cec5SDimitry Andric 35490b57cec5SDimitry Andric /// This represents '#pragma omp teams' directive. 35500b57cec5SDimitry Andric /// 35510b57cec5SDimitry Andric /// \code 35520b57cec5SDimitry Andric /// #pragma omp teams if(a) 35530b57cec5SDimitry Andric /// \endcode 35540b57cec5SDimitry Andric /// In this example directive '#pragma omp teams' has clause 'if' with 35550b57cec5SDimitry Andric /// condition 'a'. 35560b57cec5SDimitry Andric /// 35570b57cec5SDimitry Andric class OMPTeamsDirective : public OMPExecutableDirective { 35580b57cec5SDimitry Andric friend class ASTStmtReader; 3559e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 35600b57cec5SDimitry Andric /// Build directive with the given start and end location. 35610b57cec5SDimitry Andric /// 35620b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 35630b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 35640b57cec5SDimitry Andric /// OMPTeamsDirective(SourceLocation StartLoc,SourceLocation EndLoc)3565e8d8bef9SDimitry Andric OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3566e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams, 3567e8d8bef9SDimitry Andric StartLoc, EndLoc) {} 35680b57cec5SDimitry Andric 35690b57cec5SDimitry Andric /// Build an empty directive. 35700b57cec5SDimitry Andric /// OMPTeamsDirective()3571e8d8bef9SDimitry Andric explicit OMPTeamsDirective() 3572e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams, 3573e8d8bef9SDimitry Andric SourceLocation(), SourceLocation()) {} 35740b57cec5SDimitry Andric 35750b57cec5SDimitry Andric public: 35760b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 35770b57cec5SDimitry Andric /// 35780b57cec5SDimitry Andric /// \param C AST context. 35790b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 35800b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 35810b57cec5SDimitry Andric /// \param Clauses List of clauses. 35820b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 35830b57cec5SDimitry Andric /// 35840b57cec5SDimitry Andric static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc, 35850b57cec5SDimitry Andric SourceLocation EndLoc, 35860b57cec5SDimitry Andric ArrayRef<OMPClause *> Clauses, 35870b57cec5SDimitry Andric Stmt *AssociatedStmt); 35880b57cec5SDimitry Andric 35890b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses 35900b57cec5SDimitry Andric /// clauses. 35910b57cec5SDimitry Andric /// 35920b57cec5SDimitry Andric /// \param C AST context. 35930b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 35940b57cec5SDimitry Andric /// 35950b57cec5SDimitry Andric static OMPTeamsDirective *CreateEmpty(const ASTContext &C, 35960b57cec5SDimitry Andric unsigned NumClauses, EmptyShell); 35970b57cec5SDimitry Andric classof(const Stmt * T)35980b57cec5SDimitry Andric static bool classof(const Stmt *T) { 35990b57cec5SDimitry Andric return T->getStmtClass() == OMPTeamsDirectiveClass; 36000b57cec5SDimitry Andric } 36010b57cec5SDimitry Andric }; 36020b57cec5SDimitry Andric 36030b57cec5SDimitry Andric /// This represents '#pragma omp cancellation point' directive. 36040b57cec5SDimitry Andric /// 36050b57cec5SDimitry Andric /// \code 36060b57cec5SDimitry Andric /// #pragma omp cancellation point for 36070b57cec5SDimitry Andric /// \endcode 36080b57cec5SDimitry Andric /// 36090b57cec5SDimitry Andric /// In this example a cancellation point is created for innermost 'for' region. 36100b57cec5SDimitry Andric class OMPCancellationPointDirective : public OMPExecutableDirective { 36110b57cec5SDimitry Andric friend class ASTStmtReader; 3612e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 3613e8d8bef9SDimitry Andric OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown; 36140b57cec5SDimitry Andric /// Build directive with the given start and end location. 36150b57cec5SDimitry Andric /// 36160b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 36170b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 3618e8d8bef9SDimitry Andric /// statements and child expressions. 36190b57cec5SDimitry Andric /// OMPCancellationPointDirective(SourceLocation StartLoc,SourceLocation EndLoc)36200b57cec5SDimitry Andric OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3621e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPCancellationPointDirectiveClass, 3622480093f4SDimitry Andric llvm::omp::OMPD_cancellation_point, StartLoc, 3623e8d8bef9SDimitry Andric EndLoc) {} 36240b57cec5SDimitry Andric 36250b57cec5SDimitry Andric /// Build an empty directive. OMPCancellationPointDirective()36260b57cec5SDimitry Andric explicit OMPCancellationPointDirective() 3627e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPCancellationPointDirectiveClass, 3628480093f4SDimitry Andric llvm::omp::OMPD_cancellation_point, 3629e8d8bef9SDimitry Andric SourceLocation(), SourceLocation()) {} 36300b57cec5SDimitry Andric 36310b57cec5SDimitry Andric /// Set cancel region for current cancellation point. 36320b57cec5SDimitry Andric /// \param CR Cancellation region. setCancelRegion(OpenMPDirectiveKind CR)36330b57cec5SDimitry Andric void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } 36340b57cec5SDimitry Andric 36350b57cec5SDimitry Andric public: 36360b57cec5SDimitry Andric /// Creates directive. 36370b57cec5SDimitry Andric /// 36380b57cec5SDimitry Andric /// \param C AST context. 36390b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 36400b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 36410b57cec5SDimitry Andric /// 36420b57cec5SDimitry Andric static OMPCancellationPointDirective * 36430b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 36440b57cec5SDimitry Andric OpenMPDirectiveKind CancelRegion); 36450b57cec5SDimitry Andric 36460b57cec5SDimitry Andric /// Creates an empty directive. 36470b57cec5SDimitry Andric /// 36480b57cec5SDimitry Andric /// \param C AST context. 36490b57cec5SDimitry Andric /// 36500b57cec5SDimitry Andric static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C, 36510b57cec5SDimitry Andric EmptyShell); 36520b57cec5SDimitry Andric 36530b57cec5SDimitry Andric /// Get cancellation region for the current cancellation point. getCancelRegion()36540b57cec5SDimitry Andric OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } 36550b57cec5SDimitry Andric classof(const Stmt * T)36560b57cec5SDimitry Andric static bool classof(const Stmt *T) { 36570b57cec5SDimitry Andric return T->getStmtClass() == OMPCancellationPointDirectiveClass; 36580b57cec5SDimitry Andric } 36590b57cec5SDimitry Andric }; 36600b57cec5SDimitry Andric 36610b57cec5SDimitry Andric /// This represents '#pragma omp cancel' directive. 36620b57cec5SDimitry Andric /// 36630b57cec5SDimitry Andric /// \code 36640b57cec5SDimitry Andric /// #pragma omp cancel for 36650b57cec5SDimitry Andric /// \endcode 36660b57cec5SDimitry Andric /// 36670b57cec5SDimitry Andric /// In this example a cancel is created for innermost 'for' region. 36680b57cec5SDimitry Andric class OMPCancelDirective : public OMPExecutableDirective { 36690b57cec5SDimitry Andric friend class ASTStmtReader; 3670e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 3671e8d8bef9SDimitry Andric OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown; 36720b57cec5SDimitry Andric /// Build directive with the given start and end location. 36730b57cec5SDimitry Andric /// 36740b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 36750b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 36760b57cec5SDimitry Andric /// OMPCancelDirective(SourceLocation StartLoc,SourceLocation EndLoc)3677e8d8bef9SDimitry Andric OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3678e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel, 3679e8d8bef9SDimitry Andric StartLoc, EndLoc) {} 36800b57cec5SDimitry Andric 36810b57cec5SDimitry Andric /// Build an empty directive. 36820b57cec5SDimitry Andric /// OMPCancelDirective()3683e8d8bef9SDimitry Andric explicit OMPCancelDirective() 3684e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel, 3685e8d8bef9SDimitry Andric SourceLocation(), SourceLocation()) {} 36860b57cec5SDimitry Andric 36870b57cec5SDimitry Andric /// Set cancel region for current cancellation point. 36880b57cec5SDimitry Andric /// \param CR Cancellation region. setCancelRegion(OpenMPDirectiveKind CR)36890b57cec5SDimitry Andric void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } 36900b57cec5SDimitry Andric 36910b57cec5SDimitry Andric public: 36920b57cec5SDimitry Andric /// Creates directive. 36930b57cec5SDimitry Andric /// 36940b57cec5SDimitry Andric /// \param C AST context. 36950b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 36960b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 36970b57cec5SDimitry Andric /// \param Clauses List of clauses. 36980b57cec5SDimitry Andric /// 36990b57cec5SDimitry Andric static OMPCancelDirective * 37000b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 37010b57cec5SDimitry Andric ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion); 37020b57cec5SDimitry Andric 37030b57cec5SDimitry Andric /// Creates an empty directive. 37040b57cec5SDimitry Andric /// 37050b57cec5SDimitry Andric /// \param C AST context. 37060b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 37070b57cec5SDimitry Andric /// 37080b57cec5SDimitry Andric static OMPCancelDirective *CreateEmpty(const ASTContext &C, 37090b57cec5SDimitry Andric unsigned NumClauses, EmptyShell); 37100b57cec5SDimitry Andric 37110b57cec5SDimitry Andric /// Get cancellation region for the current cancellation point. getCancelRegion()37120b57cec5SDimitry Andric OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } 37130b57cec5SDimitry Andric classof(const Stmt * T)37140b57cec5SDimitry Andric static bool classof(const Stmt *T) { 37150b57cec5SDimitry Andric return T->getStmtClass() == OMPCancelDirectiveClass; 37160b57cec5SDimitry Andric } 37170b57cec5SDimitry Andric }; 37180b57cec5SDimitry Andric 37190b57cec5SDimitry Andric /// This represents '#pragma omp taskloop' directive. 37200b57cec5SDimitry Andric /// 37210b57cec5SDimitry Andric /// \code 37220b57cec5SDimitry Andric /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num) 37230b57cec5SDimitry Andric /// \endcode 37240b57cec5SDimitry Andric /// In this example directive '#pragma omp taskloop' has clauses 'private' 37250b57cec5SDimitry Andric /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and 37260b57cec5SDimitry Andric /// 'num_tasks' with expression 'num'. 37270b57cec5SDimitry Andric /// 37280b57cec5SDimitry Andric class OMPTaskLoopDirective : public OMPLoopDirective { 37290b57cec5SDimitry Andric friend class ASTStmtReader; 3730e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 37315ffd83dbSDimitry Andric /// true if the construct has inner cancel directive. 3732e8d8bef9SDimitry Andric bool HasCancel = false; 37335ffd83dbSDimitry Andric 37340b57cec5SDimitry Andric /// Build directive with the given start and end location. 37350b57cec5SDimitry Andric /// 37360b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 37370b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 37380b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 37390b57cec5SDimitry Andric /// OMPTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)37400b57cec5SDimitry Andric OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3741e8d8bef9SDimitry Andric unsigned CollapsedNum) 3742e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop, 3743e8d8bef9SDimitry Andric StartLoc, EndLoc, CollapsedNum) {} 37440b57cec5SDimitry Andric 37450b57cec5SDimitry Andric /// Build an empty directive. 37460b57cec5SDimitry Andric /// 37470b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 37480b57cec5SDimitry Andric /// OMPTaskLoopDirective(unsigned CollapsedNum)3749e8d8bef9SDimitry Andric explicit OMPTaskLoopDirective(unsigned CollapsedNum) 3750e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop, 3751e8d8bef9SDimitry Andric SourceLocation(), SourceLocation(), CollapsedNum) {} 37525ffd83dbSDimitry Andric 37535ffd83dbSDimitry Andric /// Set cancel state. setHasCancel(bool Has)37545ffd83dbSDimitry Andric void setHasCancel(bool Has) { HasCancel = Has; } 37550b57cec5SDimitry Andric 37560b57cec5SDimitry Andric public: 37570b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 37580b57cec5SDimitry Andric /// 37590b57cec5SDimitry Andric /// \param C AST context. 37600b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 37610b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 37620b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 37630b57cec5SDimitry Andric /// \param Clauses List of clauses. 37640b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 37650b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 37665ffd83dbSDimitry Andric /// \param HasCancel true if this directive has inner cancel directive. 37670b57cec5SDimitry Andric /// 37680b57cec5SDimitry Andric static OMPTaskLoopDirective * 37690b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 37700b57cec5SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 37715ffd83dbSDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 37720b57cec5SDimitry Andric 37730b57cec5SDimitry Andric /// Creates an empty directive with the place 37740b57cec5SDimitry Andric /// for \a NumClauses clauses. 37750b57cec5SDimitry Andric /// 37760b57cec5SDimitry Andric /// \param C AST context. 37770b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 37780b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 37790b57cec5SDimitry Andric /// 37800b57cec5SDimitry Andric static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C, 37810b57cec5SDimitry Andric unsigned NumClauses, 37820b57cec5SDimitry Andric unsigned CollapsedNum, EmptyShell); 37830b57cec5SDimitry Andric 37845ffd83dbSDimitry Andric /// Return true if current directive has inner cancel directive. hasCancel()37855ffd83dbSDimitry Andric bool hasCancel() const { return HasCancel; } 37865ffd83dbSDimitry Andric classof(const Stmt * T)37870b57cec5SDimitry Andric static bool classof(const Stmt *T) { 37880b57cec5SDimitry Andric return T->getStmtClass() == OMPTaskLoopDirectiveClass; 37890b57cec5SDimitry Andric } 37900b57cec5SDimitry Andric }; 37910b57cec5SDimitry Andric 37920b57cec5SDimitry Andric /// This represents '#pragma omp taskloop simd' directive. 37930b57cec5SDimitry Andric /// 37940b57cec5SDimitry Andric /// \code 37950b57cec5SDimitry Andric /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num) 37960b57cec5SDimitry Andric /// \endcode 37970b57cec5SDimitry Andric /// In this example directive '#pragma omp taskloop simd' has clauses 'private' 37980b57cec5SDimitry Andric /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and 37990b57cec5SDimitry Andric /// 'num_tasks' with expression 'num'. 38000b57cec5SDimitry Andric /// 38010b57cec5SDimitry Andric class OMPTaskLoopSimdDirective : public OMPLoopDirective { 38020b57cec5SDimitry Andric friend class ASTStmtReader; 3803e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 38040b57cec5SDimitry Andric /// Build directive with the given start and end location. 38050b57cec5SDimitry Andric /// 38060b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 38070b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 38080b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 38090b57cec5SDimitry Andric /// OMPTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)38100b57cec5SDimitry Andric OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3811e8d8bef9SDimitry Andric unsigned CollapsedNum) 3812e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass, 3813480093f4SDimitry Andric llvm::omp::OMPD_taskloop_simd, StartLoc, EndLoc, 3814e8d8bef9SDimitry Andric CollapsedNum) {} 38150b57cec5SDimitry Andric 38160b57cec5SDimitry Andric /// Build an empty directive. 38170b57cec5SDimitry Andric /// 38180b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 38190b57cec5SDimitry Andric /// OMPTaskLoopSimdDirective(unsigned CollapsedNum)3820e8d8bef9SDimitry Andric explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum) 3821e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass, 3822480093f4SDimitry Andric llvm::omp::OMPD_taskloop_simd, SourceLocation(), 3823e8d8bef9SDimitry Andric SourceLocation(), CollapsedNum) {} 38240b57cec5SDimitry Andric 38250b57cec5SDimitry Andric public: 38260b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 38270b57cec5SDimitry Andric /// 38280b57cec5SDimitry Andric /// \param C AST context. 38290b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 38300b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 38310b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 38320b57cec5SDimitry Andric /// \param Clauses List of clauses. 38330b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 38340b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 38350b57cec5SDimitry Andric /// 38360b57cec5SDimitry Andric static OMPTaskLoopSimdDirective * 38370b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 38380b57cec5SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 38390b57cec5SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 38400b57cec5SDimitry Andric 38410b57cec5SDimitry Andric /// Creates an empty directive with the place 38420b57cec5SDimitry Andric /// for \a NumClauses clauses. 38430b57cec5SDimitry Andric /// 38440b57cec5SDimitry Andric /// \param C AST context. 38450b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 38460b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 38470b57cec5SDimitry Andric /// 38480b57cec5SDimitry Andric static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, 38490b57cec5SDimitry Andric unsigned NumClauses, 38500b57cec5SDimitry Andric unsigned CollapsedNum, 38510b57cec5SDimitry Andric EmptyShell); 38520b57cec5SDimitry Andric classof(const Stmt * T)38530b57cec5SDimitry Andric static bool classof(const Stmt *T) { 38540b57cec5SDimitry Andric return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass; 38550b57cec5SDimitry Andric } 38560b57cec5SDimitry Andric }; 38570b57cec5SDimitry Andric 3858a7dea167SDimitry Andric /// This represents '#pragma omp master taskloop' directive. 3859a7dea167SDimitry Andric /// 3860a7dea167SDimitry Andric /// \code 3861a7dea167SDimitry Andric /// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num) 3862a7dea167SDimitry Andric /// \endcode 3863a7dea167SDimitry Andric /// In this example directive '#pragma omp master taskloop' has clauses 3864a7dea167SDimitry Andric /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 3865a7dea167SDimitry Andric /// and 'num_tasks' with expression 'num'. 3866a7dea167SDimitry Andric /// 3867a7dea167SDimitry Andric class OMPMasterTaskLoopDirective : public OMPLoopDirective { 3868a7dea167SDimitry Andric friend class ASTStmtReader; 3869e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 38705ffd83dbSDimitry Andric /// true if the construct has inner cancel directive. 3871e8d8bef9SDimitry Andric bool HasCancel = false; 38725ffd83dbSDimitry Andric 3873a7dea167SDimitry Andric /// Build directive with the given start and end location. 3874a7dea167SDimitry Andric /// 3875a7dea167SDimitry Andric /// \param StartLoc Starting location of the directive kind. 3876a7dea167SDimitry Andric /// \param EndLoc Ending location of the directive. 3877a7dea167SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 3878a7dea167SDimitry Andric /// OMPMasterTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)3879a7dea167SDimitry Andric OMPMasterTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3880e8d8bef9SDimitry Andric unsigned CollapsedNum) 3881e8d8bef9SDimitry Andric : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass, 3882480093f4SDimitry Andric llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc, 3883e8d8bef9SDimitry Andric CollapsedNum) {} 3884a7dea167SDimitry Andric 3885a7dea167SDimitry Andric /// Build an empty directive. 3886a7dea167SDimitry Andric /// 3887a7dea167SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 3888a7dea167SDimitry Andric /// OMPMasterTaskLoopDirective(unsigned CollapsedNum)3889e8d8bef9SDimitry Andric explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum) 3890e8d8bef9SDimitry Andric : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass, 3891480093f4SDimitry Andric llvm::omp::OMPD_master_taskloop, SourceLocation(), 3892e8d8bef9SDimitry Andric SourceLocation(), CollapsedNum) {} 38935ffd83dbSDimitry Andric 38945ffd83dbSDimitry Andric /// Set cancel state. setHasCancel(bool Has)38955ffd83dbSDimitry Andric void setHasCancel(bool Has) { HasCancel = Has; } 3896a7dea167SDimitry Andric 3897a7dea167SDimitry Andric public: 3898a7dea167SDimitry Andric /// Creates directive with a list of \a Clauses. 3899a7dea167SDimitry Andric /// 3900a7dea167SDimitry Andric /// \param C AST context. 3901a7dea167SDimitry Andric /// \param StartLoc Starting location of the directive kind. 3902a7dea167SDimitry Andric /// \param EndLoc Ending Location of the directive. 3903a7dea167SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 3904a7dea167SDimitry Andric /// \param Clauses List of clauses. 3905a7dea167SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 3906a7dea167SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 39075ffd83dbSDimitry Andric /// \param HasCancel true if this directive has inner cancel directive. 3908a7dea167SDimitry Andric /// 3909a7dea167SDimitry Andric static OMPMasterTaskLoopDirective * 3910a7dea167SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3911a7dea167SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 39125ffd83dbSDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 3913a7dea167SDimitry Andric 3914a7dea167SDimitry Andric /// Creates an empty directive with the place 3915a7dea167SDimitry Andric /// for \a NumClauses clauses. 3916a7dea167SDimitry Andric /// 3917a7dea167SDimitry Andric /// \param C AST context. 3918a7dea167SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 3919a7dea167SDimitry Andric /// \param NumClauses Number of clauses. 3920a7dea167SDimitry Andric /// 3921a7dea167SDimitry Andric static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C, 3922a7dea167SDimitry Andric unsigned NumClauses, 3923a7dea167SDimitry Andric unsigned CollapsedNum, 3924a7dea167SDimitry Andric EmptyShell); 3925a7dea167SDimitry Andric 39265ffd83dbSDimitry Andric /// Return true if current directive has inner cancel directive. hasCancel()39275ffd83dbSDimitry Andric bool hasCancel() const { return HasCancel; } 39285ffd83dbSDimitry Andric classof(const Stmt * T)3929a7dea167SDimitry Andric static bool classof(const Stmt *T) { 3930a7dea167SDimitry Andric return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass; 3931a7dea167SDimitry Andric } 3932a7dea167SDimitry Andric }; 3933a7dea167SDimitry Andric 393481ad6265SDimitry Andric /// This represents '#pragma omp masked taskloop' directive. 393581ad6265SDimitry Andric /// 393681ad6265SDimitry Andric /// \code 393781ad6265SDimitry Andric /// #pragma omp masked taskloop private(a,b) grainsize(val) num_tasks(num) 393881ad6265SDimitry Andric /// \endcode 393981ad6265SDimitry Andric /// In this example directive '#pragma omp masked taskloop' has clauses 394081ad6265SDimitry Andric /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 394181ad6265SDimitry Andric /// and 'num_tasks' with expression 'num'. 394281ad6265SDimitry Andric /// 394381ad6265SDimitry Andric class OMPMaskedTaskLoopDirective final : public OMPLoopDirective { 394481ad6265SDimitry Andric friend class ASTStmtReader; 394581ad6265SDimitry Andric friend class OMPExecutableDirective; 394681ad6265SDimitry Andric /// true if the construct has inner cancel directive. 394781ad6265SDimitry Andric bool HasCancel = false; 394881ad6265SDimitry Andric 394981ad6265SDimitry Andric /// Build directive with the given start and end location. 395081ad6265SDimitry Andric /// 395181ad6265SDimitry Andric /// \param StartLoc Starting location of the directive kind. 395281ad6265SDimitry Andric /// \param EndLoc Ending location of the directive. 395381ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 395481ad6265SDimitry Andric /// OMPMaskedTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)395581ad6265SDimitry Andric OMPMaskedTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 395681ad6265SDimitry Andric unsigned CollapsedNum) 395781ad6265SDimitry Andric : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass, 395881ad6265SDimitry Andric llvm::omp::OMPD_masked_taskloop, StartLoc, EndLoc, 395981ad6265SDimitry Andric CollapsedNum) {} 396081ad6265SDimitry Andric 396181ad6265SDimitry Andric /// Build an empty directive. 396281ad6265SDimitry Andric /// 396381ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 396481ad6265SDimitry Andric /// OMPMaskedTaskLoopDirective(unsigned CollapsedNum)396581ad6265SDimitry Andric explicit OMPMaskedTaskLoopDirective(unsigned CollapsedNum) 396681ad6265SDimitry Andric : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass, 396781ad6265SDimitry Andric llvm::omp::OMPD_masked_taskloop, SourceLocation(), 396881ad6265SDimitry Andric SourceLocation(), CollapsedNum) {} 396981ad6265SDimitry Andric 397081ad6265SDimitry Andric /// Set cancel state. setHasCancel(bool Has)397181ad6265SDimitry Andric void setHasCancel(bool Has) { HasCancel = Has; } 397281ad6265SDimitry Andric 397381ad6265SDimitry Andric public: 397481ad6265SDimitry Andric /// Creates directive with a list of \a Clauses. 397581ad6265SDimitry Andric /// 397681ad6265SDimitry Andric /// \param C AST context. 397781ad6265SDimitry Andric /// \param StartLoc Starting location of the directive kind. 397881ad6265SDimitry Andric /// \param EndLoc Ending Location of the directive. 397981ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 398081ad6265SDimitry Andric /// \param Clauses List of clauses. 398181ad6265SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 398281ad6265SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 398381ad6265SDimitry Andric /// \param HasCancel true if this directive has inner cancel directive. 398481ad6265SDimitry Andric /// 398581ad6265SDimitry Andric static OMPMaskedTaskLoopDirective * 398681ad6265SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 398781ad6265SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 398881ad6265SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 398981ad6265SDimitry Andric 399081ad6265SDimitry Andric /// Creates an empty directive with the place 399181ad6265SDimitry Andric /// for \a NumClauses clauses. 399281ad6265SDimitry Andric /// 399381ad6265SDimitry Andric /// \param C AST context. 399481ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 399581ad6265SDimitry Andric /// \param NumClauses Number of clauses. 399681ad6265SDimitry Andric /// 399781ad6265SDimitry Andric static OMPMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C, 399881ad6265SDimitry Andric unsigned NumClauses, 399981ad6265SDimitry Andric unsigned CollapsedNum, 400081ad6265SDimitry Andric EmptyShell); 400181ad6265SDimitry Andric 400281ad6265SDimitry Andric /// Return true if current directive has inner cancel directive. hasCancel()400381ad6265SDimitry Andric bool hasCancel() const { return HasCancel; } 400481ad6265SDimitry Andric classof(const Stmt * T)400581ad6265SDimitry Andric static bool classof(const Stmt *T) { 400681ad6265SDimitry Andric return T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass; 400781ad6265SDimitry Andric } 400881ad6265SDimitry Andric }; 400981ad6265SDimitry Andric 4010a7dea167SDimitry Andric /// This represents '#pragma omp master taskloop simd' directive. 4011a7dea167SDimitry Andric /// 4012a7dea167SDimitry Andric /// \code 4013a7dea167SDimitry Andric /// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num) 4014a7dea167SDimitry Andric /// \endcode 4015a7dea167SDimitry Andric /// In this example directive '#pragma omp master taskloop simd' has clauses 4016a7dea167SDimitry Andric /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 4017a7dea167SDimitry Andric /// and 'num_tasks' with expression 'num'. 4018a7dea167SDimitry Andric /// 4019a7dea167SDimitry Andric class OMPMasterTaskLoopSimdDirective : public OMPLoopDirective { 4020a7dea167SDimitry Andric friend class ASTStmtReader; 4021e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 4022a7dea167SDimitry Andric /// Build directive with the given start and end location. 4023a7dea167SDimitry Andric /// 4024a7dea167SDimitry Andric /// \param StartLoc Starting location of the directive kind. 4025a7dea167SDimitry Andric /// \param EndLoc Ending location of the directive. 4026a7dea167SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 4027a7dea167SDimitry Andric /// OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4028a7dea167SDimitry Andric OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4029e8d8bef9SDimitry Andric unsigned CollapsedNum) 4030e8d8bef9SDimitry Andric : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass, 4031480093f4SDimitry Andric llvm::omp::OMPD_master_taskloop_simd, StartLoc, EndLoc, 4032e8d8bef9SDimitry Andric CollapsedNum) {} 4033a7dea167SDimitry Andric 4034a7dea167SDimitry Andric /// Build an empty directive. 4035a7dea167SDimitry Andric /// 4036a7dea167SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 4037a7dea167SDimitry Andric /// OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum)4038e8d8bef9SDimitry Andric explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum) 4039e8d8bef9SDimitry Andric : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass, 4040480093f4SDimitry Andric llvm::omp::OMPD_master_taskloop_simd, SourceLocation(), 4041e8d8bef9SDimitry Andric SourceLocation(), CollapsedNum) {} 4042a7dea167SDimitry Andric 4043a7dea167SDimitry Andric public: 4044a7dea167SDimitry Andric /// Creates directive with a list of \p Clauses. 4045a7dea167SDimitry Andric /// 4046a7dea167SDimitry Andric /// \param C AST context. 4047a7dea167SDimitry Andric /// \param StartLoc Starting location of the directive kind. 4048a7dea167SDimitry Andric /// \param EndLoc Ending Location of the directive. 4049a7dea167SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 4050a7dea167SDimitry Andric /// \param Clauses List of clauses. 4051a7dea167SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 4052a7dea167SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 4053a7dea167SDimitry Andric /// 4054a7dea167SDimitry Andric static OMPMasterTaskLoopSimdDirective * 4055a7dea167SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4056a7dea167SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4057a7dea167SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 4058a7dea167SDimitry Andric 4059a7dea167SDimitry Andric /// Creates an empty directive with the place for \p NumClauses clauses. 4060a7dea167SDimitry Andric /// 4061a7dea167SDimitry Andric /// \param C AST context. 4062a7dea167SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 4063a7dea167SDimitry Andric /// \param NumClauses Number of clauses. 4064a7dea167SDimitry Andric /// 4065a7dea167SDimitry Andric static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, 4066a7dea167SDimitry Andric unsigned NumClauses, 4067a7dea167SDimitry Andric unsigned CollapsedNum, 4068a7dea167SDimitry Andric EmptyShell); 4069a7dea167SDimitry Andric classof(const Stmt * T)4070a7dea167SDimitry Andric static bool classof(const Stmt *T) { 4071a7dea167SDimitry Andric return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass; 4072a7dea167SDimitry Andric } 4073a7dea167SDimitry Andric }; 4074a7dea167SDimitry Andric 407581ad6265SDimitry Andric /// This represents '#pragma omp masked taskloop simd' directive. 407681ad6265SDimitry Andric /// 407781ad6265SDimitry Andric /// \code 407881ad6265SDimitry Andric /// #pragma omp masked taskloop simd private(a,b) grainsize(val) num_tasks(num) 407981ad6265SDimitry Andric /// \endcode 408081ad6265SDimitry Andric /// In this example directive '#pragma omp masked taskloop simd' has clauses 408181ad6265SDimitry Andric /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 408281ad6265SDimitry Andric /// and 'num_tasks' with expression 'num'. 408381ad6265SDimitry Andric /// 408481ad6265SDimitry Andric class OMPMaskedTaskLoopSimdDirective final : public OMPLoopDirective { 408581ad6265SDimitry Andric friend class ASTStmtReader; 408681ad6265SDimitry Andric friend class OMPExecutableDirective; 408781ad6265SDimitry Andric /// Build directive with the given start and end location. 408881ad6265SDimitry Andric /// 408981ad6265SDimitry Andric /// \param StartLoc Starting location of the directive kind. 409081ad6265SDimitry Andric /// \param EndLoc Ending location of the directive. 409181ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 409281ad6265SDimitry Andric /// OMPMaskedTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)409381ad6265SDimitry Andric OMPMaskedTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 409481ad6265SDimitry Andric unsigned CollapsedNum) 409581ad6265SDimitry Andric : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass, 409681ad6265SDimitry Andric llvm::omp::OMPD_masked_taskloop_simd, StartLoc, EndLoc, 409781ad6265SDimitry Andric CollapsedNum) {} 409881ad6265SDimitry Andric 409981ad6265SDimitry Andric /// Build an empty directive. 410081ad6265SDimitry Andric /// 410181ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 410281ad6265SDimitry Andric /// OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum)410381ad6265SDimitry Andric explicit OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum) 410481ad6265SDimitry Andric : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass, 410581ad6265SDimitry Andric llvm::omp::OMPD_masked_taskloop_simd, SourceLocation(), 410681ad6265SDimitry Andric SourceLocation(), CollapsedNum) {} 410781ad6265SDimitry Andric 410881ad6265SDimitry Andric public: 410981ad6265SDimitry Andric /// Creates directive with a list of \p Clauses. 411081ad6265SDimitry Andric /// 411181ad6265SDimitry Andric /// \param C AST context. 411281ad6265SDimitry Andric /// \param StartLoc Starting location of the directive kind. 411381ad6265SDimitry Andric /// \param EndLoc Ending Location of the directive. 411481ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 411581ad6265SDimitry Andric /// \param Clauses List of clauses. 411681ad6265SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 411781ad6265SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 411881ad6265SDimitry Andric /// 411981ad6265SDimitry Andric static OMPMaskedTaskLoopSimdDirective * 412081ad6265SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 412181ad6265SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 412281ad6265SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 412381ad6265SDimitry Andric 412481ad6265SDimitry Andric /// Creates an empty directive with the place for \p NumClauses clauses. 412581ad6265SDimitry Andric /// 412681ad6265SDimitry Andric /// \param C AST context. 412781ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 412881ad6265SDimitry Andric /// \param NumClauses Number of clauses. 412981ad6265SDimitry Andric /// 413081ad6265SDimitry Andric static OMPMaskedTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, 413181ad6265SDimitry Andric unsigned NumClauses, 413281ad6265SDimitry Andric unsigned CollapsedNum, 413381ad6265SDimitry Andric EmptyShell); 413481ad6265SDimitry Andric classof(const Stmt * T)413581ad6265SDimitry Andric static bool classof(const Stmt *T) { 413681ad6265SDimitry Andric return T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass; 413781ad6265SDimitry Andric } 413881ad6265SDimitry Andric }; 413981ad6265SDimitry Andric 4140a7dea167SDimitry Andric /// This represents '#pragma omp parallel master taskloop' directive. 4141a7dea167SDimitry Andric /// 4142a7dea167SDimitry Andric /// \code 4143a7dea167SDimitry Andric /// #pragma omp parallel master taskloop private(a,b) grainsize(val) 4144a7dea167SDimitry Andric /// num_tasks(num) 4145a7dea167SDimitry Andric /// \endcode 4146a7dea167SDimitry Andric /// In this example directive '#pragma omp parallel master taskloop' has clauses 4147a7dea167SDimitry Andric /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 4148a7dea167SDimitry Andric /// and 'num_tasks' with expression 'num'. 4149a7dea167SDimitry Andric /// 4150a7dea167SDimitry Andric class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective { 4151a7dea167SDimitry Andric friend class ASTStmtReader; 4152e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 41535ffd83dbSDimitry Andric /// true if the construct has inner cancel directive. 4154e8d8bef9SDimitry Andric bool HasCancel = false; 41555ffd83dbSDimitry Andric 4156a7dea167SDimitry Andric /// Build directive with the given start and end location. 4157a7dea167SDimitry Andric /// 4158a7dea167SDimitry Andric /// \param StartLoc Starting location of the directive kind. 4159a7dea167SDimitry Andric /// \param EndLoc Ending location of the directive. 4160a7dea167SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 4161a7dea167SDimitry Andric /// OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4162a7dea167SDimitry Andric OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc, 4163a7dea167SDimitry Andric SourceLocation EndLoc, 4164e8d8bef9SDimitry Andric unsigned CollapsedNum) 4165e8d8bef9SDimitry Andric : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass, 4166480093f4SDimitry Andric llvm::omp::OMPD_parallel_master_taskloop, StartLoc, 4167e8d8bef9SDimitry Andric EndLoc, CollapsedNum) {} 4168a7dea167SDimitry Andric 4169a7dea167SDimitry Andric /// Build an empty directive. 4170a7dea167SDimitry Andric /// 4171a7dea167SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 4172a7dea167SDimitry Andric /// OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum)4173e8d8bef9SDimitry Andric explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum) 4174e8d8bef9SDimitry Andric : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass, 4175480093f4SDimitry Andric llvm::omp::OMPD_parallel_master_taskloop, 4176e8d8bef9SDimitry Andric SourceLocation(), SourceLocation(), CollapsedNum) {} 41775ffd83dbSDimitry Andric 41785ffd83dbSDimitry Andric /// Set cancel state. setHasCancel(bool Has)41795ffd83dbSDimitry Andric void setHasCancel(bool Has) { HasCancel = Has; } 4180a7dea167SDimitry Andric 4181a7dea167SDimitry Andric public: 4182a7dea167SDimitry Andric /// Creates directive with a list of \a Clauses. 4183a7dea167SDimitry Andric /// 4184a7dea167SDimitry Andric /// \param C AST context. 4185a7dea167SDimitry Andric /// \param StartLoc Starting location of the directive kind. 4186a7dea167SDimitry Andric /// \param EndLoc Ending Location of the directive. 4187a7dea167SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 4188a7dea167SDimitry Andric /// \param Clauses List of clauses. 4189a7dea167SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 4190a7dea167SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 41915ffd83dbSDimitry Andric /// \param HasCancel true if this directive has inner cancel directive. 4192a7dea167SDimitry Andric /// 4193a7dea167SDimitry Andric static OMPParallelMasterTaskLoopDirective * 4194a7dea167SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4195a7dea167SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 41965ffd83dbSDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 4197a7dea167SDimitry Andric 4198a7dea167SDimitry Andric /// Creates an empty directive with the place 4199a7dea167SDimitry Andric /// for \a NumClauses clauses. 4200a7dea167SDimitry Andric /// 4201a7dea167SDimitry Andric /// \param C AST context. 4202a7dea167SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 4203a7dea167SDimitry Andric /// \param NumClauses Number of clauses. 4204a7dea167SDimitry Andric /// 4205a7dea167SDimitry Andric static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C, 4206a7dea167SDimitry Andric unsigned NumClauses, 4207a7dea167SDimitry Andric unsigned CollapsedNum, 4208a7dea167SDimitry Andric EmptyShell); 4209a7dea167SDimitry Andric 42105ffd83dbSDimitry Andric /// Return true if current directive has inner cancel directive. hasCancel()42115ffd83dbSDimitry Andric bool hasCancel() const { return HasCancel; } 42125ffd83dbSDimitry Andric classof(const Stmt * T)4213a7dea167SDimitry Andric static bool classof(const Stmt *T) { 4214a7dea167SDimitry Andric return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass; 4215a7dea167SDimitry Andric } 4216a7dea167SDimitry Andric }; 4217a7dea167SDimitry Andric 421881ad6265SDimitry Andric /// This represents '#pragma omp parallel masked taskloop' directive. 421981ad6265SDimitry Andric /// 422081ad6265SDimitry Andric /// \code 422181ad6265SDimitry Andric /// #pragma omp parallel masked taskloop private(a,b) grainsize(val) 422281ad6265SDimitry Andric /// num_tasks(num) 422381ad6265SDimitry Andric /// \endcode 422481ad6265SDimitry Andric /// In this example directive '#pragma omp parallel masked taskloop' has clauses 422581ad6265SDimitry Andric /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 422681ad6265SDimitry Andric /// and 'num_tasks' with expression 'num'. 422781ad6265SDimitry Andric /// 422881ad6265SDimitry Andric class OMPParallelMaskedTaskLoopDirective final : public OMPLoopDirective { 422981ad6265SDimitry Andric friend class ASTStmtReader; 423081ad6265SDimitry Andric friend class OMPExecutableDirective; 423181ad6265SDimitry Andric /// true if the construct has inner cancel directive. 423281ad6265SDimitry Andric bool HasCancel = false; 423381ad6265SDimitry Andric 423481ad6265SDimitry Andric /// Build directive with the given start and end location. 423581ad6265SDimitry Andric /// 423681ad6265SDimitry Andric /// \param StartLoc Starting location of the directive kind. 423781ad6265SDimitry Andric /// \param EndLoc Ending location of the directive. 423881ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 423981ad6265SDimitry Andric /// OMPParallelMaskedTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)424081ad6265SDimitry Andric OMPParallelMaskedTaskLoopDirective(SourceLocation StartLoc, 424181ad6265SDimitry Andric SourceLocation EndLoc, 424281ad6265SDimitry Andric unsigned CollapsedNum) 424381ad6265SDimitry Andric : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass, 424481ad6265SDimitry Andric llvm::omp::OMPD_parallel_masked_taskloop, StartLoc, 424581ad6265SDimitry Andric EndLoc, CollapsedNum) {} 424681ad6265SDimitry Andric 424781ad6265SDimitry Andric /// Build an empty directive. 424881ad6265SDimitry Andric /// 424981ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 425081ad6265SDimitry Andric /// OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum)425181ad6265SDimitry Andric explicit OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum) 425281ad6265SDimitry Andric : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass, 425381ad6265SDimitry Andric llvm::omp::OMPD_parallel_masked_taskloop, 425481ad6265SDimitry Andric SourceLocation(), SourceLocation(), CollapsedNum) {} 425581ad6265SDimitry Andric 425681ad6265SDimitry Andric /// Set cancel state. setHasCancel(bool Has)425781ad6265SDimitry Andric void setHasCancel(bool Has) { HasCancel = Has; } 425881ad6265SDimitry Andric 425981ad6265SDimitry Andric public: 426081ad6265SDimitry Andric /// Creates directive with a list of \a Clauses. 426181ad6265SDimitry Andric /// 426281ad6265SDimitry Andric /// \param C AST context. 426381ad6265SDimitry Andric /// \param StartLoc Starting location of the directive kind. 426481ad6265SDimitry Andric /// \param EndLoc Ending Location of the directive. 426581ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 426681ad6265SDimitry Andric /// \param Clauses List of clauses. 426781ad6265SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 426881ad6265SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 426981ad6265SDimitry Andric /// \param HasCancel true if this directive has inner cancel directive. 427081ad6265SDimitry Andric /// 427181ad6265SDimitry Andric static OMPParallelMaskedTaskLoopDirective * 427281ad6265SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 427381ad6265SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 427481ad6265SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 427581ad6265SDimitry Andric 427681ad6265SDimitry Andric /// Creates an empty directive with the place 427781ad6265SDimitry Andric /// for \a NumClauses clauses. 427881ad6265SDimitry Andric /// 427981ad6265SDimitry Andric /// \param C AST context. 428081ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 428181ad6265SDimitry Andric /// \param NumClauses Number of clauses. 428281ad6265SDimitry Andric /// 428381ad6265SDimitry Andric static OMPParallelMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C, 428481ad6265SDimitry Andric unsigned NumClauses, 428581ad6265SDimitry Andric unsigned CollapsedNum, 428681ad6265SDimitry Andric EmptyShell); 428781ad6265SDimitry Andric 428881ad6265SDimitry Andric /// Return true if current directive has inner cancel directive. hasCancel()428981ad6265SDimitry Andric bool hasCancel() const { return HasCancel; } 429081ad6265SDimitry Andric classof(const Stmt * T)429181ad6265SDimitry Andric static bool classof(const Stmt *T) { 429281ad6265SDimitry Andric return T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass; 429381ad6265SDimitry Andric } 429481ad6265SDimitry Andric }; 429581ad6265SDimitry Andric 4296480093f4SDimitry Andric /// This represents '#pragma omp parallel master taskloop simd' directive. 4297480093f4SDimitry Andric /// 4298480093f4SDimitry Andric /// \code 4299480093f4SDimitry Andric /// #pragma omp parallel master taskloop simd private(a,b) grainsize(val) 4300480093f4SDimitry Andric /// num_tasks(num) 4301480093f4SDimitry Andric /// \endcode 4302480093f4SDimitry Andric /// In this example directive '#pragma omp parallel master taskloop simd' has 4303480093f4SDimitry Andric /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with 4304480093f4SDimitry Andric /// expression 'val' and 'num_tasks' with expression 'num'. 4305480093f4SDimitry Andric /// 4306480093f4SDimitry Andric class OMPParallelMasterTaskLoopSimdDirective : public OMPLoopDirective { 4307480093f4SDimitry Andric friend class ASTStmtReader; 4308e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 4309480093f4SDimitry Andric /// Build directive with the given start and end location. 4310480093f4SDimitry Andric /// 4311480093f4SDimitry Andric /// \param StartLoc Starting location of the directive kind. 4312480093f4SDimitry Andric /// \param EndLoc Ending location of the directive. 4313480093f4SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 4314480093f4SDimitry Andric /// OMPParallelMasterTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4315480093f4SDimitry Andric OMPParallelMasterTaskLoopSimdDirective(SourceLocation StartLoc, 4316480093f4SDimitry Andric SourceLocation EndLoc, 4317e8d8bef9SDimitry Andric unsigned CollapsedNum) 4318e8d8bef9SDimitry Andric : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass, 4319480093f4SDimitry Andric llvm::omp::OMPD_parallel_master_taskloop_simd, 4320e8d8bef9SDimitry Andric StartLoc, EndLoc, CollapsedNum) {} 4321480093f4SDimitry Andric 4322480093f4SDimitry Andric /// Build an empty directive. 4323480093f4SDimitry Andric /// 4324480093f4SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 4325480093f4SDimitry Andric /// OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum)4326e8d8bef9SDimitry Andric explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum) 4327e8d8bef9SDimitry Andric : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass, 4328480093f4SDimitry Andric llvm::omp::OMPD_parallel_master_taskloop_simd, 4329e8d8bef9SDimitry Andric SourceLocation(), SourceLocation(), CollapsedNum) {} 4330480093f4SDimitry Andric 4331480093f4SDimitry Andric public: 4332480093f4SDimitry Andric /// Creates directive with a list of \p Clauses. 4333480093f4SDimitry Andric /// 4334480093f4SDimitry Andric /// \param C AST context. 4335480093f4SDimitry Andric /// \param StartLoc Starting location of the directive kind. 4336480093f4SDimitry Andric /// \param EndLoc Ending Location of the directive. 4337480093f4SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 4338480093f4SDimitry Andric /// \param Clauses List of clauses. 4339480093f4SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 4340480093f4SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 4341480093f4SDimitry Andric /// 4342480093f4SDimitry Andric static OMPParallelMasterTaskLoopSimdDirective * 4343480093f4SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4344480093f4SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4345480093f4SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 4346480093f4SDimitry Andric 4347480093f4SDimitry Andric /// Creates an empty directive with the place 4348480093f4SDimitry Andric /// for \a NumClauses clauses. 4349480093f4SDimitry Andric /// 4350480093f4SDimitry Andric /// \param C AST context. 4351480093f4SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 4352480093f4SDimitry Andric /// \param NumClauses Number of clauses. 4353480093f4SDimitry Andric /// 4354480093f4SDimitry Andric static OMPParallelMasterTaskLoopSimdDirective * 4355480093f4SDimitry Andric CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4356480093f4SDimitry Andric EmptyShell); 4357480093f4SDimitry Andric classof(const Stmt * T)4358480093f4SDimitry Andric static bool classof(const Stmt *T) { 4359480093f4SDimitry Andric return T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass; 4360480093f4SDimitry Andric } 4361480093f4SDimitry Andric }; 4362480093f4SDimitry Andric 436381ad6265SDimitry Andric /// This represents '#pragma omp parallel masked taskloop simd' directive. 436481ad6265SDimitry Andric /// 436581ad6265SDimitry Andric /// \code 436681ad6265SDimitry Andric /// #pragma omp parallel masked taskloop simd private(a,b) grainsize(val) 436781ad6265SDimitry Andric /// num_tasks(num) 436881ad6265SDimitry Andric /// \endcode 436981ad6265SDimitry Andric /// In this example directive '#pragma omp parallel masked taskloop simd' has 437081ad6265SDimitry Andric /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with 437181ad6265SDimitry Andric /// expression 'val' and 'num_tasks' with expression 'num'. 437281ad6265SDimitry Andric /// 437381ad6265SDimitry Andric class OMPParallelMaskedTaskLoopSimdDirective final : public OMPLoopDirective { 437481ad6265SDimitry Andric friend class ASTStmtReader; 437581ad6265SDimitry Andric friend class OMPExecutableDirective; 437681ad6265SDimitry Andric /// Build directive with the given start and end location. 437781ad6265SDimitry Andric /// 437881ad6265SDimitry Andric /// \param StartLoc Starting location of the directive kind. 437981ad6265SDimitry Andric /// \param EndLoc Ending location of the directive. 438081ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 438181ad6265SDimitry Andric /// OMPParallelMaskedTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)438281ad6265SDimitry Andric OMPParallelMaskedTaskLoopSimdDirective(SourceLocation StartLoc, 438381ad6265SDimitry Andric SourceLocation EndLoc, 438481ad6265SDimitry Andric unsigned CollapsedNum) 438581ad6265SDimitry Andric : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass, 438681ad6265SDimitry Andric llvm::omp::OMPD_parallel_masked_taskloop_simd, 438781ad6265SDimitry Andric StartLoc, EndLoc, CollapsedNum) {} 438881ad6265SDimitry Andric 438981ad6265SDimitry Andric /// Build an empty directive. 439081ad6265SDimitry Andric /// 439181ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 439281ad6265SDimitry Andric /// OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum)439381ad6265SDimitry Andric explicit OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum) 439481ad6265SDimitry Andric : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass, 439581ad6265SDimitry Andric llvm::omp::OMPD_parallel_masked_taskloop_simd, 439681ad6265SDimitry Andric SourceLocation(), SourceLocation(), CollapsedNum) {} 439781ad6265SDimitry Andric 439881ad6265SDimitry Andric public: 439981ad6265SDimitry Andric /// Creates directive with a list of \p Clauses. 440081ad6265SDimitry Andric /// 440181ad6265SDimitry Andric /// \param C AST context. 440281ad6265SDimitry Andric /// \param StartLoc Starting location of the directive kind. 440381ad6265SDimitry Andric /// \param EndLoc Ending Location of the directive. 440481ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 440581ad6265SDimitry Andric /// \param Clauses List of clauses. 440681ad6265SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 440781ad6265SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 440881ad6265SDimitry Andric /// 440981ad6265SDimitry Andric static OMPParallelMaskedTaskLoopSimdDirective * 441081ad6265SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 441181ad6265SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 441281ad6265SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 441381ad6265SDimitry Andric 441481ad6265SDimitry Andric /// Creates an empty directive with the place 441581ad6265SDimitry Andric /// for \a NumClauses clauses. 441681ad6265SDimitry Andric /// 441781ad6265SDimitry Andric /// \param C AST context. 441881ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 441981ad6265SDimitry Andric /// \param NumClauses Number of clauses. 442081ad6265SDimitry Andric /// 442181ad6265SDimitry Andric static OMPParallelMaskedTaskLoopSimdDirective * 442281ad6265SDimitry Andric CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 442381ad6265SDimitry Andric EmptyShell); 442481ad6265SDimitry Andric classof(const Stmt * T)442581ad6265SDimitry Andric static bool classof(const Stmt *T) { 442681ad6265SDimitry Andric return T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass; 442781ad6265SDimitry Andric } 442881ad6265SDimitry Andric }; 442981ad6265SDimitry Andric 44300b57cec5SDimitry Andric /// This represents '#pragma omp distribute' directive. 44310b57cec5SDimitry Andric /// 44320b57cec5SDimitry Andric /// \code 44330b57cec5SDimitry Andric /// #pragma omp distribute private(a,b) 44340b57cec5SDimitry Andric /// \endcode 44350b57cec5SDimitry Andric /// In this example directive '#pragma omp distribute' has clauses 'private' 44360b57cec5SDimitry Andric /// with the variables 'a' and 'b' 44370b57cec5SDimitry Andric /// 44380b57cec5SDimitry Andric class OMPDistributeDirective : public OMPLoopDirective { 44390b57cec5SDimitry Andric friend class ASTStmtReader; 4440e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 44410b57cec5SDimitry Andric 44420b57cec5SDimitry Andric /// Build directive with the given start and end location. 44430b57cec5SDimitry Andric /// 44440b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 44450b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 44460b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 44470b57cec5SDimitry Andric /// OMPDistributeDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)44480b57cec5SDimitry Andric OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4449e8d8bef9SDimitry Andric unsigned CollapsedNum) 4450e8d8bef9SDimitry Andric : OMPLoopDirective(OMPDistributeDirectiveClass, 4451480093f4SDimitry Andric llvm::omp::OMPD_distribute, StartLoc, EndLoc, 4452e8d8bef9SDimitry Andric CollapsedNum) {} 44530b57cec5SDimitry Andric 44540b57cec5SDimitry Andric /// Build an empty directive. 44550b57cec5SDimitry Andric /// 44560b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 44570b57cec5SDimitry Andric /// OMPDistributeDirective(unsigned CollapsedNum)4458e8d8bef9SDimitry Andric explicit OMPDistributeDirective(unsigned CollapsedNum) 4459e8d8bef9SDimitry Andric : OMPLoopDirective(OMPDistributeDirectiveClass, 4460480093f4SDimitry Andric llvm::omp::OMPD_distribute, SourceLocation(), 4461e8d8bef9SDimitry Andric SourceLocation(), CollapsedNum) {} 44620b57cec5SDimitry Andric 44630b57cec5SDimitry Andric public: 44640b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 44650b57cec5SDimitry Andric /// 44660b57cec5SDimitry Andric /// \param C AST context. 44670b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 44680b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 44690b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 44700b57cec5SDimitry Andric /// \param Clauses List of clauses. 44710b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 44720b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 44730b57cec5SDimitry Andric /// 44740b57cec5SDimitry Andric static OMPDistributeDirective * 44750b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 44760b57cec5SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 44775f757f3fSDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs, 44785f757f3fSDimitry Andric OpenMPDirectiveKind ParamPrevMappedDirective); 44790b57cec5SDimitry Andric 44800b57cec5SDimitry Andric /// Creates an empty directive with the place 44810b57cec5SDimitry Andric /// for \a NumClauses clauses. 44820b57cec5SDimitry Andric /// 44830b57cec5SDimitry Andric /// \param C AST context. 44840b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 44850b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 44860b57cec5SDimitry Andric /// 44870b57cec5SDimitry Andric static OMPDistributeDirective *CreateEmpty(const ASTContext &C, 44880b57cec5SDimitry Andric unsigned NumClauses, 44890b57cec5SDimitry Andric unsigned CollapsedNum, EmptyShell); 44900b57cec5SDimitry Andric classof(const Stmt * T)44910b57cec5SDimitry Andric static bool classof(const Stmt *T) { 44920b57cec5SDimitry Andric return T->getStmtClass() == OMPDistributeDirectiveClass; 44930b57cec5SDimitry Andric } 44940b57cec5SDimitry Andric }; 44950b57cec5SDimitry Andric 44960b57cec5SDimitry Andric /// This represents '#pragma omp target update' directive. 44970b57cec5SDimitry Andric /// 44980b57cec5SDimitry Andric /// \code 44990b57cec5SDimitry Andric /// #pragma omp target update to(a) from(b) device(1) 45000b57cec5SDimitry Andric /// \endcode 45010b57cec5SDimitry Andric /// In this example directive '#pragma omp target update' has clause 'to' with 45020b57cec5SDimitry Andric /// argument 'a', clause 'from' with argument 'b' and clause 'device' with 45030b57cec5SDimitry Andric /// argument '1'. 45040b57cec5SDimitry Andric /// 45050b57cec5SDimitry Andric class OMPTargetUpdateDirective : public OMPExecutableDirective { 45060b57cec5SDimitry Andric friend class ASTStmtReader; 4507e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 45080b57cec5SDimitry Andric /// Build directive with the given start and end location. 45090b57cec5SDimitry Andric /// 45100b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 45110b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 45120b57cec5SDimitry Andric /// OMPTargetUpdateDirective(SourceLocation StartLoc,SourceLocation EndLoc)4513e8d8bef9SDimitry Andric OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc) 4514e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTargetUpdateDirectiveClass, 4515e8d8bef9SDimitry Andric llvm::omp::OMPD_target_update, StartLoc, 4516e8d8bef9SDimitry Andric EndLoc) {} 45170b57cec5SDimitry Andric 45180b57cec5SDimitry Andric /// Build an empty directive. 45190b57cec5SDimitry Andric /// OMPTargetUpdateDirective()4520e8d8bef9SDimitry Andric explicit OMPTargetUpdateDirective() 4521e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTargetUpdateDirectiveClass, 4522480093f4SDimitry Andric llvm::omp::OMPD_target_update, SourceLocation(), 4523e8d8bef9SDimitry Andric SourceLocation()) {} 45240b57cec5SDimitry Andric 45250b57cec5SDimitry Andric public: 45260b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 45270b57cec5SDimitry Andric /// 45280b57cec5SDimitry Andric /// \param C AST context. 45290b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 45300b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 45310b57cec5SDimitry Andric /// \param Clauses List of clauses. 45320b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 45330b57cec5SDimitry Andric /// 45340b57cec5SDimitry Andric static OMPTargetUpdateDirective * 45350b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 45360b57cec5SDimitry Andric ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 45370b57cec5SDimitry Andric 45380b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses 45390b57cec5SDimitry Andric /// clauses. 45400b57cec5SDimitry Andric /// 45410b57cec5SDimitry Andric /// \param C AST context. 45420b57cec5SDimitry Andric /// \param NumClauses The number of clauses. 45430b57cec5SDimitry Andric /// 45440b57cec5SDimitry Andric static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C, 45450b57cec5SDimitry Andric unsigned NumClauses, EmptyShell); 45460b57cec5SDimitry Andric classof(const Stmt * T)45470b57cec5SDimitry Andric static bool classof(const Stmt *T) { 45480b57cec5SDimitry Andric return T->getStmtClass() == OMPTargetUpdateDirectiveClass; 45490b57cec5SDimitry Andric } 45500b57cec5SDimitry Andric }; 45510b57cec5SDimitry Andric 45520b57cec5SDimitry Andric /// This represents '#pragma omp distribute parallel for' composite 45530b57cec5SDimitry Andric /// directive. 45540b57cec5SDimitry Andric /// 45550b57cec5SDimitry Andric /// \code 45560b57cec5SDimitry Andric /// #pragma omp distribute parallel for private(a,b) 45570b57cec5SDimitry Andric /// \endcode 45580b57cec5SDimitry Andric /// In this example directive '#pragma omp distribute parallel for' has clause 45590b57cec5SDimitry Andric /// 'private' with the variables 'a' and 'b' 45600b57cec5SDimitry Andric /// 45610b57cec5SDimitry Andric class OMPDistributeParallelForDirective : public OMPLoopDirective { 45620b57cec5SDimitry Andric friend class ASTStmtReader; 4563e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 45640b57cec5SDimitry Andric /// true if the construct has inner cancel directive. 45650b57cec5SDimitry Andric bool HasCancel = false; 45660b57cec5SDimitry Andric 45670b57cec5SDimitry Andric /// Build directive with the given start and end location. 45680b57cec5SDimitry Andric /// 45690b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 45700b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 45710b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 45720b57cec5SDimitry Andric /// OMPDistributeParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)45730b57cec5SDimitry Andric OMPDistributeParallelForDirective(SourceLocation StartLoc, 45740b57cec5SDimitry Andric SourceLocation EndLoc, 4575e8d8bef9SDimitry Andric unsigned CollapsedNum) 4576e8d8bef9SDimitry Andric : OMPLoopDirective(OMPDistributeParallelForDirectiveClass, 4577480093f4SDimitry Andric llvm::omp::OMPD_distribute_parallel_for, StartLoc, 4578e8d8bef9SDimitry Andric EndLoc, CollapsedNum) {} 45790b57cec5SDimitry Andric 45800b57cec5SDimitry Andric /// Build an empty directive. 45810b57cec5SDimitry Andric /// 45820b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 45830b57cec5SDimitry Andric /// OMPDistributeParallelForDirective(unsigned CollapsedNum)4584e8d8bef9SDimitry Andric explicit OMPDistributeParallelForDirective(unsigned CollapsedNum) 4585e8d8bef9SDimitry Andric : OMPLoopDirective(OMPDistributeParallelForDirectiveClass, 4586480093f4SDimitry Andric llvm::omp::OMPD_distribute_parallel_for, 4587e8d8bef9SDimitry Andric SourceLocation(), SourceLocation(), CollapsedNum) {} 45880b57cec5SDimitry Andric 45895ffd83dbSDimitry Andric /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)4590e8d8bef9SDimitry Andric void setTaskReductionRefExpr(Expr *E) { 4591e8d8bef9SDimitry Andric Data->getChildren()[numLoopChildren( 4592fe6060f1SDimitry Andric getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)] = E; 4593e8d8bef9SDimitry Andric } 45945ffd83dbSDimitry Andric 45950b57cec5SDimitry Andric /// Set cancel state. setHasCancel(bool Has)45960b57cec5SDimitry Andric void setHasCancel(bool Has) { HasCancel = Has; } 45970b57cec5SDimitry Andric 45980b57cec5SDimitry Andric public: 45990b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 46000b57cec5SDimitry Andric /// 46010b57cec5SDimitry Andric /// \param C AST context. 46020b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 46030b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 46040b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 46050b57cec5SDimitry Andric /// \param Clauses List of clauses. 46060b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 46070b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 46085ffd83dbSDimitry Andric /// \param TaskRedRef Task reduction special reference expression to handle 46095ffd83dbSDimitry Andric /// taskgroup descriptor. 46100b57cec5SDimitry Andric /// \param HasCancel true if this directive has inner cancel directive. 46110b57cec5SDimitry Andric /// 46120b57cec5SDimitry Andric static OMPDistributeParallelForDirective * 46130b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 46140b57cec5SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 46155ffd83dbSDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 46165ffd83dbSDimitry Andric bool HasCancel); 46170b57cec5SDimitry Andric 46180b57cec5SDimitry Andric /// Creates an empty directive with the place 46190b57cec5SDimitry Andric /// for \a NumClauses clauses. 46200b57cec5SDimitry Andric /// 46210b57cec5SDimitry Andric /// \param C AST context. 46220b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 46230b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 46240b57cec5SDimitry Andric /// 46250b57cec5SDimitry Andric static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C, 46260b57cec5SDimitry Andric unsigned NumClauses, 46270b57cec5SDimitry Andric unsigned CollapsedNum, 46280b57cec5SDimitry Andric EmptyShell); 46290b57cec5SDimitry Andric 46305ffd83dbSDimitry Andric /// Returns special task reduction reference expression. getTaskReductionRefExpr()4631e8d8bef9SDimitry Andric Expr *getTaskReductionRefExpr() { 4632e8d8bef9SDimitry Andric return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 4633fe6060f1SDimitry Andric getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)]); 4634e8d8bef9SDimitry Andric } getTaskReductionRefExpr()4635e8d8bef9SDimitry Andric const Expr *getTaskReductionRefExpr() const { 4636e8d8bef9SDimitry Andric return const_cast<OMPDistributeParallelForDirective *>(this) 4637e8d8bef9SDimitry Andric ->getTaskReductionRefExpr(); 4638e8d8bef9SDimitry Andric } 46395ffd83dbSDimitry Andric 46400b57cec5SDimitry Andric /// Return true if current directive has inner cancel directive. hasCancel()46410b57cec5SDimitry Andric bool hasCancel() const { return HasCancel; } 46420b57cec5SDimitry Andric classof(const Stmt * T)46430b57cec5SDimitry Andric static bool classof(const Stmt *T) { 46440b57cec5SDimitry Andric return T->getStmtClass() == OMPDistributeParallelForDirectiveClass; 46450b57cec5SDimitry Andric } 46460b57cec5SDimitry Andric }; 46470b57cec5SDimitry Andric 46480b57cec5SDimitry Andric /// This represents '#pragma omp distribute parallel for simd' composite 46490b57cec5SDimitry Andric /// directive. 46500b57cec5SDimitry Andric /// 46510b57cec5SDimitry Andric /// \code 46520b57cec5SDimitry Andric /// #pragma omp distribute parallel for simd private(x) 46530b57cec5SDimitry Andric /// \endcode 46540b57cec5SDimitry Andric /// In this example directive '#pragma omp distribute parallel for simd' has 46550b57cec5SDimitry Andric /// clause 'private' with the variables 'x' 46560b57cec5SDimitry Andric /// 46570b57cec5SDimitry Andric class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective { 46580b57cec5SDimitry Andric friend class ASTStmtReader; 4659e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 46600b57cec5SDimitry Andric 46610b57cec5SDimitry Andric /// Build directive with the given start and end location. 46620b57cec5SDimitry Andric /// 46630b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 46640b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 46650b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 46660b57cec5SDimitry Andric /// OMPDistributeParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)46670b57cec5SDimitry Andric OMPDistributeParallelForSimdDirective(SourceLocation StartLoc, 46680b57cec5SDimitry Andric SourceLocation EndLoc, 4669e8d8bef9SDimitry Andric unsigned CollapsedNum) 4670e8d8bef9SDimitry Andric : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass, 4671480093f4SDimitry Andric llvm::omp::OMPD_distribute_parallel_for_simd, StartLoc, 4672e8d8bef9SDimitry Andric EndLoc, CollapsedNum) {} 46730b57cec5SDimitry Andric 46740b57cec5SDimitry Andric /// Build an empty directive. 46750b57cec5SDimitry Andric /// 46760b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 46770b57cec5SDimitry Andric /// OMPDistributeParallelForSimdDirective(unsigned CollapsedNum)4678e8d8bef9SDimitry Andric explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum) 4679e8d8bef9SDimitry Andric : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass, 4680480093f4SDimitry Andric llvm::omp::OMPD_distribute_parallel_for_simd, 4681e8d8bef9SDimitry Andric SourceLocation(), SourceLocation(), CollapsedNum) {} 46820b57cec5SDimitry Andric 46830b57cec5SDimitry Andric public: 46840b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 46850b57cec5SDimitry Andric /// 46860b57cec5SDimitry Andric /// \param C AST context. 46870b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 46880b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 46890b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 46900b57cec5SDimitry Andric /// \param Clauses List of clauses. 46910b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 46920b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 46930b57cec5SDimitry Andric /// 46940b57cec5SDimitry Andric static OMPDistributeParallelForSimdDirective *Create( 46950b57cec5SDimitry Andric const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 46960b57cec5SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 46970b57cec5SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 46980b57cec5SDimitry Andric 46990b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses clauses. 47000b57cec5SDimitry Andric /// 47010b57cec5SDimitry Andric /// \param C AST context. 47020b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 47030b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 47040b57cec5SDimitry Andric /// 47050b57cec5SDimitry Andric static OMPDistributeParallelForSimdDirective *CreateEmpty( 47060b57cec5SDimitry Andric const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 47070b57cec5SDimitry Andric EmptyShell); 47080b57cec5SDimitry Andric classof(const Stmt * T)47090b57cec5SDimitry Andric static bool classof(const Stmt *T) { 47100b57cec5SDimitry Andric return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass; 47110b57cec5SDimitry Andric } 47120b57cec5SDimitry Andric }; 47130b57cec5SDimitry Andric 47140b57cec5SDimitry Andric /// This represents '#pragma omp distribute simd' composite directive. 47150b57cec5SDimitry Andric /// 47160b57cec5SDimitry Andric /// \code 47170b57cec5SDimitry Andric /// #pragma omp distribute simd private(x) 47180b57cec5SDimitry Andric /// \endcode 47190b57cec5SDimitry Andric /// In this example directive '#pragma omp distribute simd' has clause 47200b57cec5SDimitry Andric /// 'private' with the variables 'x' 47210b57cec5SDimitry Andric /// 47220b57cec5SDimitry Andric class OMPDistributeSimdDirective final : public OMPLoopDirective { 47230b57cec5SDimitry Andric friend class ASTStmtReader; 4724e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 47250b57cec5SDimitry Andric 47260b57cec5SDimitry Andric /// Build directive with the given start and end location. 47270b57cec5SDimitry Andric /// 47280b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 47290b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 47300b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 47310b57cec5SDimitry Andric /// OMPDistributeSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)47320b57cec5SDimitry Andric OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4733e8d8bef9SDimitry Andric unsigned CollapsedNum) 4734e8d8bef9SDimitry Andric : OMPLoopDirective(OMPDistributeSimdDirectiveClass, 4735480093f4SDimitry Andric llvm::omp::OMPD_distribute_simd, StartLoc, EndLoc, 4736e8d8bef9SDimitry Andric CollapsedNum) {} 47370b57cec5SDimitry Andric 47380b57cec5SDimitry Andric /// Build an empty directive. 47390b57cec5SDimitry Andric /// 47400b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 47410b57cec5SDimitry Andric /// OMPDistributeSimdDirective(unsigned CollapsedNum)4742e8d8bef9SDimitry Andric explicit OMPDistributeSimdDirective(unsigned CollapsedNum) 4743e8d8bef9SDimitry Andric : OMPLoopDirective(OMPDistributeSimdDirectiveClass, 4744480093f4SDimitry Andric llvm::omp::OMPD_distribute_simd, SourceLocation(), 4745e8d8bef9SDimitry Andric SourceLocation(), CollapsedNum) {} 47460b57cec5SDimitry Andric 47470b57cec5SDimitry Andric public: 47480b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 47490b57cec5SDimitry Andric /// 47500b57cec5SDimitry Andric /// \param C AST context. 47510b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 47520b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 47530b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 47540b57cec5SDimitry Andric /// \param Clauses List of clauses. 47550b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 47560b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 47570b57cec5SDimitry Andric /// 47580b57cec5SDimitry Andric static OMPDistributeSimdDirective * 47590b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 47600b57cec5SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 47610b57cec5SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 47620b57cec5SDimitry Andric 47630b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses clauses. 47640b57cec5SDimitry Andric /// 47650b57cec5SDimitry Andric /// \param C AST context. 47660b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 47670b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 47680b57cec5SDimitry Andric /// 47690b57cec5SDimitry Andric static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C, 47700b57cec5SDimitry Andric unsigned NumClauses, 47710b57cec5SDimitry Andric unsigned CollapsedNum, 47720b57cec5SDimitry Andric EmptyShell); 47730b57cec5SDimitry Andric classof(const Stmt * T)47740b57cec5SDimitry Andric static bool classof(const Stmt *T) { 47750b57cec5SDimitry Andric return T->getStmtClass() == OMPDistributeSimdDirectiveClass; 47760b57cec5SDimitry Andric } 47770b57cec5SDimitry Andric }; 47780b57cec5SDimitry Andric 47790b57cec5SDimitry Andric /// This represents '#pragma omp target parallel for simd' directive. 47800b57cec5SDimitry Andric /// 47810b57cec5SDimitry Andric /// \code 47820b57cec5SDimitry Andric /// #pragma omp target parallel for simd private(a) map(b) safelen(c) 47830b57cec5SDimitry Andric /// \endcode 47840b57cec5SDimitry Andric /// In this example directive '#pragma omp target parallel for simd' has clauses 47850b57cec5SDimitry Andric /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen' 47860b57cec5SDimitry Andric /// with the variable 'c'. 47870b57cec5SDimitry Andric /// 47880b57cec5SDimitry Andric class OMPTargetParallelForSimdDirective final : public OMPLoopDirective { 47890b57cec5SDimitry Andric friend class ASTStmtReader; 4790e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 47910b57cec5SDimitry Andric 47920b57cec5SDimitry Andric /// Build directive with the given start and end location. 47930b57cec5SDimitry Andric /// 47940b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 47950b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 47960b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 47970b57cec5SDimitry Andric /// OMPTargetParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4798480093f4SDimitry Andric OMPTargetParallelForSimdDirective(SourceLocation StartLoc, 4799480093f4SDimitry Andric SourceLocation EndLoc, 4800e8d8bef9SDimitry Andric unsigned CollapsedNum) 4801e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass, 4802480093f4SDimitry Andric llvm::omp::OMPD_target_parallel_for_simd, StartLoc, 4803e8d8bef9SDimitry Andric EndLoc, CollapsedNum) {} 48040b57cec5SDimitry Andric 48050b57cec5SDimitry Andric /// Build an empty directive. 48060b57cec5SDimitry Andric /// 48070b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 48080b57cec5SDimitry Andric /// OMPTargetParallelForSimdDirective(unsigned CollapsedNum)4809e8d8bef9SDimitry Andric explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum) 4810e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass, 4811480093f4SDimitry Andric llvm::omp::OMPD_target_parallel_for_simd, 4812e8d8bef9SDimitry Andric SourceLocation(), SourceLocation(), CollapsedNum) {} 48130b57cec5SDimitry Andric 48140b57cec5SDimitry Andric public: 48150b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 48160b57cec5SDimitry Andric /// 48170b57cec5SDimitry Andric /// \param C AST context. 48180b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 48190b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 48200b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 48210b57cec5SDimitry Andric /// \param Clauses List of clauses. 48220b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 48230b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 48240b57cec5SDimitry Andric /// 48250b57cec5SDimitry Andric static OMPTargetParallelForSimdDirective * 48260b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 48270b57cec5SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 48280b57cec5SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 48290b57cec5SDimitry Andric 48300b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses clauses. 48310b57cec5SDimitry Andric /// 48320b57cec5SDimitry Andric /// \param C AST context. 48330b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 48340b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 48350b57cec5SDimitry Andric /// 48360b57cec5SDimitry Andric static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C, 48370b57cec5SDimitry Andric unsigned NumClauses, 48380b57cec5SDimitry Andric unsigned CollapsedNum, 48390b57cec5SDimitry Andric EmptyShell); 48400b57cec5SDimitry Andric classof(const Stmt * T)48410b57cec5SDimitry Andric static bool classof(const Stmt *T) { 48420b57cec5SDimitry Andric return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass; 48430b57cec5SDimitry Andric } 48440b57cec5SDimitry Andric }; 48450b57cec5SDimitry Andric 48460b57cec5SDimitry Andric /// This represents '#pragma omp target simd' directive. 48470b57cec5SDimitry Andric /// 48480b57cec5SDimitry Andric /// \code 48490b57cec5SDimitry Andric /// #pragma omp target simd private(a) map(b) safelen(c) 48500b57cec5SDimitry Andric /// \endcode 48510b57cec5SDimitry Andric /// In this example directive '#pragma omp target simd' has clauses 'private' 48520b57cec5SDimitry Andric /// with the variable 'a', 'map' with the variable 'b' and 'safelen' with 48530b57cec5SDimitry Andric /// the variable 'c'. 48540b57cec5SDimitry Andric /// 48550b57cec5SDimitry Andric class OMPTargetSimdDirective final : public OMPLoopDirective { 48560b57cec5SDimitry Andric friend class ASTStmtReader; 4857e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 48580b57cec5SDimitry Andric 48590b57cec5SDimitry Andric /// Build directive with the given start and end location. 48600b57cec5SDimitry Andric /// 48610b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 48620b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 48630b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 48640b57cec5SDimitry Andric /// OMPTargetSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)48650b57cec5SDimitry Andric OMPTargetSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4866e8d8bef9SDimitry Andric unsigned CollapsedNum) 4867e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTargetSimdDirectiveClass, 4868480093f4SDimitry Andric llvm::omp::OMPD_target_simd, StartLoc, EndLoc, 4869e8d8bef9SDimitry Andric CollapsedNum) {} 48700b57cec5SDimitry Andric 48710b57cec5SDimitry Andric /// Build an empty directive. 48720b57cec5SDimitry Andric /// 48730b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 48740b57cec5SDimitry Andric /// OMPTargetSimdDirective(unsigned CollapsedNum)4875e8d8bef9SDimitry Andric explicit OMPTargetSimdDirective(unsigned CollapsedNum) 4876e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTargetSimdDirectiveClass, 4877480093f4SDimitry Andric llvm::omp::OMPD_target_simd, SourceLocation(), 4878e8d8bef9SDimitry Andric SourceLocation(), CollapsedNum) {} 48790b57cec5SDimitry Andric 48800b57cec5SDimitry Andric public: 48810b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 48820b57cec5SDimitry Andric /// 48830b57cec5SDimitry Andric /// \param C AST context. 48840b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 48850b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 48860b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 48870b57cec5SDimitry Andric /// \param Clauses List of clauses. 48880b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 48890b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 48900b57cec5SDimitry Andric /// 48910b57cec5SDimitry Andric static OMPTargetSimdDirective * 48920b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 48930b57cec5SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 48940b57cec5SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 48950b57cec5SDimitry Andric 48960b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses clauses. 48970b57cec5SDimitry Andric /// 48980b57cec5SDimitry Andric /// \param C AST context. 48990b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 49000b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 49010b57cec5SDimitry Andric /// 49020b57cec5SDimitry Andric static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C, 49030b57cec5SDimitry Andric unsigned NumClauses, 49040b57cec5SDimitry Andric unsigned CollapsedNum, 49050b57cec5SDimitry Andric EmptyShell); 49060b57cec5SDimitry Andric classof(const Stmt * T)49070b57cec5SDimitry Andric static bool classof(const Stmt *T) { 49080b57cec5SDimitry Andric return T->getStmtClass() == OMPTargetSimdDirectiveClass; 49090b57cec5SDimitry Andric } 49100b57cec5SDimitry Andric }; 49110b57cec5SDimitry Andric 49120b57cec5SDimitry Andric /// This represents '#pragma omp teams distribute' directive. 49130b57cec5SDimitry Andric /// 49140b57cec5SDimitry Andric /// \code 49150b57cec5SDimitry Andric /// #pragma omp teams distribute private(a,b) 49160b57cec5SDimitry Andric /// \endcode 49170b57cec5SDimitry Andric /// In this example directive '#pragma omp teams distribute' has clauses 49180b57cec5SDimitry Andric /// 'private' with the variables 'a' and 'b' 49190b57cec5SDimitry Andric /// 49200b57cec5SDimitry Andric class OMPTeamsDistributeDirective final : public OMPLoopDirective { 49210b57cec5SDimitry Andric friend class ASTStmtReader; 4922e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 49230b57cec5SDimitry Andric 49240b57cec5SDimitry Andric /// Build directive with the given start and end location. 49250b57cec5SDimitry Andric /// 49260b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 49270b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 49280b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 49290b57cec5SDimitry Andric /// OMPTeamsDistributeDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)49300b57cec5SDimitry Andric OMPTeamsDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4931e8d8bef9SDimitry Andric unsigned CollapsedNum) 4932e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTeamsDistributeDirectiveClass, 4933480093f4SDimitry Andric llvm::omp::OMPD_teams_distribute, StartLoc, EndLoc, 4934e8d8bef9SDimitry Andric CollapsedNum) {} 49350b57cec5SDimitry Andric 49360b57cec5SDimitry Andric /// Build an empty directive. 49370b57cec5SDimitry Andric /// 49380b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 49390b57cec5SDimitry Andric /// OMPTeamsDistributeDirective(unsigned CollapsedNum)4940e8d8bef9SDimitry Andric explicit OMPTeamsDistributeDirective(unsigned CollapsedNum) 4941e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTeamsDistributeDirectiveClass, 4942480093f4SDimitry Andric llvm::omp::OMPD_teams_distribute, SourceLocation(), 4943e8d8bef9SDimitry Andric SourceLocation(), CollapsedNum) {} 49440b57cec5SDimitry Andric 49450b57cec5SDimitry Andric public: 49460b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 49470b57cec5SDimitry Andric /// 49480b57cec5SDimitry Andric /// \param C AST context. 49490b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 49500b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 49510b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 49520b57cec5SDimitry Andric /// \param Clauses List of clauses. 49530b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 49540b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 49550b57cec5SDimitry Andric /// 49560b57cec5SDimitry Andric static OMPTeamsDistributeDirective * 49570b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 49580b57cec5SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 49590b57cec5SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 49600b57cec5SDimitry Andric 49610b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses clauses. 49620b57cec5SDimitry Andric /// 49630b57cec5SDimitry Andric /// \param C AST context. 49640b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 49650b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 49660b57cec5SDimitry Andric /// 49670b57cec5SDimitry Andric static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C, 49680b57cec5SDimitry Andric unsigned NumClauses, 49690b57cec5SDimitry Andric unsigned CollapsedNum, 49700b57cec5SDimitry Andric EmptyShell); 49710b57cec5SDimitry Andric classof(const Stmt * T)49720b57cec5SDimitry Andric static bool classof(const Stmt *T) { 49730b57cec5SDimitry Andric return T->getStmtClass() == OMPTeamsDistributeDirectiveClass; 49740b57cec5SDimitry Andric } 49750b57cec5SDimitry Andric }; 49760b57cec5SDimitry Andric 49770b57cec5SDimitry Andric /// This represents '#pragma omp teams distribute simd' 49780b57cec5SDimitry Andric /// combined directive. 49790b57cec5SDimitry Andric /// 49800b57cec5SDimitry Andric /// \code 49810b57cec5SDimitry Andric /// #pragma omp teams distribute simd private(a,b) 49820b57cec5SDimitry Andric /// \endcode 49830b57cec5SDimitry Andric /// In this example directive '#pragma omp teams distribute simd' 49840b57cec5SDimitry Andric /// has clause 'private' with the variables 'a' and 'b' 49850b57cec5SDimitry Andric /// 49860b57cec5SDimitry Andric class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective { 49870b57cec5SDimitry Andric friend class ASTStmtReader; 4988e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 49890b57cec5SDimitry Andric 49900b57cec5SDimitry Andric /// Build directive with the given start and end location. 49910b57cec5SDimitry Andric /// 49920b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 49930b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 49940b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 49950b57cec5SDimitry Andric /// OMPTeamsDistributeSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)49960b57cec5SDimitry Andric OMPTeamsDistributeSimdDirective(SourceLocation StartLoc, 4997e8d8bef9SDimitry Andric SourceLocation EndLoc, unsigned CollapsedNum) 4998e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass, 4999480093f4SDimitry Andric llvm::omp::OMPD_teams_distribute_simd, StartLoc, 5000e8d8bef9SDimitry Andric EndLoc, CollapsedNum) {} 50010b57cec5SDimitry Andric 50020b57cec5SDimitry Andric /// Build an empty directive. 50030b57cec5SDimitry Andric /// 50040b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 50050b57cec5SDimitry Andric /// OMPTeamsDistributeSimdDirective(unsigned CollapsedNum)5006e8d8bef9SDimitry Andric explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum) 5007e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass, 5008480093f4SDimitry Andric llvm::omp::OMPD_teams_distribute_simd, 5009e8d8bef9SDimitry Andric SourceLocation(), SourceLocation(), CollapsedNum) {} 50100b57cec5SDimitry Andric 50110b57cec5SDimitry Andric public: 50120b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 50130b57cec5SDimitry Andric /// 50140b57cec5SDimitry Andric /// \param C AST context. 50150b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 50160b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 50170b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 50180b57cec5SDimitry Andric /// \param Clauses List of clauses. 50190b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 50200b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 50210b57cec5SDimitry Andric /// 50220b57cec5SDimitry Andric static OMPTeamsDistributeSimdDirective * 50230b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 50240b57cec5SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 50250b57cec5SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 50260b57cec5SDimitry Andric 50270b57cec5SDimitry Andric /// Creates an empty directive with the place 50280b57cec5SDimitry Andric /// for \a NumClauses clauses. 50290b57cec5SDimitry Andric /// 50300b57cec5SDimitry Andric /// \param C AST context. 50310b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 50320b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 50330b57cec5SDimitry Andric /// 50340b57cec5SDimitry Andric static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C, 50350b57cec5SDimitry Andric unsigned NumClauses, 50360b57cec5SDimitry Andric unsigned CollapsedNum, 50370b57cec5SDimitry Andric EmptyShell); 50380b57cec5SDimitry Andric classof(const Stmt * T)50390b57cec5SDimitry Andric static bool classof(const Stmt *T) { 50400b57cec5SDimitry Andric return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass; 50410b57cec5SDimitry Andric } 50420b57cec5SDimitry Andric }; 50430b57cec5SDimitry Andric 50440b57cec5SDimitry Andric /// This represents '#pragma omp teams distribute parallel for simd' composite 50450b57cec5SDimitry Andric /// directive. 50460b57cec5SDimitry Andric /// 50470b57cec5SDimitry Andric /// \code 50480b57cec5SDimitry Andric /// #pragma omp teams distribute parallel for simd private(x) 50490b57cec5SDimitry Andric /// \endcode 50500b57cec5SDimitry Andric /// In this example directive '#pragma omp teams distribute parallel for simd' 50510b57cec5SDimitry Andric /// has clause 'private' with the variables 'x' 50520b57cec5SDimitry Andric /// 50530b57cec5SDimitry Andric class OMPTeamsDistributeParallelForSimdDirective final 50540b57cec5SDimitry Andric : public OMPLoopDirective { 50550b57cec5SDimitry Andric friend class ASTStmtReader; 5056e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 50570b57cec5SDimitry Andric 50580b57cec5SDimitry Andric /// Build directive with the given start and end location. 50590b57cec5SDimitry Andric /// 50600b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 50610b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 50620b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 50630b57cec5SDimitry Andric /// OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)50640b57cec5SDimitry Andric OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc, 50650b57cec5SDimitry Andric SourceLocation EndLoc, 5066e8d8bef9SDimitry Andric unsigned CollapsedNum) 5067e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass, 5068480093f4SDimitry Andric llvm::omp::OMPD_teams_distribute_parallel_for_simd, 5069e8d8bef9SDimitry Andric StartLoc, EndLoc, CollapsedNum) {} 50700b57cec5SDimitry Andric 50710b57cec5SDimitry Andric /// Build an empty directive. 50720b57cec5SDimitry Andric /// 50730b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 50740b57cec5SDimitry Andric /// OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum)5075e8d8bef9SDimitry Andric explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum) 5076e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass, 5077480093f4SDimitry Andric llvm::omp::OMPD_teams_distribute_parallel_for_simd, 5078e8d8bef9SDimitry Andric SourceLocation(), SourceLocation(), CollapsedNum) {} 50790b57cec5SDimitry Andric 50800b57cec5SDimitry Andric public: 50810b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 50820b57cec5SDimitry Andric /// 50830b57cec5SDimitry Andric /// \param C AST context. 50840b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 50850b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 50860b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 50870b57cec5SDimitry Andric /// \param Clauses List of clauses. 50880b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 50890b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 50900b57cec5SDimitry Andric /// 50910b57cec5SDimitry Andric static OMPTeamsDistributeParallelForSimdDirective * 50920b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 50930b57cec5SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 50940b57cec5SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 50950b57cec5SDimitry Andric 50960b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses clauses. 50970b57cec5SDimitry Andric /// 50980b57cec5SDimitry Andric /// \param C AST context. 50990b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 51000b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 51010b57cec5SDimitry Andric /// 51020b57cec5SDimitry Andric static OMPTeamsDistributeParallelForSimdDirective * 51030b57cec5SDimitry Andric CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 51040b57cec5SDimitry Andric EmptyShell); 51050b57cec5SDimitry Andric classof(const Stmt * T)51060b57cec5SDimitry Andric static bool classof(const Stmt *T) { 51070b57cec5SDimitry Andric return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass; 51080b57cec5SDimitry Andric } 51090b57cec5SDimitry Andric }; 51100b57cec5SDimitry Andric 51110b57cec5SDimitry Andric /// This represents '#pragma omp teams distribute parallel for' composite 51120b57cec5SDimitry Andric /// directive. 51130b57cec5SDimitry Andric /// 51140b57cec5SDimitry Andric /// \code 51150b57cec5SDimitry Andric /// #pragma omp teams distribute parallel for private(x) 51160b57cec5SDimitry Andric /// \endcode 51170b57cec5SDimitry Andric /// In this example directive '#pragma omp teams distribute parallel for' 51180b57cec5SDimitry Andric /// has clause 'private' with the variables 'x' 51190b57cec5SDimitry Andric /// 51200b57cec5SDimitry Andric class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective { 51210b57cec5SDimitry Andric friend class ASTStmtReader; 5122e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 51230b57cec5SDimitry Andric /// true if the construct has inner cancel directive. 51240b57cec5SDimitry Andric bool HasCancel = false; 51250b57cec5SDimitry Andric 51260b57cec5SDimitry Andric /// Build directive with the given start and end location. 51270b57cec5SDimitry Andric /// 51280b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 51290b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 51300b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 51310b57cec5SDimitry Andric /// OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)51320b57cec5SDimitry Andric OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc, 51330b57cec5SDimitry Andric SourceLocation EndLoc, 5134e8d8bef9SDimitry Andric unsigned CollapsedNum) 5135e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass, 5136480093f4SDimitry Andric llvm::omp::OMPD_teams_distribute_parallel_for, 5137e8d8bef9SDimitry Andric StartLoc, EndLoc, CollapsedNum) {} 51380b57cec5SDimitry Andric 51390b57cec5SDimitry Andric /// Build an empty directive. 51400b57cec5SDimitry Andric /// 51410b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 51420b57cec5SDimitry Andric /// OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum)5143e8d8bef9SDimitry Andric explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum) 5144e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass, 5145480093f4SDimitry Andric llvm::omp::OMPD_teams_distribute_parallel_for, 5146e8d8bef9SDimitry Andric SourceLocation(), SourceLocation(), CollapsedNum) {} 51470b57cec5SDimitry Andric 51485ffd83dbSDimitry Andric /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)5149e8d8bef9SDimitry Andric void setTaskReductionRefExpr(Expr *E) { 5150e8d8bef9SDimitry Andric Data->getChildren()[numLoopChildren( 5151fe6060f1SDimitry Andric getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)] = E; 5152e8d8bef9SDimitry Andric } 51535ffd83dbSDimitry Andric 51540b57cec5SDimitry Andric /// Set cancel state. setHasCancel(bool Has)51550b57cec5SDimitry Andric void setHasCancel(bool Has) { HasCancel = Has; } 51560b57cec5SDimitry Andric 51570b57cec5SDimitry Andric public: 51580b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 51590b57cec5SDimitry Andric /// 51600b57cec5SDimitry Andric /// \param C AST context. 51610b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 51620b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 51630b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 51640b57cec5SDimitry Andric /// \param Clauses List of clauses. 51650b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 51660b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 51675ffd83dbSDimitry Andric /// \param TaskRedRef Task reduction special reference expression to handle 51685ffd83dbSDimitry Andric /// taskgroup descriptor. 51690b57cec5SDimitry Andric /// \param HasCancel true if this directive has inner cancel directive. 51700b57cec5SDimitry Andric /// 51710b57cec5SDimitry Andric static OMPTeamsDistributeParallelForDirective * 51720b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 51730b57cec5SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 51745ffd83dbSDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 51755ffd83dbSDimitry Andric bool HasCancel); 51760b57cec5SDimitry Andric 51770b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses clauses. 51780b57cec5SDimitry Andric /// 51790b57cec5SDimitry Andric /// \param C AST context. 51800b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 51810b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 51820b57cec5SDimitry Andric /// 51830b57cec5SDimitry Andric static OMPTeamsDistributeParallelForDirective * 51840b57cec5SDimitry Andric CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 51850b57cec5SDimitry Andric EmptyShell); 51860b57cec5SDimitry Andric 51875ffd83dbSDimitry Andric /// Returns special task reduction reference expression. getTaskReductionRefExpr()5188e8d8bef9SDimitry Andric Expr *getTaskReductionRefExpr() { 5189e8d8bef9SDimitry Andric return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 5190fe6060f1SDimitry Andric getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)]); 5191e8d8bef9SDimitry Andric } getTaskReductionRefExpr()5192e8d8bef9SDimitry Andric const Expr *getTaskReductionRefExpr() const { 5193e8d8bef9SDimitry Andric return const_cast<OMPTeamsDistributeParallelForDirective *>(this) 5194e8d8bef9SDimitry Andric ->getTaskReductionRefExpr(); 5195e8d8bef9SDimitry Andric } 51965ffd83dbSDimitry Andric 51970b57cec5SDimitry Andric /// Return true if current directive has inner cancel directive. hasCancel()51980b57cec5SDimitry Andric bool hasCancel() const { return HasCancel; } 51990b57cec5SDimitry Andric classof(const Stmt * T)52000b57cec5SDimitry Andric static bool classof(const Stmt *T) { 52010b57cec5SDimitry Andric return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass; 52020b57cec5SDimitry Andric } 52030b57cec5SDimitry Andric }; 52040b57cec5SDimitry Andric 52050b57cec5SDimitry Andric /// This represents '#pragma omp target teams' directive. 52060b57cec5SDimitry Andric /// 52070b57cec5SDimitry Andric /// \code 52080b57cec5SDimitry Andric /// #pragma omp target teams if(a>0) 52090b57cec5SDimitry Andric /// \endcode 52100b57cec5SDimitry Andric /// In this example directive '#pragma omp target teams' has clause 'if' with 52110b57cec5SDimitry Andric /// condition 'a>0'. 52120b57cec5SDimitry Andric /// 52130b57cec5SDimitry Andric class OMPTargetTeamsDirective final : public OMPExecutableDirective { 52140b57cec5SDimitry Andric friend class ASTStmtReader; 5215e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 52160b57cec5SDimitry Andric /// Build directive with the given start and end location. 52170b57cec5SDimitry Andric /// 52180b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 52190b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 52200b57cec5SDimitry Andric /// OMPTargetTeamsDirective(SourceLocation StartLoc,SourceLocation EndLoc)5221e8d8bef9SDimitry Andric OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5222e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTargetTeamsDirectiveClass, 5223e8d8bef9SDimitry Andric llvm::omp::OMPD_target_teams, StartLoc, EndLoc) { 5224e8d8bef9SDimitry Andric } 52250b57cec5SDimitry Andric 52260b57cec5SDimitry Andric /// Build an empty directive. 52270b57cec5SDimitry Andric /// OMPTargetTeamsDirective()5228e8d8bef9SDimitry Andric explicit OMPTargetTeamsDirective() 5229e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPTargetTeamsDirectiveClass, 5230480093f4SDimitry Andric llvm::omp::OMPD_target_teams, SourceLocation(), 5231e8d8bef9SDimitry Andric SourceLocation()) {} 52320b57cec5SDimitry Andric 52330b57cec5SDimitry Andric public: 52340b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 52350b57cec5SDimitry Andric /// 52360b57cec5SDimitry Andric /// \param C AST context. 52370b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 52380b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 52390b57cec5SDimitry Andric /// \param Clauses List of clauses. 52400b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 52410b57cec5SDimitry Andric /// 52420b57cec5SDimitry Andric static OMPTargetTeamsDirective *Create(const ASTContext &C, 52430b57cec5SDimitry Andric SourceLocation StartLoc, 52440b57cec5SDimitry Andric SourceLocation EndLoc, 52450b57cec5SDimitry Andric ArrayRef<OMPClause *> Clauses, 52460b57cec5SDimitry Andric Stmt *AssociatedStmt); 52470b57cec5SDimitry Andric 52480b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses clauses. 52490b57cec5SDimitry Andric /// 52500b57cec5SDimitry Andric /// \param C AST context. 52510b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 52520b57cec5SDimitry Andric /// 52530b57cec5SDimitry Andric static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C, 52540b57cec5SDimitry Andric unsigned NumClauses, EmptyShell); 52550b57cec5SDimitry Andric classof(const Stmt * T)52560b57cec5SDimitry Andric static bool classof(const Stmt *T) { 52570b57cec5SDimitry Andric return T->getStmtClass() == OMPTargetTeamsDirectiveClass; 52580b57cec5SDimitry Andric } 52590b57cec5SDimitry Andric }; 52600b57cec5SDimitry Andric 52610b57cec5SDimitry Andric /// This represents '#pragma omp target teams distribute' combined directive. 52620b57cec5SDimitry Andric /// 52630b57cec5SDimitry Andric /// \code 52640b57cec5SDimitry Andric /// #pragma omp target teams distribute private(x) 52650b57cec5SDimitry Andric /// \endcode 52660b57cec5SDimitry Andric /// In this example directive '#pragma omp target teams distribute' has clause 52670b57cec5SDimitry Andric /// 'private' with the variables 'x' 52680b57cec5SDimitry Andric /// 52690b57cec5SDimitry Andric class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective { 52700b57cec5SDimitry Andric friend class ASTStmtReader; 5271e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 52720b57cec5SDimitry Andric 52730b57cec5SDimitry Andric /// Build directive with the given start and end location. 52740b57cec5SDimitry Andric /// 52750b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 52760b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 52770b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 52780b57cec5SDimitry Andric /// OMPTargetTeamsDistributeDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)52790b57cec5SDimitry Andric OMPTargetTeamsDistributeDirective(SourceLocation StartLoc, 52800b57cec5SDimitry Andric SourceLocation EndLoc, 5281e8d8bef9SDimitry Andric unsigned CollapsedNum) 5282e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass, 5283480093f4SDimitry Andric llvm::omp::OMPD_target_teams_distribute, StartLoc, 5284e8d8bef9SDimitry Andric EndLoc, CollapsedNum) {} 52850b57cec5SDimitry Andric 52860b57cec5SDimitry Andric /// Build an empty directive. 52870b57cec5SDimitry Andric /// 52880b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 52890b57cec5SDimitry Andric /// OMPTargetTeamsDistributeDirective(unsigned CollapsedNum)5290e8d8bef9SDimitry Andric explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum) 5291e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass, 5292480093f4SDimitry Andric llvm::omp::OMPD_target_teams_distribute, 5293e8d8bef9SDimitry Andric SourceLocation(), SourceLocation(), CollapsedNum) {} 52940b57cec5SDimitry Andric 52950b57cec5SDimitry Andric public: 52960b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 52970b57cec5SDimitry Andric /// 52980b57cec5SDimitry Andric /// \param C AST context. 52990b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 53000b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 53010b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 53020b57cec5SDimitry Andric /// \param Clauses List of clauses. 53030b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 53040b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 53050b57cec5SDimitry Andric /// 53060b57cec5SDimitry Andric static OMPTargetTeamsDistributeDirective * 53070b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 53080b57cec5SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 53090b57cec5SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 53100b57cec5SDimitry Andric 53110b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses clauses. 53120b57cec5SDimitry Andric /// 53130b57cec5SDimitry Andric /// \param C AST context. 53140b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 53150b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 53160b57cec5SDimitry Andric /// 53170b57cec5SDimitry Andric static OMPTargetTeamsDistributeDirective * 53180b57cec5SDimitry Andric CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 53190b57cec5SDimitry Andric EmptyShell); 53200b57cec5SDimitry Andric classof(const Stmt * T)53210b57cec5SDimitry Andric static bool classof(const Stmt *T) { 53220b57cec5SDimitry Andric return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass; 53230b57cec5SDimitry Andric } 53240b57cec5SDimitry Andric }; 53250b57cec5SDimitry Andric 53260b57cec5SDimitry Andric /// This represents '#pragma omp target teams distribute parallel for' combined 53270b57cec5SDimitry Andric /// directive. 53280b57cec5SDimitry Andric /// 53290b57cec5SDimitry Andric /// \code 53300b57cec5SDimitry Andric /// #pragma omp target teams distribute parallel for private(x) 53310b57cec5SDimitry Andric /// \endcode 53320b57cec5SDimitry Andric /// In this example directive '#pragma omp target teams distribute parallel 53330b57cec5SDimitry Andric /// for' has clause 'private' with the variables 'x' 53340b57cec5SDimitry Andric /// 53350b57cec5SDimitry Andric class OMPTargetTeamsDistributeParallelForDirective final 53360b57cec5SDimitry Andric : public OMPLoopDirective { 53370b57cec5SDimitry Andric friend class ASTStmtReader; 5338e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 53390b57cec5SDimitry Andric /// true if the construct has inner cancel directive. 53400b57cec5SDimitry Andric bool HasCancel = false; 53410b57cec5SDimitry Andric 53420b57cec5SDimitry Andric /// Build directive with the given start and end location. 53430b57cec5SDimitry Andric /// 53440b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 53450b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 53460b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 53470b57cec5SDimitry Andric /// OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)53480b57cec5SDimitry Andric OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc, 53490b57cec5SDimitry Andric SourceLocation EndLoc, 5350e8d8bef9SDimitry Andric unsigned CollapsedNum) 5351e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass, 5352480093f4SDimitry Andric llvm::omp::OMPD_target_teams_distribute_parallel_for, 5353e8d8bef9SDimitry Andric StartLoc, EndLoc, CollapsedNum) {} 53540b57cec5SDimitry Andric 53550b57cec5SDimitry Andric /// Build an empty directive. 53560b57cec5SDimitry Andric /// 53570b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 53580b57cec5SDimitry Andric /// OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum)5359e8d8bef9SDimitry Andric explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum) 5360e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass, 5361480093f4SDimitry Andric llvm::omp::OMPD_target_teams_distribute_parallel_for, 5362e8d8bef9SDimitry Andric SourceLocation(), SourceLocation(), CollapsedNum) {} 53630b57cec5SDimitry Andric 53645ffd83dbSDimitry Andric /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)5365e8d8bef9SDimitry Andric void setTaskReductionRefExpr(Expr *E) { 5366e8d8bef9SDimitry Andric Data->getChildren()[numLoopChildren( 5367fe6060f1SDimitry Andric getLoopsNumber(), 5368e8d8bef9SDimitry Andric llvm::omp::OMPD_target_teams_distribute_parallel_for)] = E; 5369e8d8bef9SDimitry Andric } 53705ffd83dbSDimitry Andric 53710b57cec5SDimitry Andric /// Set cancel state. setHasCancel(bool Has)53720b57cec5SDimitry Andric void setHasCancel(bool Has) { HasCancel = Has; } 53730b57cec5SDimitry Andric 53740b57cec5SDimitry Andric public: 53750b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 53760b57cec5SDimitry Andric /// 53770b57cec5SDimitry Andric /// \param C AST context. 53780b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 53790b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 53800b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 53810b57cec5SDimitry Andric /// \param Clauses List of clauses. 53820b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 53830b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 53845ffd83dbSDimitry Andric /// \param TaskRedRef Task reduction special reference expression to handle 53855ffd83dbSDimitry Andric /// taskgroup descriptor. 53860b57cec5SDimitry Andric /// \param HasCancel true if this directive has inner cancel directive. 53870b57cec5SDimitry Andric /// 53880b57cec5SDimitry Andric static OMPTargetTeamsDistributeParallelForDirective * 53890b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 53900b57cec5SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 53915ffd83dbSDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 53925ffd83dbSDimitry Andric bool HasCancel); 53930b57cec5SDimitry Andric 53940b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses clauses. 53950b57cec5SDimitry Andric /// 53960b57cec5SDimitry Andric /// \param C AST context. 53970b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 53980b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 53990b57cec5SDimitry Andric /// 54000b57cec5SDimitry Andric static OMPTargetTeamsDistributeParallelForDirective * 54010b57cec5SDimitry Andric CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 54020b57cec5SDimitry Andric EmptyShell); 54030b57cec5SDimitry Andric 54045ffd83dbSDimitry Andric /// Returns special task reduction reference expression. getTaskReductionRefExpr()5405e8d8bef9SDimitry Andric Expr *getTaskReductionRefExpr() { 5406e8d8bef9SDimitry Andric return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 5407fe6060f1SDimitry Andric getLoopsNumber(), 5408e8d8bef9SDimitry Andric llvm::omp::OMPD_target_teams_distribute_parallel_for)]); 5409e8d8bef9SDimitry Andric } getTaskReductionRefExpr()5410e8d8bef9SDimitry Andric const Expr *getTaskReductionRefExpr() const { 5411e8d8bef9SDimitry Andric return const_cast<OMPTargetTeamsDistributeParallelForDirective *>(this) 5412e8d8bef9SDimitry Andric ->getTaskReductionRefExpr(); 5413e8d8bef9SDimitry Andric } 54145ffd83dbSDimitry Andric 54150b57cec5SDimitry Andric /// Return true if current directive has inner cancel directive. hasCancel()54160b57cec5SDimitry Andric bool hasCancel() const { return HasCancel; } 54170b57cec5SDimitry Andric classof(const Stmt * T)54180b57cec5SDimitry Andric static bool classof(const Stmt *T) { 54190b57cec5SDimitry Andric return T->getStmtClass() == 54200b57cec5SDimitry Andric OMPTargetTeamsDistributeParallelForDirectiveClass; 54210b57cec5SDimitry Andric } 54220b57cec5SDimitry Andric }; 54230b57cec5SDimitry Andric 54240b57cec5SDimitry Andric /// This represents '#pragma omp target teams distribute parallel for simd' 54250b57cec5SDimitry Andric /// combined directive. 54260b57cec5SDimitry Andric /// 54270b57cec5SDimitry Andric /// \code 54280b57cec5SDimitry Andric /// #pragma omp target teams distribute parallel for simd private(x) 54290b57cec5SDimitry Andric /// \endcode 54300b57cec5SDimitry Andric /// In this example directive '#pragma omp target teams distribute parallel 54310b57cec5SDimitry Andric /// for simd' has clause 'private' with the variables 'x' 54320b57cec5SDimitry Andric /// 54330b57cec5SDimitry Andric class OMPTargetTeamsDistributeParallelForSimdDirective final 54340b57cec5SDimitry Andric : public OMPLoopDirective { 54350b57cec5SDimitry Andric friend class ASTStmtReader; 5436e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 54370b57cec5SDimitry Andric 54380b57cec5SDimitry Andric /// Build directive with the given start and end location. 54390b57cec5SDimitry Andric /// 54400b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 54410b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 54420b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 54430b57cec5SDimitry Andric /// OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)54440b57cec5SDimitry Andric OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc, 54450b57cec5SDimitry Andric SourceLocation EndLoc, 5446e8d8bef9SDimitry Andric unsigned CollapsedNum) 5447480093f4SDimitry Andric : OMPLoopDirective( 5448e8d8bef9SDimitry Andric OMPTargetTeamsDistributeParallelForSimdDirectiveClass, 5449480093f4SDimitry Andric llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, StartLoc, 5450e8d8bef9SDimitry Andric EndLoc, CollapsedNum) {} 54510b57cec5SDimitry Andric 54520b57cec5SDimitry Andric /// Build an empty directive. 54530b57cec5SDimitry Andric /// 54540b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 54550b57cec5SDimitry Andric /// OMPTargetTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum)54560b57cec5SDimitry Andric explicit OMPTargetTeamsDistributeParallelForSimdDirective( 5457e8d8bef9SDimitry Andric unsigned CollapsedNum) 54580b57cec5SDimitry Andric : OMPLoopDirective( 5459e8d8bef9SDimitry Andric OMPTargetTeamsDistributeParallelForSimdDirectiveClass, 5460480093f4SDimitry Andric llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, 5461e8d8bef9SDimitry Andric SourceLocation(), SourceLocation(), CollapsedNum) {} 54620b57cec5SDimitry Andric 54630b57cec5SDimitry Andric public: 54640b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 54650b57cec5SDimitry Andric /// 54660b57cec5SDimitry Andric /// \param C AST context. 54670b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 54680b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 54690b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 54700b57cec5SDimitry Andric /// \param Clauses List of clauses. 54710b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 54720b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 54730b57cec5SDimitry Andric /// 54740b57cec5SDimitry Andric static OMPTargetTeamsDistributeParallelForSimdDirective * 54750b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 54760b57cec5SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 54770b57cec5SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 54780b57cec5SDimitry Andric 54790b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses clauses. 54800b57cec5SDimitry Andric /// 54810b57cec5SDimitry Andric /// \param C AST context. 54820b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 54830b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 54840b57cec5SDimitry Andric /// 54850b57cec5SDimitry Andric static OMPTargetTeamsDistributeParallelForSimdDirective * 54860b57cec5SDimitry Andric CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 54870b57cec5SDimitry Andric EmptyShell); 54880b57cec5SDimitry Andric classof(const Stmt * T)54890b57cec5SDimitry Andric static bool classof(const Stmt *T) { 54900b57cec5SDimitry Andric return T->getStmtClass() == 54910b57cec5SDimitry Andric OMPTargetTeamsDistributeParallelForSimdDirectiveClass; 54920b57cec5SDimitry Andric } 54930b57cec5SDimitry Andric }; 54940b57cec5SDimitry Andric 54950b57cec5SDimitry Andric /// This represents '#pragma omp target teams distribute simd' combined 54960b57cec5SDimitry Andric /// directive. 54970b57cec5SDimitry Andric /// 54980b57cec5SDimitry Andric /// \code 54990b57cec5SDimitry Andric /// #pragma omp target teams distribute simd private(x) 55000b57cec5SDimitry Andric /// \endcode 55010b57cec5SDimitry Andric /// In this example directive '#pragma omp target teams distribute simd' 55020b57cec5SDimitry Andric /// has clause 'private' with the variables 'x' 55030b57cec5SDimitry Andric /// 55040b57cec5SDimitry Andric class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective { 55050b57cec5SDimitry Andric friend class ASTStmtReader; 5506e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 55070b57cec5SDimitry Andric 55080b57cec5SDimitry Andric /// Build directive with the given start and end location. 55090b57cec5SDimitry Andric /// 55100b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 55110b57cec5SDimitry Andric /// \param EndLoc Ending location of the directive. 55120b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 55130b57cec5SDimitry Andric /// OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)55140b57cec5SDimitry Andric OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc, 55150b57cec5SDimitry Andric SourceLocation EndLoc, 5516e8d8bef9SDimitry Andric unsigned CollapsedNum) 5517e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass, 5518480093f4SDimitry Andric llvm::omp::OMPD_target_teams_distribute_simd, StartLoc, 5519e8d8bef9SDimitry Andric EndLoc, CollapsedNum) {} 55200b57cec5SDimitry Andric 55210b57cec5SDimitry Andric /// Build an empty directive. 55220b57cec5SDimitry Andric /// 55230b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 55240b57cec5SDimitry Andric /// OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum)5525e8d8bef9SDimitry Andric explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum) 5526e8d8bef9SDimitry Andric : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass, 5527480093f4SDimitry Andric llvm::omp::OMPD_target_teams_distribute_simd, 5528e8d8bef9SDimitry Andric SourceLocation(), SourceLocation(), CollapsedNum) {} 55290b57cec5SDimitry Andric 55300b57cec5SDimitry Andric public: 55310b57cec5SDimitry Andric /// Creates directive with a list of \a Clauses. 55320b57cec5SDimitry Andric /// 55330b57cec5SDimitry Andric /// \param C AST context. 55340b57cec5SDimitry Andric /// \param StartLoc Starting location of the directive kind. 55350b57cec5SDimitry Andric /// \param EndLoc Ending Location of the directive. 55360b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 55370b57cec5SDimitry Andric /// \param Clauses List of clauses. 55380b57cec5SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 55390b57cec5SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 55400b57cec5SDimitry Andric /// 55410b57cec5SDimitry Andric static OMPTargetTeamsDistributeSimdDirective * 55420b57cec5SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 55430b57cec5SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 55440b57cec5SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 55450b57cec5SDimitry Andric 55460b57cec5SDimitry Andric /// Creates an empty directive with the place for \a NumClauses clauses. 55470b57cec5SDimitry Andric /// 55480b57cec5SDimitry Andric /// \param C AST context. 55490b57cec5SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 55500b57cec5SDimitry Andric /// \param NumClauses Number of clauses. 55510b57cec5SDimitry Andric /// 55520b57cec5SDimitry Andric static OMPTargetTeamsDistributeSimdDirective * 55530b57cec5SDimitry Andric CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 55540b57cec5SDimitry Andric EmptyShell); 55550b57cec5SDimitry Andric classof(const Stmt * T)55560b57cec5SDimitry Andric static bool classof(const Stmt *T) { 55570b57cec5SDimitry Andric return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass; 55580b57cec5SDimitry Andric } 55590b57cec5SDimitry Andric }; 55600b57cec5SDimitry Andric 5561fe6060f1SDimitry Andric /// This represents the '#pragma omp tile' loop transformation directive. 5562349cc55cSDimitry Andric class OMPTileDirective final : public OMPLoopTransformationDirective { 5563fe6060f1SDimitry Andric friend class ASTStmtReader; 5564fe6060f1SDimitry Andric friend class OMPExecutableDirective; 5565fe6060f1SDimitry Andric 5566fe6060f1SDimitry Andric /// Default list of offsets. 5567fe6060f1SDimitry Andric enum { 5568fe6060f1SDimitry Andric PreInitsOffset = 0, 5569fe6060f1SDimitry Andric TransformedStmtOffset, 5570fe6060f1SDimitry Andric }; 5571fe6060f1SDimitry Andric OMPTileDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumLoops)5572fe6060f1SDimitry Andric explicit OMPTileDirective(SourceLocation StartLoc, SourceLocation EndLoc, 5573fe6060f1SDimitry Andric unsigned NumLoops) 5574349cc55cSDimitry Andric : OMPLoopTransformationDirective(OMPTileDirectiveClass, 5575349cc55cSDimitry Andric llvm::omp::OMPD_tile, StartLoc, EndLoc, 5576349cc55cSDimitry Andric NumLoops) { 5577349cc55cSDimitry Andric setNumGeneratedLoops(3 * NumLoops); 5578349cc55cSDimitry Andric } 5579fe6060f1SDimitry Andric setPreInits(Stmt * PreInits)5580fe6060f1SDimitry Andric void setPreInits(Stmt *PreInits) { 5581fe6060f1SDimitry Andric Data->getChildren()[PreInitsOffset] = PreInits; 5582fe6060f1SDimitry Andric } 5583fe6060f1SDimitry Andric setTransformedStmt(Stmt * S)5584fe6060f1SDimitry Andric void setTransformedStmt(Stmt *S) { 5585fe6060f1SDimitry Andric Data->getChildren()[TransformedStmtOffset] = S; 5586fe6060f1SDimitry Andric } 5587fe6060f1SDimitry Andric 5588fe6060f1SDimitry Andric public: 5589fe6060f1SDimitry Andric /// Create a new AST node representation for '#pragma omp tile'. 5590fe6060f1SDimitry Andric /// 5591fe6060f1SDimitry Andric /// \param C Context of the AST. 5592fe6060f1SDimitry Andric /// \param StartLoc Location of the introducer (e.g. the 'omp' token). 5593fe6060f1SDimitry Andric /// \param EndLoc Location of the directive's end (e.g. the tok::eod). 5594fe6060f1SDimitry Andric /// \param Clauses The directive's clauses. 5595fe6060f1SDimitry Andric /// \param NumLoops Number of associated loops (number of items in the 5596fe6060f1SDimitry Andric /// 'sizes' clause). 5597fe6060f1SDimitry Andric /// \param AssociatedStmt The outermost associated loop. 5598fe6060f1SDimitry Andric /// \param TransformedStmt The loop nest after tiling, or nullptr in 5599fe6060f1SDimitry Andric /// dependent contexts. 5600fe6060f1SDimitry Andric /// \param PreInits Helper preinits statements for the loop nest. 5601fe6060f1SDimitry Andric static OMPTileDirective *Create(const ASTContext &C, SourceLocation StartLoc, 5602fe6060f1SDimitry Andric SourceLocation EndLoc, 5603fe6060f1SDimitry Andric ArrayRef<OMPClause *> Clauses, 5604fe6060f1SDimitry Andric unsigned NumLoops, Stmt *AssociatedStmt, 5605fe6060f1SDimitry Andric Stmt *TransformedStmt, Stmt *PreInits); 5606fe6060f1SDimitry Andric 5607fe6060f1SDimitry Andric /// Build an empty '#pragma omp tile' AST node for deserialization. 5608fe6060f1SDimitry Andric /// 5609fe6060f1SDimitry Andric /// \param C Context of the AST. 5610fe6060f1SDimitry Andric /// \param NumClauses Number of clauses to allocate. 5611fe6060f1SDimitry Andric /// \param NumLoops Number of associated loops to allocate. 5612fe6060f1SDimitry Andric static OMPTileDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 5613fe6060f1SDimitry Andric unsigned NumLoops); 5614fe6060f1SDimitry Andric 5615fe6060f1SDimitry Andric /// Gets/sets the associated loops after tiling. 5616fe6060f1SDimitry Andric /// 5617fe6060f1SDimitry Andric /// This is in de-sugared format stored as a CompoundStmt. 5618fe6060f1SDimitry Andric /// 5619fe6060f1SDimitry Andric /// \code 5620fe6060f1SDimitry Andric /// for (...) 5621fe6060f1SDimitry Andric /// ... 5622fe6060f1SDimitry Andric /// \endcode 5623fe6060f1SDimitry Andric /// 5624fe6060f1SDimitry Andric /// Note that if the generated loops a become associated loops of another 5625fe6060f1SDimitry Andric /// directive, they may need to be hoisted before them. getTransformedStmt()5626fe6060f1SDimitry Andric Stmt *getTransformedStmt() const { 5627fe6060f1SDimitry Andric return Data->getChildren()[TransformedStmtOffset]; 5628fe6060f1SDimitry Andric } 5629fe6060f1SDimitry Andric 5630fe6060f1SDimitry Andric /// Return preinits statement. getPreInits()5631fe6060f1SDimitry Andric Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } 5632fe6060f1SDimitry Andric classof(const Stmt * T)5633fe6060f1SDimitry Andric static bool classof(const Stmt *T) { 5634fe6060f1SDimitry Andric return T->getStmtClass() == OMPTileDirectiveClass; 5635fe6060f1SDimitry Andric } 5636fe6060f1SDimitry Andric }; 5637fe6060f1SDimitry Andric 5638fe6060f1SDimitry Andric /// This represents the '#pragma omp unroll' loop transformation directive. 5639fe6060f1SDimitry Andric /// 5640fe6060f1SDimitry Andric /// \code 5641fe6060f1SDimitry Andric /// #pragma omp unroll 5642fe6060f1SDimitry Andric /// for (int i = 0; i < 64; ++i) 5643fe6060f1SDimitry Andric /// \endcode 5644349cc55cSDimitry Andric class OMPUnrollDirective final : public OMPLoopTransformationDirective { 5645fe6060f1SDimitry Andric friend class ASTStmtReader; 5646fe6060f1SDimitry Andric friend class OMPExecutableDirective; 5647fe6060f1SDimitry Andric 5648fe6060f1SDimitry Andric /// Default list of offsets. 5649fe6060f1SDimitry Andric enum { 5650fe6060f1SDimitry Andric PreInitsOffset = 0, 5651fe6060f1SDimitry Andric TransformedStmtOffset, 5652fe6060f1SDimitry Andric }; 5653fe6060f1SDimitry Andric OMPUnrollDirective(SourceLocation StartLoc,SourceLocation EndLoc)5654fe6060f1SDimitry Andric explicit OMPUnrollDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5655349cc55cSDimitry Andric : OMPLoopTransformationDirective(OMPUnrollDirectiveClass, 5656349cc55cSDimitry Andric llvm::omp::OMPD_unroll, StartLoc, EndLoc, 5657349cc55cSDimitry Andric 1) {} 5658fe6060f1SDimitry Andric 5659fe6060f1SDimitry Andric /// Set the pre-init statements. setPreInits(Stmt * PreInits)5660fe6060f1SDimitry Andric void setPreInits(Stmt *PreInits) { 5661fe6060f1SDimitry Andric Data->getChildren()[PreInitsOffset] = PreInits; 5662fe6060f1SDimitry Andric } 5663fe6060f1SDimitry Andric 5664fe6060f1SDimitry Andric /// Set the de-sugared statement. setTransformedStmt(Stmt * S)5665fe6060f1SDimitry Andric void setTransformedStmt(Stmt *S) { 5666fe6060f1SDimitry Andric Data->getChildren()[TransformedStmtOffset] = S; 5667fe6060f1SDimitry Andric } 5668fe6060f1SDimitry Andric 5669fe6060f1SDimitry Andric public: 5670fe6060f1SDimitry Andric /// Create a new AST node representation for '#pragma omp unroll'. 5671fe6060f1SDimitry Andric /// 5672fe6060f1SDimitry Andric /// \param C Context of the AST. 5673fe6060f1SDimitry Andric /// \param StartLoc Location of the introducer (e.g. the 'omp' token). 5674fe6060f1SDimitry Andric /// \param EndLoc Location of the directive's end (e.g. the tok::eod). 5675fe6060f1SDimitry Andric /// \param Clauses The directive's clauses. 5676fe6060f1SDimitry Andric /// \param AssociatedStmt The outermost associated loop. 5677fe6060f1SDimitry Andric /// \param TransformedStmt The loop nest after tiling, or nullptr in 5678fe6060f1SDimitry Andric /// dependent contexts. 5679fe6060f1SDimitry Andric /// \param PreInits Helper preinits statements for the loop nest. 5680fe6060f1SDimitry Andric static OMPUnrollDirective * 5681fe6060f1SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5682fe6060f1SDimitry Andric ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, 5683349cc55cSDimitry Andric unsigned NumGeneratedLoops, Stmt *TransformedStmt, Stmt *PreInits); 5684fe6060f1SDimitry Andric 5685fe6060f1SDimitry Andric /// Build an empty '#pragma omp unroll' AST node for deserialization. 5686fe6060f1SDimitry Andric /// 5687fe6060f1SDimitry Andric /// \param C Context of the AST. 5688fe6060f1SDimitry Andric /// \param NumClauses Number of clauses to allocate. 5689fe6060f1SDimitry Andric static OMPUnrollDirective *CreateEmpty(const ASTContext &C, 5690fe6060f1SDimitry Andric unsigned NumClauses); 5691fe6060f1SDimitry Andric 5692fe6060f1SDimitry Andric /// Get the de-sugared associated loops after unrolling. 5693fe6060f1SDimitry Andric /// 5694fe6060f1SDimitry Andric /// This is only used if the unrolled loop becomes an associated loop of 5695fe6060f1SDimitry Andric /// another directive, otherwise the loop is emitted directly using loop 5696fe6060f1SDimitry Andric /// transformation metadata. When the unrolled loop cannot be used by another 5697fe6060f1SDimitry Andric /// directive (e.g. because of the full clause), the transformed stmt can also 5698fe6060f1SDimitry Andric /// be nullptr. getTransformedStmt()5699fe6060f1SDimitry Andric Stmt *getTransformedStmt() const { 5700fe6060f1SDimitry Andric return Data->getChildren()[TransformedStmtOffset]; 5701fe6060f1SDimitry Andric } 5702fe6060f1SDimitry Andric 5703fe6060f1SDimitry Andric /// Return the pre-init statements. getPreInits()5704fe6060f1SDimitry Andric Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } 5705fe6060f1SDimitry Andric classof(const Stmt * T)5706fe6060f1SDimitry Andric static bool classof(const Stmt *T) { 5707fe6060f1SDimitry Andric return T->getStmtClass() == OMPUnrollDirectiveClass; 5708fe6060f1SDimitry Andric } 5709fe6060f1SDimitry Andric }; 5710fe6060f1SDimitry Andric 57115ffd83dbSDimitry Andric /// This represents '#pragma omp scan' directive. 57125ffd83dbSDimitry Andric /// 57135ffd83dbSDimitry Andric /// \code 57145ffd83dbSDimitry Andric /// #pragma omp scan inclusive(a) 57155ffd83dbSDimitry Andric /// \endcode 57165ffd83dbSDimitry Andric /// In this example directive '#pragma omp scan' has clause 'inclusive' with 57175ffd83dbSDimitry Andric /// list item 'a'. 57185ffd83dbSDimitry Andric class OMPScanDirective final : public OMPExecutableDirective { 57195ffd83dbSDimitry Andric friend class ASTStmtReader; 5720e8d8bef9SDimitry Andric friend class OMPExecutableDirective; 57215ffd83dbSDimitry Andric /// Build directive with the given start and end location. 57225ffd83dbSDimitry Andric /// 57235ffd83dbSDimitry Andric /// \param StartLoc Starting location of the directive kind. 57245ffd83dbSDimitry Andric /// \param EndLoc Ending location of the directive. 57255ffd83dbSDimitry Andric /// OMPScanDirective(SourceLocation StartLoc,SourceLocation EndLoc)5726e8d8bef9SDimitry Andric OMPScanDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5727e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan, 5728e8d8bef9SDimitry Andric StartLoc, EndLoc) {} 57295ffd83dbSDimitry Andric 57305ffd83dbSDimitry Andric /// Build an empty directive. 57315ffd83dbSDimitry Andric /// OMPScanDirective()5732e8d8bef9SDimitry Andric explicit OMPScanDirective() 5733e8d8bef9SDimitry Andric : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan, 5734e8d8bef9SDimitry Andric SourceLocation(), SourceLocation()) {} 57355ffd83dbSDimitry Andric 57365ffd83dbSDimitry Andric public: 57375ffd83dbSDimitry Andric /// Creates directive with a list of \a Clauses. 57385ffd83dbSDimitry Andric /// 57395ffd83dbSDimitry Andric /// \param C AST context. 57405ffd83dbSDimitry Andric /// \param StartLoc Starting location of the directive kind. 57415ffd83dbSDimitry Andric /// \param EndLoc Ending Location of the directive. 57425ffd83dbSDimitry Andric /// \param Clauses List of clauses (only single OMPFlushClause clause is 57435ffd83dbSDimitry Andric /// allowed). 57445ffd83dbSDimitry Andric /// 57455ffd83dbSDimitry Andric static OMPScanDirective *Create(const ASTContext &C, SourceLocation StartLoc, 57465ffd83dbSDimitry Andric SourceLocation EndLoc, 57475ffd83dbSDimitry Andric ArrayRef<OMPClause *> Clauses); 57485ffd83dbSDimitry Andric 57495ffd83dbSDimitry Andric /// Creates an empty directive with the place for \a NumClauses 57505ffd83dbSDimitry Andric /// clauses. 57515ffd83dbSDimitry Andric /// 57525ffd83dbSDimitry Andric /// \param C AST context. 57535ffd83dbSDimitry Andric /// \param NumClauses Number of clauses. 57545ffd83dbSDimitry Andric /// 57555ffd83dbSDimitry Andric static OMPScanDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 57565ffd83dbSDimitry Andric EmptyShell); 57575ffd83dbSDimitry Andric classof(const Stmt * T)57585ffd83dbSDimitry Andric static bool classof(const Stmt *T) { 57595ffd83dbSDimitry Andric return T->getStmtClass() == OMPScanDirectiveClass; 57605ffd83dbSDimitry Andric } 57615ffd83dbSDimitry Andric }; 57625ffd83dbSDimitry Andric 5763fe6060f1SDimitry Andric /// This represents '#pragma omp interop' directive. 5764fe6060f1SDimitry Andric /// 5765fe6060f1SDimitry Andric /// \code 5766fe6060f1SDimitry Andric /// #pragma omp interop init(target:obj) device(x) depend(inout:y) nowait 5767fe6060f1SDimitry Andric /// \endcode 5768fe6060f1SDimitry Andric /// In this example directive '#pragma omp interop' has 5769fe6060f1SDimitry Andric /// clauses 'init', 'device', 'depend' and 'nowait'. 5770fe6060f1SDimitry Andric /// 5771fe6060f1SDimitry Andric class OMPInteropDirective final : public OMPExecutableDirective { 5772fe6060f1SDimitry Andric friend class ASTStmtReader; 5773fe6060f1SDimitry Andric friend class OMPExecutableDirective; 5774fe6060f1SDimitry Andric 5775fe6060f1SDimitry Andric /// Build directive with the given start and end location. 5776fe6060f1SDimitry Andric /// 5777fe6060f1SDimitry Andric /// \param StartLoc Starting location of the directive. 5778fe6060f1SDimitry Andric /// \param EndLoc Ending location of the directive. 5779fe6060f1SDimitry Andric /// OMPInteropDirective(SourceLocation StartLoc,SourceLocation EndLoc)5780fe6060f1SDimitry Andric OMPInteropDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5781fe6060f1SDimitry Andric : OMPExecutableDirective(OMPInteropDirectiveClass, 5782fe6060f1SDimitry Andric llvm::omp::OMPD_interop, StartLoc, EndLoc) {} 5783fe6060f1SDimitry Andric 5784fe6060f1SDimitry Andric /// Build an empty directive. 5785fe6060f1SDimitry Andric /// OMPInteropDirective()5786fe6060f1SDimitry Andric explicit OMPInteropDirective() 5787fe6060f1SDimitry Andric : OMPExecutableDirective(OMPInteropDirectiveClass, 5788fe6060f1SDimitry Andric llvm::omp::OMPD_interop, SourceLocation(), 5789fe6060f1SDimitry Andric SourceLocation()) {} 5790fe6060f1SDimitry Andric 5791fe6060f1SDimitry Andric public: 5792fe6060f1SDimitry Andric /// Creates directive. 5793fe6060f1SDimitry Andric /// 5794fe6060f1SDimitry Andric /// \param C AST context. 5795fe6060f1SDimitry Andric /// \param StartLoc Starting location of the directive. 5796fe6060f1SDimitry Andric /// \param EndLoc Ending Location of the directive. 5797fe6060f1SDimitry Andric /// \param Clauses The directive's clauses. 5798fe6060f1SDimitry Andric /// 5799fe6060f1SDimitry Andric static OMPInteropDirective *Create(const ASTContext &C, 5800fe6060f1SDimitry Andric SourceLocation StartLoc, 5801fe6060f1SDimitry Andric SourceLocation EndLoc, 5802fe6060f1SDimitry Andric ArrayRef<OMPClause *> Clauses); 5803fe6060f1SDimitry Andric 5804fe6060f1SDimitry Andric /// Creates an empty directive. 5805fe6060f1SDimitry Andric /// 5806fe6060f1SDimitry Andric /// \param C AST context. 5807fe6060f1SDimitry Andric /// 5808fe6060f1SDimitry Andric static OMPInteropDirective *CreateEmpty(const ASTContext &C, 5809fe6060f1SDimitry Andric unsigned NumClauses, EmptyShell); 5810fe6060f1SDimitry Andric classof(const Stmt * T)5811fe6060f1SDimitry Andric static bool classof(const Stmt *T) { 5812fe6060f1SDimitry Andric return T->getStmtClass() == OMPInteropDirectiveClass; 5813fe6060f1SDimitry Andric } 5814fe6060f1SDimitry Andric }; 5815fe6060f1SDimitry Andric 5816fe6060f1SDimitry Andric /// This represents '#pragma omp dispatch' directive. 5817fe6060f1SDimitry Andric /// 5818fe6060f1SDimitry Andric /// \code 5819fe6060f1SDimitry Andric /// #pragma omp dispatch device(dnum) 5820fe6060f1SDimitry Andric /// \endcode 5821fe6060f1SDimitry Andric /// This example shows a directive '#pragma omp dispatch' with a 5822fe6060f1SDimitry Andric /// device clause with variable 'dnum'. 5823fe6060f1SDimitry Andric /// 5824fe6060f1SDimitry Andric class OMPDispatchDirective final : public OMPExecutableDirective { 5825fe6060f1SDimitry Andric friend class ASTStmtReader; 5826fe6060f1SDimitry Andric friend class OMPExecutableDirective; 5827fe6060f1SDimitry Andric 5828fe6060f1SDimitry Andric /// The location of the target-call. 5829fe6060f1SDimitry Andric SourceLocation TargetCallLoc; 5830fe6060f1SDimitry Andric 5831fe6060f1SDimitry Andric /// Set the location of the target-call. setTargetCallLoc(SourceLocation Loc)5832fe6060f1SDimitry Andric void setTargetCallLoc(SourceLocation Loc) { TargetCallLoc = Loc; } 5833fe6060f1SDimitry Andric 5834fe6060f1SDimitry Andric /// Build directive with the given start and end location. 5835fe6060f1SDimitry Andric /// 5836fe6060f1SDimitry Andric /// \param StartLoc Starting location of the directive kind. 5837fe6060f1SDimitry Andric /// \param EndLoc Ending location of the directive. 5838fe6060f1SDimitry Andric /// OMPDispatchDirective(SourceLocation StartLoc,SourceLocation EndLoc)5839fe6060f1SDimitry Andric OMPDispatchDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5840fe6060f1SDimitry Andric : OMPExecutableDirective(OMPDispatchDirectiveClass, 5841fe6060f1SDimitry Andric llvm::omp::OMPD_dispatch, StartLoc, EndLoc) {} 5842fe6060f1SDimitry Andric 5843fe6060f1SDimitry Andric /// Build an empty directive. 5844fe6060f1SDimitry Andric /// OMPDispatchDirective()5845fe6060f1SDimitry Andric explicit OMPDispatchDirective() 5846fe6060f1SDimitry Andric : OMPExecutableDirective(OMPDispatchDirectiveClass, 5847fe6060f1SDimitry Andric llvm::omp::OMPD_dispatch, SourceLocation(), 5848fe6060f1SDimitry Andric SourceLocation()) {} 5849fe6060f1SDimitry Andric 5850fe6060f1SDimitry Andric public: 5851fe6060f1SDimitry Andric /// Creates directive with a list of \a Clauses. 5852fe6060f1SDimitry Andric /// 5853fe6060f1SDimitry Andric /// \param C AST context. 5854fe6060f1SDimitry Andric /// \param StartLoc Starting location of the directive kind. 5855fe6060f1SDimitry Andric /// \param EndLoc Ending Location of the directive. 5856fe6060f1SDimitry Andric /// \param Clauses List of clauses. 5857fe6060f1SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 5858fe6060f1SDimitry Andric /// \param TargetCallLoc Location of the target-call. 5859fe6060f1SDimitry Andric /// 5860fe6060f1SDimitry Andric static OMPDispatchDirective * 5861fe6060f1SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5862fe6060f1SDimitry Andric ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, 5863fe6060f1SDimitry Andric SourceLocation TargetCallLoc); 5864fe6060f1SDimitry Andric 5865fe6060f1SDimitry Andric /// Creates an empty directive with the place for \a NumClauses 5866fe6060f1SDimitry Andric /// clauses. 5867fe6060f1SDimitry Andric /// 5868fe6060f1SDimitry Andric /// \param C AST context. 5869fe6060f1SDimitry Andric /// \param NumClauses Number of clauses. 5870fe6060f1SDimitry Andric /// 5871fe6060f1SDimitry Andric static OMPDispatchDirective *CreateEmpty(const ASTContext &C, 5872fe6060f1SDimitry Andric unsigned NumClauses, EmptyShell); 5873fe6060f1SDimitry Andric 5874fe6060f1SDimitry Andric /// Return location of target-call. getTargetCallLoc()5875fe6060f1SDimitry Andric SourceLocation getTargetCallLoc() const { return TargetCallLoc; } 5876fe6060f1SDimitry Andric classof(const Stmt * T)5877fe6060f1SDimitry Andric static bool classof(const Stmt *T) { 5878fe6060f1SDimitry Andric return T->getStmtClass() == OMPDispatchDirectiveClass; 5879fe6060f1SDimitry Andric } 5880fe6060f1SDimitry Andric }; 5881fe6060f1SDimitry Andric 5882fe6060f1SDimitry Andric /// This represents '#pragma omp masked' directive. 5883fe6060f1SDimitry Andric /// \code 5884fe6060f1SDimitry Andric /// #pragma omp masked filter(tid) 5885fe6060f1SDimitry Andric /// \endcode 5886fe6060f1SDimitry Andric /// This example shows a directive '#pragma omp masked' with a filter clause 5887fe6060f1SDimitry Andric /// with variable 'tid'. 5888fe6060f1SDimitry Andric /// 5889fe6060f1SDimitry Andric class OMPMaskedDirective final : public OMPExecutableDirective { 5890fe6060f1SDimitry Andric friend class ASTStmtReader; 5891fe6060f1SDimitry Andric friend class OMPExecutableDirective; 5892fe6060f1SDimitry Andric 5893fe6060f1SDimitry Andric /// Build directive with the given start and end location. 5894fe6060f1SDimitry Andric /// 5895fe6060f1SDimitry Andric /// \param StartLoc Starting location of the directive kind. 5896fe6060f1SDimitry Andric /// \param EndLoc Ending location of the directive. 5897fe6060f1SDimitry Andric /// OMPMaskedDirective(SourceLocation StartLoc,SourceLocation EndLoc)5898fe6060f1SDimitry Andric OMPMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5899fe6060f1SDimitry Andric : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked, 5900fe6060f1SDimitry Andric StartLoc, EndLoc) {} 5901fe6060f1SDimitry Andric 5902fe6060f1SDimitry Andric /// Build an empty directive. 5903fe6060f1SDimitry Andric /// OMPMaskedDirective()5904fe6060f1SDimitry Andric explicit OMPMaskedDirective() 5905fe6060f1SDimitry Andric : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked, 5906fe6060f1SDimitry Andric SourceLocation(), SourceLocation()) {} 5907fe6060f1SDimitry Andric 5908fe6060f1SDimitry Andric public: 5909fe6060f1SDimitry Andric /// Creates directive. 5910fe6060f1SDimitry Andric /// 5911fe6060f1SDimitry Andric /// \param C AST context. 5912fe6060f1SDimitry Andric /// \param StartLoc Starting location of the directive kind. 5913fe6060f1SDimitry Andric /// \param EndLoc Ending Location of the directive. 5914fe6060f1SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 5915fe6060f1SDimitry Andric /// 5916fe6060f1SDimitry Andric static OMPMaskedDirective * 5917fe6060f1SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5918fe6060f1SDimitry Andric ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 5919fe6060f1SDimitry Andric 5920fe6060f1SDimitry Andric /// Creates an empty directive. 5921fe6060f1SDimitry Andric /// 5922fe6060f1SDimitry Andric /// \param C AST context. 5923fe6060f1SDimitry Andric /// 5924fe6060f1SDimitry Andric static OMPMaskedDirective *CreateEmpty(const ASTContext &C, 5925fe6060f1SDimitry Andric unsigned NumClauses, EmptyShell); 5926fe6060f1SDimitry Andric classof(const Stmt * T)5927fe6060f1SDimitry Andric static bool classof(const Stmt *T) { 5928fe6060f1SDimitry Andric return T->getStmtClass() == OMPMaskedDirectiveClass; 5929fe6060f1SDimitry Andric } 5930fe6060f1SDimitry Andric }; 5931fe6060f1SDimitry Andric 5932349cc55cSDimitry Andric /// This represents '#pragma omp metadirective' directive. 5933349cc55cSDimitry Andric /// 5934349cc55cSDimitry Andric /// \code 5935349cc55cSDimitry Andric /// #pragma omp metadirective when(user={condition(N>10)}: parallel for) 5936349cc55cSDimitry Andric /// \endcode 5937349cc55cSDimitry Andric /// In this example directive '#pragma omp metadirective' has clauses 'when' 5938349cc55cSDimitry Andric /// with a dynamic user condition to check if a variable 'N > 10' 5939349cc55cSDimitry Andric /// 5940349cc55cSDimitry Andric class OMPMetaDirective final : public OMPExecutableDirective { 5941349cc55cSDimitry Andric friend class ASTStmtReader; 5942349cc55cSDimitry Andric friend class OMPExecutableDirective; 5943349cc55cSDimitry Andric Stmt *IfStmt; 5944349cc55cSDimitry Andric OMPMetaDirective(SourceLocation StartLoc,SourceLocation EndLoc)5945349cc55cSDimitry Andric OMPMetaDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5946349cc55cSDimitry Andric : OMPExecutableDirective(OMPMetaDirectiveClass, 5947349cc55cSDimitry Andric llvm::omp::OMPD_metadirective, StartLoc, 5948349cc55cSDimitry Andric EndLoc) {} OMPMetaDirective()5949349cc55cSDimitry Andric explicit OMPMetaDirective() 5950349cc55cSDimitry Andric : OMPExecutableDirective(OMPMetaDirectiveClass, 5951349cc55cSDimitry Andric llvm::omp::OMPD_metadirective, SourceLocation(), 5952349cc55cSDimitry Andric SourceLocation()) {} 5953349cc55cSDimitry Andric setIfStmt(Stmt * S)5954349cc55cSDimitry Andric void setIfStmt(Stmt *S) { IfStmt = S; } 5955349cc55cSDimitry Andric 5956349cc55cSDimitry Andric public: 5957349cc55cSDimitry Andric static OMPMetaDirective *Create(const ASTContext &C, SourceLocation StartLoc, 5958349cc55cSDimitry Andric SourceLocation EndLoc, 5959349cc55cSDimitry Andric ArrayRef<OMPClause *> Clauses, 5960349cc55cSDimitry Andric Stmt *AssociatedStmt, Stmt *IfStmt); 5961349cc55cSDimitry Andric static OMPMetaDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 5962349cc55cSDimitry Andric EmptyShell); getIfStmt()5963349cc55cSDimitry Andric Stmt *getIfStmt() const { return IfStmt; } 5964349cc55cSDimitry Andric classof(const Stmt * T)5965349cc55cSDimitry Andric static bool classof(const Stmt *T) { 5966349cc55cSDimitry Andric return T->getStmtClass() == OMPMetaDirectiveClass; 5967349cc55cSDimitry Andric } 5968349cc55cSDimitry Andric }; 5969349cc55cSDimitry Andric 5970349cc55cSDimitry Andric /// This represents '#pragma omp loop' directive. 5971349cc55cSDimitry Andric /// 5972349cc55cSDimitry Andric /// \code 5973349cc55cSDimitry Andric /// #pragma omp loop private(a,b) binding(parallel) order(concurrent) 5974349cc55cSDimitry Andric /// \endcode 5975349cc55cSDimitry Andric /// In this example directive '#pragma omp loop' has 5976349cc55cSDimitry Andric /// clauses 'private' with the variables 'a' and 'b', 'binding' with 5977349cc55cSDimitry Andric /// modifier 'parallel' and 'order(concurrent). 5978349cc55cSDimitry Andric /// 5979349cc55cSDimitry Andric class OMPGenericLoopDirective final : public OMPLoopDirective { 5980349cc55cSDimitry Andric friend class ASTStmtReader; 5981349cc55cSDimitry Andric friend class OMPExecutableDirective; 5982349cc55cSDimitry Andric /// Build directive with the given start and end location. 5983349cc55cSDimitry Andric /// 5984349cc55cSDimitry Andric /// \param StartLoc Starting location of the directive kind. 5985349cc55cSDimitry Andric /// \param EndLoc Ending location of the directive. 5986349cc55cSDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 5987349cc55cSDimitry Andric /// OMPGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5988349cc55cSDimitry Andric OMPGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 5989349cc55cSDimitry Andric unsigned CollapsedNum) 5990349cc55cSDimitry Andric : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop, 5991349cc55cSDimitry Andric StartLoc, EndLoc, CollapsedNum) {} 5992349cc55cSDimitry Andric 5993349cc55cSDimitry Andric /// Build an empty directive. 5994349cc55cSDimitry Andric /// 5995349cc55cSDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 5996349cc55cSDimitry Andric /// OMPGenericLoopDirective(unsigned CollapsedNum)5997349cc55cSDimitry Andric explicit OMPGenericLoopDirective(unsigned CollapsedNum) 5998349cc55cSDimitry Andric : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop, 5999349cc55cSDimitry Andric SourceLocation(), SourceLocation(), CollapsedNum) {} 6000349cc55cSDimitry Andric 6001349cc55cSDimitry Andric public: 6002349cc55cSDimitry Andric /// Creates directive with a list of \p Clauses. 6003349cc55cSDimitry Andric /// 6004349cc55cSDimitry Andric /// \param C AST context. 6005349cc55cSDimitry Andric /// \param StartLoc Starting location of the directive kind. 6006349cc55cSDimitry Andric /// \param EndLoc Ending Location of the directive. 6007349cc55cSDimitry Andric /// \param CollapsedNum Number of collapsed loops. 6008349cc55cSDimitry Andric /// \param Clauses List of clauses. 6009349cc55cSDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 6010349cc55cSDimitry Andric /// \param Exprs Helper expressions for CodeGen. 6011349cc55cSDimitry Andric /// 6012349cc55cSDimitry Andric static OMPGenericLoopDirective * 6013349cc55cSDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 6014349cc55cSDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 6015349cc55cSDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 6016349cc55cSDimitry Andric 6017349cc55cSDimitry Andric /// Creates an empty directive with a place for \a NumClauses clauses. 6018349cc55cSDimitry Andric /// 6019349cc55cSDimitry Andric /// \param C AST context. 6020349cc55cSDimitry Andric /// \param NumClauses Number of clauses. 6021349cc55cSDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 6022349cc55cSDimitry Andric /// 6023349cc55cSDimitry Andric static OMPGenericLoopDirective *CreateEmpty(const ASTContext &C, 6024349cc55cSDimitry Andric unsigned NumClauses, 6025349cc55cSDimitry Andric unsigned CollapsedNum, 6026349cc55cSDimitry Andric EmptyShell); 6027349cc55cSDimitry Andric classof(const Stmt * T)6028349cc55cSDimitry Andric static bool classof(const Stmt *T) { 6029349cc55cSDimitry Andric return T->getStmtClass() == OMPGenericLoopDirectiveClass; 6030349cc55cSDimitry Andric } 6031349cc55cSDimitry Andric }; 6032349cc55cSDimitry Andric 603381ad6265SDimitry Andric /// This represents '#pragma omp teams loop' directive. 603481ad6265SDimitry Andric /// 603581ad6265SDimitry Andric /// \code 603681ad6265SDimitry Andric /// #pragma omp teams loop private(a,b) order(concurrent) 603781ad6265SDimitry Andric /// \endcode 603881ad6265SDimitry Andric /// In this example directive '#pragma omp teams loop' has 603981ad6265SDimitry Andric /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). 604081ad6265SDimitry Andric /// 604181ad6265SDimitry Andric class OMPTeamsGenericLoopDirective final : public OMPLoopDirective { 604281ad6265SDimitry Andric friend class ASTStmtReader; 604381ad6265SDimitry Andric friend class OMPExecutableDirective; 604481ad6265SDimitry Andric /// Build directive with the given start and end location. 604581ad6265SDimitry Andric /// 604681ad6265SDimitry Andric /// \param StartLoc Starting location of the directive kind. 604781ad6265SDimitry Andric /// \param EndLoc Ending location of the directive. 604881ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 604981ad6265SDimitry Andric /// OMPTeamsGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)605081ad6265SDimitry Andric OMPTeamsGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 605181ad6265SDimitry Andric unsigned CollapsedNum) 605281ad6265SDimitry Andric : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass, 605381ad6265SDimitry Andric llvm::omp::OMPD_teams_loop, StartLoc, EndLoc, 605481ad6265SDimitry Andric CollapsedNum) {} 605581ad6265SDimitry Andric 605681ad6265SDimitry Andric /// Build an empty directive. 605781ad6265SDimitry Andric /// 605881ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 605981ad6265SDimitry Andric /// OMPTeamsGenericLoopDirective(unsigned CollapsedNum)606081ad6265SDimitry Andric explicit OMPTeamsGenericLoopDirective(unsigned CollapsedNum) 606181ad6265SDimitry Andric : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass, 606281ad6265SDimitry Andric llvm::omp::OMPD_teams_loop, SourceLocation(), 606381ad6265SDimitry Andric SourceLocation(), CollapsedNum) {} 606481ad6265SDimitry Andric 606581ad6265SDimitry Andric public: 606681ad6265SDimitry Andric /// Creates directive with a list of \p Clauses. 606781ad6265SDimitry Andric /// 606881ad6265SDimitry Andric /// \param C AST context. 606981ad6265SDimitry Andric /// \param StartLoc Starting location of the directive kind. 607081ad6265SDimitry Andric /// \param EndLoc Ending Location of the directive. 607181ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 607281ad6265SDimitry Andric /// \param Clauses List of clauses. 607381ad6265SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 607481ad6265SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 607581ad6265SDimitry Andric /// 607681ad6265SDimitry Andric static OMPTeamsGenericLoopDirective * 607781ad6265SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 607881ad6265SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 607981ad6265SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 608081ad6265SDimitry Andric 608181ad6265SDimitry Andric /// Creates an empty directive with the place 608281ad6265SDimitry Andric /// for \a NumClauses clauses. 608381ad6265SDimitry Andric /// 608481ad6265SDimitry Andric /// \param C AST context. 608581ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 608681ad6265SDimitry Andric /// \param NumClauses Number of clauses. 608781ad6265SDimitry Andric /// 608881ad6265SDimitry Andric static OMPTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C, 608981ad6265SDimitry Andric unsigned NumClauses, 609081ad6265SDimitry Andric unsigned CollapsedNum, 609181ad6265SDimitry Andric EmptyShell); 609281ad6265SDimitry Andric classof(const Stmt * T)609381ad6265SDimitry Andric static bool classof(const Stmt *T) { 609481ad6265SDimitry Andric return T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass; 609581ad6265SDimitry Andric } 609681ad6265SDimitry Andric }; 609781ad6265SDimitry Andric 609881ad6265SDimitry Andric /// This represents '#pragma omp target teams loop' directive. 609981ad6265SDimitry Andric /// 610081ad6265SDimitry Andric /// \code 610181ad6265SDimitry Andric /// #pragma omp target teams loop private(a,b) order(concurrent) 610281ad6265SDimitry Andric /// \endcode 610381ad6265SDimitry Andric /// In this example directive '#pragma omp target teams loop' has 610481ad6265SDimitry Andric /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). 610581ad6265SDimitry Andric /// 610681ad6265SDimitry Andric class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective { 610781ad6265SDimitry Andric friend class ASTStmtReader; 610881ad6265SDimitry Andric friend class OMPExecutableDirective; 610981ad6265SDimitry Andric /// Build directive with the given start and end location. 611081ad6265SDimitry Andric /// 611181ad6265SDimitry Andric /// \param StartLoc Starting location of the directive kind. 611281ad6265SDimitry Andric /// \param EndLoc Ending location of the directive. 611381ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 611481ad6265SDimitry Andric /// OMPTargetTeamsGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)611581ad6265SDimitry Andric OMPTargetTeamsGenericLoopDirective(SourceLocation StartLoc, 611681ad6265SDimitry Andric SourceLocation EndLoc, 611781ad6265SDimitry Andric unsigned CollapsedNum) 611881ad6265SDimitry Andric : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass, 611981ad6265SDimitry Andric llvm::omp::OMPD_target_teams_loop, StartLoc, EndLoc, 612081ad6265SDimitry Andric CollapsedNum) {} 612181ad6265SDimitry Andric 612281ad6265SDimitry Andric /// Build an empty directive. 612381ad6265SDimitry Andric /// 612481ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 612581ad6265SDimitry Andric /// OMPTargetTeamsGenericLoopDirective(unsigned CollapsedNum)612681ad6265SDimitry Andric explicit OMPTargetTeamsGenericLoopDirective(unsigned CollapsedNum) 612781ad6265SDimitry Andric : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass, 612881ad6265SDimitry Andric llvm::omp::OMPD_target_teams_loop, SourceLocation(), 612981ad6265SDimitry Andric SourceLocation(), CollapsedNum) {} 613081ad6265SDimitry Andric 613181ad6265SDimitry Andric public: 613281ad6265SDimitry Andric /// Creates directive with a list of \p Clauses. 613381ad6265SDimitry Andric /// 613481ad6265SDimitry Andric /// \param C AST context. 613581ad6265SDimitry Andric /// \param StartLoc Starting location of the directive kind. 613681ad6265SDimitry Andric /// \param EndLoc Ending Location of the directive. 613781ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 613881ad6265SDimitry Andric /// \param Clauses List of clauses. 613981ad6265SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 614081ad6265SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 614181ad6265SDimitry Andric /// 614281ad6265SDimitry Andric static OMPTargetTeamsGenericLoopDirective * 614381ad6265SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 614481ad6265SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 614581ad6265SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 614681ad6265SDimitry Andric 614781ad6265SDimitry Andric /// Creates an empty directive with the place 614881ad6265SDimitry Andric /// for \a NumClauses clauses. 614981ad6265SDimitry Andric /// 615081ad6265SDimitry Andric /// \param C AST context. 615181ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 615281ad6265SDimitry Andric /// \param NumClauses Number of clauses. 615381ad6265SDimitry Andric /// 615481ad6265SDimitry Andric static OMPTargetTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C, 615581ad6265SDimitry Andric unsigned NumClauses, 615681ad6265SDimitry Andric unsigned CollapsedNum, 615781ad6265SDimitry Andric EmptyShell); 615881ad6265SDimitry Andric classof(const Stmt * T)615981ad6265SDimitry Andric static bool classof(const Stmt *T) { 616081ad6265SDimitry Andric return T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass; 616181ad6265SDimitry Andric } 616281ad6265SDimitry Andric }; 616381ad6265SDimitry Andric 616481ad6265SDimitry Andric /// This represents '#pragma omp parallel loop' directive. 616581ad6265SDimitry Andric /// 616681ad6265SDimitry Andric /// \code 616781ad6265SDimitry Andric /// #pragma omp parallel loop private(a,b) order(concurrent) 616881ad6265SDimitry Andric /// \endcode 616981ad6265SDimitry Andric /// In this example directive '#pragma omp parallel loop' has 617081ad6265SDimitry Andric /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). 617181ad6265SDimitry Andric /// 617281ad6265SDimitry Andric class OMPParallelGenericLoopDirective final : public OMPLoopDirective { 617381ad6265SDimitry Andric friend class ASTStmtReader; 617481ad6265SDimitry Andric friend class OMPExecutableDirective; 617581ad6265SDimitry Andric /// Build directive with the given start and end location. 617681ad6265SDimitry Andric /// 617781ad6265SDimitry Andric /// \param StartLoc Starting location of the directive kind. 617881ad6265SDimitry Andric /// \param EndLoc Ending location of the directive. 617981ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 618081ad6265SDimitry Andric /// OMPParallelGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)618181ad6265SDimitry Andric OMPParallelGenericLoopDirective(SourceLocation StartLoc, 618281ad6265SDimitry Andric SourceLocation EndLoc, unsigned CollapsedNum) 618381ad6265SDimitry Andric : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass, 618481ad6265SDimitry Andric llvm::omp::OMPD_parallel_loop, StartLoc, EndLoc, 618581ad6265SDimitry Andric CollapsedNum) {} 618681ad6265SDimitry Andric 618781ad6265SDimitry Andric /// Build an empty directive. 618881ad6265SDimitry Andric /// 618981ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 619081ad6265SDimitry Andric /// OMPParallelGenericLoopDirective(unsigned CollapsedNum)619181ad6265SDimitry Andric explicit OMPParallelGenericLoopDirective(unsigned CollapsedNum) 619281ad6265SDimitry Andric : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass, 619381ad6265SDimitry Andric llvm::omp::OMPD_parallel_loop, SourceLocation(), 619481ad6265SDimitry Andric SourceLocation(), CollapsedNum) {} 619581ad6265SDimitry Andric 619681ad6265SDimitry Andric public: 619781ad6265SDimitry Andric /// Creates directive with a list of \p Clauses. 619881ad6265SDimitry Andric /// 619981ad6265SDimitry Andric /// \param C AST context. 620081ad6265SDimitry Andric /// \param StartLoc Starting location of the directive kind. 620181ad6265SDimitry Andric /// \param EndLoc Ending Location of the directive. 620281ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 620381ad6265SDimitry Andric /// \param Clauses List of clauses. 620481ad6265SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 620581ad6265SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 620681ad6265SDimitry Andric /// 620781ad6265SDimitry Andric static OMPParallelGenericLoopDirective * 620881ad6265SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 620981ad6265SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 621081ad6265SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 621181ad6265SDimitry Andric 621281ad6265SDimitry Andric /// Creates an empty directive with the place 621381ad6265SDimitry Andric /// for \a NumClauses clauses. 621481ad6265SDimitry Andric /// 621581ad6265SDimitry Andric /// \param C AST context. 621681ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 621781ad6265SDimitry Andric /// \param NumClauses Number of clauses. 621881ad6265SDimitry Andric /// 621981ad6265SDimitry Andric static OMPParallelGenericLoopDirective *CreateEmpty(const ASTContext &C, 622081ad6265SDimitry Andric unsigned NumClauses, 622181ad6265SDimitry Andric unsigned CollapsedNum, 622281ad6265SDimitry Andric EmptyShell); 622381ad6265SDimitry Andric classof(const Stmt * T)622481ad6265SDimitry Andric static bool classof(const Stmt *T) { 622581ad6265SDimitry Andric return T->getStmtClass() == OMPParallelGenericLoopDirectiveClass; 622681ad6265SDimitry Andric } 622781ad6265SDimitry Andric }; 622881ad6265SDimitry Andric 622981ad6265SDimitry Andric /// This represents '#pragma omp target parallel loop' directive. 623081ad6265SDimitry Andric /// 623181ad6265SDimitry Andric /// \code 623281ad6265SDimitry Andric /// #pragma omp target parallel loop private(a,b) order(concurrent) 623381ad6265SDimitry Andric /// \endcode 623481ad6265SDimitry Andric /// In this example directive '#pragma omp target parallel loop' has 623581ad6265SDimitry Andric /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). 623681ad6265SDimitry Andric /// 623781ad6265SDimitry Andric class OMPTargetParallelGenericLoopDirective final : public OMPLoopDirective { 623881ad6265SDimitry Andric friend class ASTStmtReader; 623981ad6265SDimitry Andric friend class OMPExecutableDirective; 624081ad6265SDimitry Andric /// Build directive with the given start and end location. 624181ad6265SDimitry Andric /// 624281ad6265SDimitry Andric /// \param StartLoc Starting location of the directive kind. 624381ad6265SDimitry Andric /// \param EndLoc Ending location of the directive. 624481ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 624581ad6265SDimitry Andric /// OMPTargetParallelGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)624681ad6265SDimitry Andric OMPTargetParallelGenericLoopDirective(SourceLocation StartLoc, 624781ad6265SDimitry Andric SourceLocation EndLoc, 624881ad6265SDimitry Andric unsigned CollapsedNum) 624981ad6265SDimitry Andric : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass, 625081ad6265SDimitry Andric llvm::omp::OMPD_target_parallel_loop, StartLoc, EndLoc, 625181ad6265SDimitry Andric CollapsedNum) {} 625281ad6265SDimitry Andric 625381ad6265SDimitry Andric /// Build an empty directive. 625481ad6265SDimitry Andric /// 625581ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 625681ad6265SDimitry Andric /// OMPTargetParallelGenericLoopDirective(unsigned CollapsedNum)625781ad6265SDimitry Andric explicit OMPTargetParallelGenericLoopDirective(unsigned CollapsedNum) 625881ad6265SDimitry Andric : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass, 625981ad6265SDimitry Andric llvm::omp::OMPD_target_parallel_loop, SourceLocation(), 626081ad6265SDimitry Andric SourceLocation(), CollapsedNum) {} 626181ad6265SDimitry Andric 626281ad6265SDimitry Andric public: 626381ad6265SDimitry Andric /// Creates directive with a list of \p Clauses. 626481ad6265SDimitry Andric /// 626581ad6265SDimitry Andric /// \param C AST context. 626681ad6265SDimitry Andric /// \param StartLoc Starting location of the directive kind. 626781ad6265SDimitry Andric /// \param EndLoc Ending Location of the directive. 626881ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed loops. 626981ad6265SDimitry Andric /// \param Clauses List of clauses. 627081ad6265SDimitry Andric /// \param AssociatedStmt Statement, associated with the directive. 627181ad6265SDimitry Andric /// \param Exprs Helper expressions for CodeGen. 627281ad6265SDimitry Andric /// 627381ad6265SDimitry Andric static OMPTargetParallelGenericLoopDirective * 627481ad6265SDimitry Andric Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 627581ad6265SDimitry Andric unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 627681ad6265SDimitry Andric Stmt *AssociatedStmt, const HelperExprs &Exprs); 627781ad6265SDimitry Andric 627881ad6265SDimitry Andric /// Creates an empty directive with the place 627981ad6265SDimitry Andric /// for \a NumClauses clauses. 628081ad6265SDimitry Andric /// 628181ad6265SDimitry Andric /// \param C AST context. 628281ad6265SDimitry Andric /// \param CollapsedNum Number of collapsed nested loops. 628381ad6265SDimitry Andric /// \param NumClauses Number of clauses. 628481ad6265SDimitry Andric /// 628581ad6265SDimitry Andric static OMPTargetParallelGenericLoopDirective * 628681ad6265SDimitry Andric CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 628781ad6265SDimitry Andric EmptyShell); 628881ad6265SDimitry Andric classof(const Stmt * T)628981ad6265SDimitry Andric static bool classof(const Stmt *T) { 629081ad6265SDimitry Andric return T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass; 629181ad6265SDimitry Andric } 629281ad6265SDimitry Andric }; 6293bdd1243dSDimitry Andric 6294bdd1243dSDimitry Andric /// This represents '#pragma omp error' directive. 6295bdd1243dSDimitry Andric /// 6296bdd1243dSDimitry Andric /// \code 6297bdd1243dSDimitry Andric /// #pragma omp error 6298bdd1243dSDimitry Andric /// \endcode 6299bdd1243dSDimitry Andric class OMPErrorDirective final : public OMPExecutableDirective { 6300bdd1243dSDimitry Andric friend class ASTStmtReader; 6301bdd1243dSDimitry Andric friend class OMPExecutableDirective; 6302bdd1243dSDimitry Andric /// Build directive with the given start and end location. 6303bdd1243dSDimitry Andric /// 6304bdd1243dSDimitry Andric /// \param StartLoc Starting location of the directive kind. 6305bdd1243dSDimitry Andric /// \param EndLoc Ending location of the directive. 6306bdd1243dSDimitry Andric /// OMPErrorDirective(SourceLocation StartLoc,SourceLocation EndLoc)6307bdd1243dSDimitry Andric OMPErrorDirective(SourceLocation StartLoc, SourceLocation EndLoc) 6308bdd1243dSDimitry Andric : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error, 6309bdd1243dSDimitry Andric StartLoc, EndLoc) {} 6310bdd1243dSDimitry Andric /// Build an empty directive. 6311bdd1243dSDimitry Andric /// OMPErrorDirective()6312bdd1243dSDimitry Andric explicit OMPErrorDirective() 6313bdd1243dSDimitry Andric : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error, 6314bdd1243dSDimitry Andric SourceLocation(), SourceLocation()) {} 6315bdd1243dSDimitry Andric 6316bdd1243dSDimitry Andric public: 6317bdd1243dSDimitry Andric /// 6318bdd1243dSDimitry Andric /// \param C AST context. 6319bdd1243dSDimitry Andric /// \param StartLoc Starting location of the directive kind. 6320bdd1243dSDimitry Andric /// \param EndLoc Ending Location of the directive. 6321bdd1243dSDimitry Andric /// \param Clauses List of clauses. 6322bdd1243dSDimitry Andric /// 6323bdd1243dSDimitry Andric static OMPErrorDirective *Create(const ASTContext &C, SourceLocation StartLoc, 6324bdd1243dSDimitry Andric SourceLocation EndLoc, 6325bdd1243dSDimitry Andric ArrayRef<OMPClause *> Clauses); 6326bdd1243dSDimitry Andric 6327bdd1243dSDimitry Andric /// Creates an empty directive. 6328bdd1243dSDimitry Andric /// 6329bdd1243dSDimitry Andric /// \param C AST context. 6330bdd1243dSDimitry Andric /// 6331bdd1243dSDimitry Andric static OMPErrorDirective *CreateEmpty(const ASTContext &C, 6332bdd1243dSDimitry Andric unsigned NumClauses, EmptyShell); 6333bdd1243dSDimitry Andric classof(const Stmt * T)6334bdd1243dSDimitry Andric static bool classof(const Stmt *T) { 6335bdd1243dSDimitry Andric return T->getStmtClass() == OMPErrorDirectiveClass; 6336bdd1243dSDimitry Andric } 6337bdd1243dSDimitry Andric }; 63380b57cec5SDimitry Andric } // end namespace clang 63390b57cec5SDimitry Andric 63400b57cec5SDimitry Andric #endif 6341