1 //===- StmtOpenMP.h - Classes for OpenMP directives ------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file defines OpenMP AST classes for executable directives and 10 /// clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_AST_STMTOPENMP_H 15 #define LLVM_CLANG_AST_STMTOPENMP_H 16 17 #include "clang/AST/ASTContext.h" 18 #include "clang/AST/Expr.h" 19 #include "clang/AST/OpenMPClause.h" 20 #include "clang/AST/Stmt.h" 21 #include "clang/AST/StmtCXX.h" 22 #include "clang/Basic/OpenMPKinds.h" 23 #include "clang/Basic/SourceLocation.h" 24 25 namespace clang { 26 27 //===----------------------------------------------------------------------===// 28 // AST classes for directives. 29 //===----------------------------------------------------------------------===// 30 31 /// Representation of an OpenMP canonical loop. 32 /// 33 /// OpenMP 1.0 C/C++, section 2.4.1 for Construct; canonical-shape 34 /// OpenMP 2.0 C/C++, section 2.4.1 for Construct; canonical-shape 35 /// OpenMP 2.5, section 2.5.1 Loop Construct; canonical form 36 /// OpenMP 3.1, section 2.5.1 Loop Construct; canonical form 37 /// OpenMP 4.0, section 2.6 Canonical Loop Form 38 /// OpenMP 4.5, section 2.6 Canonical Loop Form 39 /// OpenMP 5.0, section 2.9.1 Canonical Loop Form 40 /// OpenMP 5.1, section 2.11.1 Canonical Loop Nest Form 41 /// 42 /// An OpenMP canonical loop is a for-statement or range-based for-statement 43 /// with additional requirements that ensure that the number of iterations is 44 /// known before entering the loop and allow skipping to an arbitrary iteration. 45 /// The OMPCanonicalLoop AST node wraps a ForStmt or CXXForRangeStmt that is 46 /// known to fulfill OpenMP's canonical loop requirements because of being 47 /// associated to an OMPLoopBasedDirective. That is, the general structure is: 48 /// 49 /// OMPLoopBasedDirective 50 /// [`- CapturedStmt ] 51 /// [ `- CapturedDecl] 52 /// ` OMPCanonicalLoop 53 /// `- ForStmt/CXXForRangeStmt 54 /// `- Stmt 55 /// 56 /// One or multiple CapturedStmt/CapturedDecl pairs may be inserted by some 57 /// directives such as OMPParallelForDirective, but others do not need them 58 /// (such as OMPTileDirective). In The OMPCanonicalLoop and 59 /// ForStmt/CXXForRangeStmt pair is repeated for loop associated with the 60 /// directive. A OMPCanonicalLoop must not appear in the AST unless associated 61 /// with a OMPLoopBasedDirective. In an imperfectly nested loop nest, the 62 /// OMPCanonicalLoop may also be wrapped in a CompoundStmt: 63 /// 64 /// [...] 65 /// ` OMPCanonicalLoop 66 /// `- ForStmt/CXXForRangeStmt 67 /// `- CompoundStmt 68 /// |- Leading in-between code (if any) 69 /// |- OMPCanonicalLoop 70 /// | `- ForStmt/CXXForRangeStmt 71 /// | `- ... 72 /// `- Trailing in-between code (if any) 73 /// 74 /// The leading/trailing in-between code must not itself be a OMPCanonicalLoop 75 /// to avoid confusion which loop belongs to the nesting. 76 /// 77 /// There are three different kinds of iteration variables for different 78 /// purposes: 79 /// * Loop user variable: The user-accessible variable with different value for 80 /// each iteration. 81 /// * Loop iteration variable: The variable used to identify a loop iteration; 82 /// for range-based for-statement, this is the hidden iterator '__begin'. For 83 /// other loops, it is identical to the loop user variable. Must be a 84 /// random-access iterator, pointer or integer type. 85 /// * Logical iteration counter: Normalized loop counter starting at 0 and 86 /// incrementing by one at each iteration. Allows abstracting over the type 87 /// of the loop iteration variable and is always an unsigned integer type 88 /// appropriate to represent the range of the loop iteration variable. Its 89 /// value corresponds to the logical iteration number in the OpenMP 90 /// specification. 91 /// 92 /// This AST node provides two captured statements: 93 /// * The distance function which computes the number of iterations. 94 /// * The loop user variable function that computes the loop user variable when 95 /// given a logical iteration number. 96 /// 97 /// These captured statements provide the link between C/C++ semantics and the 98 /// logical iteration counters used by the OpenMPIRBuilder which is 99 /// language-agnostic and therefore does not know e.g. how to advance a 100 /// random-access iterator. The OpenMPIRBuilder will use this information to 101 /// apply simd, workshare-loop, distribute, taskloop and loop directives to the 102 /// loop. For compatibility with the non-OpenMPIRBuilder codegen path, an 103 /// OMPCanonicalLoop can itself also be wrapped into the CapturedStmts of an 104 /// OMPLoopDirective and skipped when searching for the associated syntactical 105 /// loop. 106 /// 107 /// Example: 108 /// <code> 109 /// std::vector<std::string> Container{1,2,3}; 110 /// for (std::string Str : Container) 111 /// Body(Str); 112 /// </code> 113 /// which is syntactic sugar for approximately: 114 /// <code> 115 /// auto &&__range = Container; 116 /// auto __begin = std::begin(__range); 117 /// auto __end = std::end(__range); 118 /// for (; __begin != __end; ++__begin) { 119 /// std::String Str = *__begin; 120 /// Body(Str); 121 /// } 122 /// </code> 123 /// In this example, the loop user variable is `Str`, the loop iteration 124 /// variable is `__begin` of type `std::vector<std::string>::iterator` and the 125 /// logical iteration number type is `size_t` (unsigned version of 126 /// `std::vector<std::string>::iterator::difference_type` aka `ptrdiff_t`). 127 /// Therefore, the distance function will be 128 /// <code> 129 /// [&](size_t &Result) { Result = __end - __begin; } 130 /// </code> 131 /// and the loop variable function is 132 /// <code> 133 /// [&,__begin](std::vector<std::string>::iterator &Result, size_t Logical) { 134 /// Result = __begin + Logical; 135 /// } 136 /// </code> 137 /// The variable `__begin`, aka the loop iteration variable, is captured by 138 /// value because it is modified in the loop body, but both functions require 139 /// the initial value. The OpenMP specification explicitly leaves unspecified 140 /// when the loop expressions are evaluated such that a capture by reference is 141 /// sufficient. 142 class OMPCanonicalLoop : public Stmt { 143 friend class ASTStmtReader; 144 friend class ASTStmtWriter; 145 146 /// Children of this AST node. 147 enum { 148 LOOP_STMT, 149 DISTANCE_FUNC, 150 LOOPVAR_FUNC, 151 LOOPVAR_REF, 152 LastSubStmt = LOOPVAR_REF 153 }; 154 155 private: 156 /// This AST node's children. 157 Stmt *SubStmts[LastSubStmt + 1] = {}; 158 OMPCanonicalLoop()159 OMPCanonicalLoop() : Stmt(StmtClass::OMPCanonicalLoopClass) {} 160 161 public: 162 /// Create a new OMPCanonicalLoop. create(const ASTContext & Ctx,Stmt * LoopStmt,CapturedStmt * DistanceFunc,CapturedStmt * LoopVarFunc,DeclRefExpr * LoopVarRef)163 static OMPCanonicalLoop *create(const ASTContext &Ctx, Stmt *LoopStmt, 164 CapturedStmt *DistanceFunc, 165 CapturedStmt *LoopVarFunc, 166 DeclRefExpr *LoopVarRef) { 167 OMPCanonicalLoop *S = new (Ctx) OMPCanonicalLoop(); 168 S->setLoopStmt(LoopStmt); 169 S->setDistanceFunc(DistanceFunc); 170 S->setLoopVarFunc(LoopVarFunc); 171 S->setLoopVarRef(LoopVarRef); 172 return S; 173 } 174 175 /// Create an empty OMPCanonicalLoop for deserialization. createEmpty(const ASTContext & Ctx)176 static OMPCanonicalLoop *createEmpty(const ASTContext &Ctx) { 177 return new (Ctx) OMPCanonicalLoop(); 178 } 179 classof(const Stmt * S)180 static bool classof(const Stmt *S) { 181 return S->getStmtClass() == StmtClass::OMPCanonicalLoopClass; 182 } 183 getBeginLoc()184 SourceLocation getBeginLoc() const { return getLoopStmt()->getBeginLoc(); } getEndLoc()185 SourceLocation getEndLoc() const { return getLoopStmt()->getEndLoc(); } 186 187 /// Return this AST node's children. 188 /// @{ children()189 child_range children() { 190 return child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1); 191 } children()192 const_child_range children() const { 193 return const_child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1); 194 } 195 /// @} 196 197 /// The wrapped syntactic loop statement (ForStmt or CXXForRangeStmt). 198 /// @{ getLoopStmt()199 Stmt *getLoopStmt() { return SubStmts[LOOP_STMT]; } getLoopStmt()200 const Stmt *getLoopStmt() const { return SubStmts[LOOP_STMT]; } setLoopStmt(Stmt * S)201 void setLoopStmt(Stmt *S) { 202 assert((isa<ForStmt>(S) || isa<CXXForRangeStmt>(S)) && 203 "Canonical loop must be a for loop (range-based or otherwise)"); 204 SubStmts[LOOP_STMT] = S; 205 } 206 /// @} 207 208 /// The function that computes the number of loop iterations. Can be evaluated 209 /// before entering the loop but after the syntactical loop's init 210 /// statement(s). 211 /// 212 /// Function signature: void(LogicalTy &Result) 213 /// Any values necessary to compute the distance are captures of the closure. 214 /// @{ getDistanceFunc()215 CapturedStmt *getDistanceFunc() { 216 return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]); 217 } getDistanceFunc()218 const CapturedStmt *getDistanceFunc() const { 219 return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]); 220 } setDistanceFunc(CapturedStmt * S)221 void setDistanceFunc(CapturedStmt *S) { 222 assert(S && "Expected non-null captured statement"); 223 SubStmts[DISTANCE_FUNC] = S; 224 } 225 /// @} 226 227 /// The function that computes the loop user variable from a logical iteration 228 /// counter. Can be evaluated as first statement in the loop. 229 /// 230 /// Function signature: void(LoopVarTy &Result, LogicalTy Number) 231 /// Any other values required to compute the loop user variable (such as start 232 /// value, step size) are captured by the closure. In particular, the initial 233 /// value of loop iteration variable is captured by value to be unaffected by 234 /// previous iterations. 235 /// @{ getLoopVarFunc()236 CapturedStmt *getLoopVarFunc() { 237 return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]); 238 } getLoopVarFunc()239 const CapturedStmt *getLoopVarFunc() const { 240 return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]); 241 } setLoopVarFunc(CapturedStmt * S)242 void setLoopVarFunc(CapturedStmt *S) { 243 assert(S && "Expected non-null captured statement"); 244 SubStmts[LOOPVAR_FUNC] = S; 245 } 246 /// @} 247 248 /// Reference to the loop user variable as accessed in the loop body. 249 /// @{ getLoopVarRef()250 DeclRefExpr *getLoopVarRef() { 251 return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]); 252 } getLoopVarRef()253 const DeclRefExpr *getLoopVarRef() const { 254 return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]); 255 } setLoopVarRef(DeclRefExpr * E)256 void setLoopVarRef(DeclRefExpr *E) { 257 assert(E && "Expected non-null loop variable"); 258 SubStmts[LOOPVAR_REF] = E; 259 } 260 /// @} 261 }; 262 263 /// This is a basic class for representing single OpenMP executable 264 /// directive. 265 /// 266 class OMPExecutableDirective : public Stmt { 267 friend class ASTStmtReader; 268 friend class ASTStmtWriter; 269 270 /// Kind of the directive. 271 OpenMPDirectiveKind Kind = llvm::omp::OMPD_unknown; 272 /// Starting location of the directive (directive keyword). 273 SourceLocation StartLoc; 274 /// Ending location of the directive. 275 SourceLocation EndLoc; 276 277 /// Get the clauses storage. getClauses()278 MutableArrayRef<OMPClause *> getClauses() { 279 if (!Data) 280 return std::nullopt; 281 return Data->getClauses(); 282 } 283 284 /// Was this directive mapped from an another directive? 285 /// e.g. 1) omp loop bind(parallel) is mapped to OMPD_for 286 /// 2) omp loop bind(teams) is mapped to OMPD_distribute 287 /// 3) omp loop bind(thread) is mapped to OMPD_simd 288 /// It was necessary to note it down in the Directive because of 289 /// clang::TreeTransform::TransformOMPExecutableDirective() pass in 290 /// the frontend. 291 OpenMPDirectiveKind PrevMappedDirective = llvm::omp::OMPD_unknown; 292 293 protected: 294 /// Data, associated with the directive. 295 OMPChildren *Data = nullptr; 296 297 /// Build instance of directive of class \a K. 298 /// 299 /// \param SC Statement class. 300 /// \param K Kind of OpenMP directive. 301 /// \param StartLoc Starting location of the directive (directive keyword). 302 /// \param EndLoc Ending location of the directive. 303 /// OMPExecutableDirective(StmtClass SC,OpenMPDirectiveKind K,SourceLocation StartLoc,SourceLocation EndLoc)304 OMPExecutableDirective(StmtClass SC, OpenMPDirectiveKind K, 305 SourceLocation StartLoc, SourceLocation EndLoc) 306 : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)), 307 EndLoc(std::move(EndLoc)) {} 308 309 template <typename T, typename... Params> createDirective(const ASTContext & C,ArrayRef<OMPClause * > Clauses,Stmt * AssociatedStmt,unsigned NumChildren,Params &&...P)310 static T *createDirective(const ASTContext &C, ArrayRef<OMPClause *> Clauses, 311 Stmt *AssociatedStmt, unsigned NumChildren, 312 Params &&... P) { 313 void *Mem = 314 C.Allocate(sizeof(T) + OMPChildren::size(Clauses.size(), AssociatedStmt, 315 NumChildren), 316 alignof(T)); 317 318 auto *Data = OMPChildren::Create(reinterpret_cast<T *>(Mem) + 1, Clauses, 319 AssociatedStmt, NumChildren); 320 auto *Inst = new (Mem) T(std::forward<Params>(P)...); 321 Inst->Data = Data; 322 return Inst; 323 } 324 325 template <typename T, typename... Params> createEmptyDirective(const ASTContext & C,unsigned NumClauses,bool HasAssociatedStmt,unsigned NumChildren,Params &&...P)326 static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses, 327 bool HasAssociatedStmt, unsigned NumChildren, 328 Params &&... P) { 329 void *Mem = 330 C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt, 331 NumChildren), 332 alignof(T)); 333 auto *Data = 334 OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses, 335 HasAssociatedStmt, NumChildren); 336 auto *Inst = new (Mem) T(std::forward<Params>(P)...); 337 Inst->Data = Data; 338 return Inst; 339 } 340 341 template <typename T> 342 static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses, 343 bool HasAssociatedStmt = false, 344 unsigned NumChildren = 0) { 345 void *Mem = 346 C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt, 347 NumChildren), 348 alignof(T)); 349 auto *Data = 350 OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses, 351 HasAssociatedStmt, NumChildren); 352 auto *Inst = new (Mem) T; 353 Inst->Data = Data; 354 return Inst; 355 } 356 setMappedDirective(OpenMPDirectiveKind MappedDirective)357 void setMappedDirective(OpenMPDirectiveKind MappedDirective) { 358 PrevMappedDirective = MappedDirective; 359 } 360 361 public: 362 /// Iterates over expressions/statements used in the construct. 363 class used_clauses_child_iterator 364 : public llvm::iterator_adaptor_base< 365 used_clauses_child_iterator, ArrayRef<OMPClause *>::iterator, 366 std::forward_iterator_tag, Stmt *, ptrdiff_t, Stmt *, Stmt *> { 367 ArrayRef<OMPClause *>::iterator End; 368 OMPClause::child_iterator ChildI, ChildEnd; 369 MoveToNext()370 void MoveToNext() { 371 if (ChildI != ChildEnd) 372 return; 373 while (this->I != End) { 374 ++this->I; 375 if (this->I != End) { 376 ChildI = (*this->I)->used_children().begin(); 377 ChildEnd = (*this->I)->used_children().end(); 378 if (ChildI != ChildEnd) 379 return; 380 } 381 } 382 } 383 384 public: used_clauses_child_iterator(ArrayRef<OMPClause * > Clauses)385 explicit used_clauses_child_iterator(ArrayRef<OMPClause *> Clauses) 386 : used_clauses_child_iterator::iterator_adaptor_base(Clauses.begin()), 387 End(Clauses.end()) { 388 if (this->I != End) { 389 ChildI = (*this->I)->used_children().begin(); 390 ChildEnd = (*this->I)->used_children().end(); 391 MoveToNext(); 392 } 393 } 394 Stmt *operator*() const { return *ChildI; } 395 Stmt *operator->() const { return **this; } 396 397 used_clauses_child_iterator &operator++() { 398 ++ChildI; 399 if (ChildI != ChildEnd) 400 return *this; 401 if (this->I != End) { 402 ++this->I; 403 if (this->I != End) { 404 ChildI = (*this->I)->used_children().begin(); 405 ChildEnd = (*this->I)->used_children().end(); 406 } 407 } 408 MoveToNext(); 409 return *this; 410 } 411 }; 412 413 static llvm::iterator_range<used_clauses_child_iterator> used_clauses_children(ArrayRef<OMPClause * > Clauses)414 used_clauses_children(ArrayRef<OMPClause *> Clauses) { 415 return { 416 used_clauses_child_iterator(Clauses), 417 used_clauses_child_iterator(llvm::ArrayRef(Clauses.end(), (size_t)0))}; 418 } 419 420 /// Iterates over a filtered subrange of clauses applied to a 421 /// directive. 422 /// 423 /// This iterator visits only clauses of type SpecificClause. 424 template <typename SpecificClause> 425 class specific_clause_iterator 426 : public llvm::iterator_adaptor_base< 427 specific_clause_iterator<SpecificClause>, 428 ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag, 429 const SpecificClause *, ptrdiff_t, const SpecificClause *, 430 const SpecificClause *> { 431 ArrayRef<OMPClause *>::const_iterator End; 432 SkipToNextClause()433 void SkipToNextClause() { 434 while (this->I != End && !isa<SpecificClause>(*this->I)) 435 ++this->I; 436 } 437 438 public: specific_clause_iterator(ArrayRef<OMPClause * > Clauses)439 explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses) 440 : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()), 441 End(Clauses.end()) { 442 SkipToNextClause(); 443 } 444 445 const SpecificClause *operator*() const { 446 return cast<SpecificClause>(*this->I); 447 } 448 const SpecificClause *operator->() const { return **this; } 449 450 specific_clause_iterator &operator++() { 451 ++this->I; 452 SkipToNextClause(); 453 return *this; 454 } 455 }; 456 457 template <typename SpecificClause> 458 static llvm::iterator_range<specific_clause_iterator<SpecificClause>> getClausesOfKind(ArrayRef<OMPClause * > Clauses)459 getClausesOfKind(ArrayRef<OMPClause *> Clauses) { 460 return {specific_clause_iterator<SpecificClause>(Clauses), 461 specific_clause_iterator<SpecificClause>( 462 llvm::ArrayRef(Clauses.end(), (size_t)0))}; 463 } 464 465 template <typename SpecificClause> 466 llvm::iterator_range<specific_clause_iterator<SpecificClause>> getClausesOfKind()467 getClausesOfKind() const { 468 return getClausesOfKind<SpecificClause>(clauses()); 469 } 470 471 /// Gets a single clause of the specified kind associated with the 472 /// current directive iff there is only one clause of this kind (and assertion 473 /// is fired if there is more than one clause is associated with the 474 /// directive). Returns nullptr if no clause of this kind is associated with 475 /// the directive. 476 template <typename SpecificClause> getSingleClause(ArrayRef<OMPClause * > Clauses)477 static const SpecificClause *getSingleClause(ArrayRef<OMPClause *> Clauses) { 478 auto ClausesOfKind = getClausesOfKind<SpecificClause>(Clauses); 479 480 if (ClausesOfKind.begin() != ClausesOfKind.end()) { 481 assert(std::next(ClausesOfKind.begin()) == ClausesOfKind.end() && 482 "There are at least 2 clauses of the specified kind"); 483 return *ClausesOfKind.begin(); 484 } 485 return nullptr; 486 } 487 488 template <typename SpecificClause> getSingleClause()489 const SpecificClause *getSingleClause() const { 490 return getSingleClause<SpecificClause>(clauses()); 491 } 492 493 /// Returns true if the current directive has one or more clauses of a 494 /// specific kind. 495 template <typename SpecificClause> hasClausesOfKind()496 bool hasClausesOfKind() const { 497 auto Clauses = getClausesOfKind<SpecificClause>(); 498 return Clauses.begin() != Clauses.end(); 499 } 500 501 /// Returns starting location of directive kind. getBeginLoc()502 SourceLocation getBeginLoc() const { return StartLoc; } 503 /// Returns ending location of directive. getEndLoc()504 SourceLocation getEndLoc() const { return EndLoc; } 505 506 /// Set starting location of directive kind. 507 /// 508 /// \param Loc New starting location of directive. 509 /// setLocStart(SourceLocation Loc)510 void setLocStart(SourceLocation Loc) { StartLoc = Loc; } 511 /// Set ending location of directive. 512 /// 513 /// \param Loc New ending location of directive. 514 /// setLocEnd(SourceLocation Loc)515 void setLocEnd(SourceLocation Loc) { EndLoc = Loc; } 516 517 /// Get number of clauses. getNumClauses()518 unsigned getNumClauses() const { 519 if (!Data) 520 return 0; 521 return Data->getNumClauses(); 522 } 523 524 /// Returns specified clause. 525 /// 526 /// \param I Number of clause. 527 /// getClause(unsigned I)528 OMPClause *getClause(unsigned I) const { return clauses()[I]; } 529 530 /// Returns true if directive has associated statement. hasAssociatedStmt()531 bool hasAssociatedStmt() const { return Data && Data->hasAssociatedStmt(); } 532 533 /// Returns statement associated with the directive. getAssociatedStmt()534 const Stmt *getAssociatedStmt() const { 535 return const_cast<OMPExecutableDirective *>(this)->getAssociatedStmt(); 536 } getAssociatedStmt()537 Stmt *getAssociatedStmt() { 538 assert(hasAssociatedStmt() && 539 "Expected directive with the associated statement."); 540 return Data->getAssociatedStmt(); 541 } 542 543 /// Returns the captured statement associated with the 544 /// component region within the (combined) directive. 545 /// 546 /// \param RegionKind Component region kind. getCapturedStmt(OpenMPDirectiveKind RegionKind)547 const CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const { 548 assert(hasAssociatedStmt() && 549 "Expected directive with the associated statement."); 550 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 551 getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind()); 552 return Data->getCapturedStmt(RegionKind, CaptureRegions); 553 } 554 555 /// Get innermost captured statement for the construct. getInnermostCapturedStmt()556 CapturedStmt *getInnermostCapturedStmt() { 557 assert(hasAssociatedStmt() && 558 "Expected directive with the associated statement."); 559 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 560 getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind()); 561 return Data->getInnermostCapturedStmt(CaptureRegions); 562 } 563 getInnermostCapturedStmt()564 const CapturedStmt *getInnermostCapturedStmt() const { 565 return const_cast<OMPExecutableDirective *>(this) 566 ->getInnermostCapturedStmt(); 567 } 568 getDirectiveKind()569 OpenMPDirectiveKind getDirectiveKind() const { return Kind; } 570 classof(const Stmt * S)571 static bool classof(const Stmt *S) { 572 return S->getStmtClass() >= firstOMPExecutableDirectiveConstant && 573 S->getStmtClass() <= lastOMPExecutableDirectiveConstant; 574 } 575 children()576 child_range children() { 577 if (!Data) 578 return child_range(child_iterator(), child_iterator()); 579 return Data->getAssociatedStmtAsRange(); 580 } 581 children()582 const_child_range children() const { 583 return const_cast<OMPExecutableDirective *>(this)->children(); 584 } 585 clauses()586 ArrayRef<OMPClause *> clauses() const { 587 if (!Data) 588 return std::nullopt; 589 return Data->getClauses(); 590 } 591 592 /// Returns whether or not this is a Standalone directive. 593 /// 594 /// Stand-alone directives are executable directives 595 /// that have no associated user code. 596 bool isStandaloneDirective() const; 597 598 /// Returns the AST node representing OpenMP structured-block of this 599 /// OpenMP executable directive, 600 /// Prerequisite: Executable Directive must not be Standalone directive. getStructuredBlock()601 const Stmt *getStructuredBlock() const { 602 return const_cast<OMPExecutableDirective *>(this)->getStructuredBlock(); 603 } 604 Stmt *getStructuredBlock(); 605 getRawStmt()606 const Stmt *getRawStmt() const { 607 return const_cast<OMPExecutableDirective *>(this)->getRawStmt(); 608 } getRawStmt()609 Stmt *getRawStmt() { 610 assert(hasAssociatedStmt() && 611 "Expected directive with the associated statement."); 612 return Data->getRawStmt(); 613 } 614 getMappedDirective()615 OpenMPDirectiveKind getMappedDirective() const { return PrevMappedDirective; } 616 }; 617 618 /// This represents '#pragma omp parallel' directive. 619 /// 620 /// \code 621 /// #pragma omp parallel private(a,b) reduction(+: c,d) 622 /// \endcode 623 /// In this example directive '#pragma omp parallel' has clauses 'private' 624 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and 625 /// variables 'c' and 'd'. 626 /// 627 class OMPParallelDirective : public OMPExecutableDirective { 628 friend class ASTStmtReader; 629 friend class OMPExecutableDirective; 630 /// true if the construct has inner cancel directive. 631 bool HasCancel = false; 632 633 /// Build directive with the given start and end location. 634 /// 635 /// \param StartLoc Starting location of the directive (directive keyword). 636 /// \param EndLoc Ending Location of the directive. 637 /// OMPParallelDirective(SourceLocation StartLoc,SourceLocation EndLoc)638 OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc) 639 : OMPExecutableDirective(OMPParallelDirectiveClass, 640 llvm::omp::OMPD_parallel, StartLoc, EndLoc) {} 641 642 /// Build an empty directive. 643 /// OMPParallelDirective()644 explicit OMPParallelDirective() 645 : OMPExecutableDirective(OMPParallelDirectiveClass, 646 llvm::omp::OMPD_parallel, SourceLocation(), 647 SourceLocation()) {} 648 649 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)650 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 651 652 /// Set cancel state. setHasCancel(bool Has)653 void setHasCancel(bool Has) { HasCancel = Has; } 654 655 public: 656 /// Creates directive with a list of \a Clauses. 657 /// 658 /// \param C AST context. 659 /// \param StartLoc Starting location of the directive kind. 660 /// \param EndLoc Ending Location of the directive. 661 /// \param Clauses List of clauses. 662 /// \param AssociatedStmt Statement associated with the directive. 663 /// \param TaskRedRef Task reduction special reference expression to handle 664 /// taskgroup descriptor. 665 /// \param HasCancel true if this directive has inner cancel directive. 666 /// 667 static OMPParallelDirective * 668 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 669 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 670 bool HasCancel); 671 672 /// Creates an empty directive with the place for \a N clauses. 673 /// 674 /// \param C AST context. 675 /// \param NumClauses Number of clauses. 676 /// 677 static OMPParallelDirective *CreateEmpty(const ASTContext &C, 678 unsigned NumClauses, EmptyShell); 679 680 /// Returns special task reduction reference expression. getTaskReductionRefExpr()681 Expr *getTaskReductionRefExpr() { 682 return cast_or_null<Expr>(Data->getChildren()[0]); 683 } getTaskReductionRefExpr()684 const Expr *getTaskReductionRefExpr() const { 685 return const_cast<OMPParallelDirective *>(this)->getTaskReductionRefExpr(); 686 } 687 688 /// Return true if current directive has inner cancel directive. hasCancel()689 bool hasCancel() const { return HasCancel; } 690 classof(const Stmt * T)691 static bool classof(const Stmt *T) { 692 return T->getStmtClass() == OMPParallelDirectiveClass; 693 } 694 }; 695 696 /// The base class for all loop-based directives, including loop transformation 697 /// directives. 698 class OMPLoopBasedDirective : public OMPExecutableDirective { 699 friend class ASTStmtReader; 700 701 protected: 702 /// Number of collapsed loops as specified by 'collapse' clause. 703 unsigned NumAssociatedLoops = 0; 704 705 /// Build instance of loop directive of class \a Kind. 706 /// 707 /// \param SC Statement class. 708 /// \param Kind Kind of OpenMP directive. 709 /// \param StartLoc Starting location of the directive (directive keyword). 710 /// \param EndLoc Ending location of the directive. 711 /// \param NumAssociatedLoops Number of loops associated with the construct. 712 /// OMPLoopBasedDirective(StmtClass SC,OpenMPDirectiveKind Kind,SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumAssociatedLoops)713 OMPLoopBasedDirective(StmtClass SC, OpenMPDirectiveKind Kind, 714 SourceLocation StartLoc, SourceLocation EndLoc, 715 unsigned NumAssociatedLoops) 716 : OMPExecutableDirective(SC, Kind, StartLoc, EndLoc), 717 NumAssociatedLoops(NumAssociatedLoops) {} 718 719 public: 720 /// The expressions built to support OpenMP loops in combined/composite 721 /// pragmas (e.g. pragma omp distribute parallel for) 722 struct DistCombinedHelperExprs { 723 /// DistributeLowerBound - used when composing 'omp distribute' with 724 /// 'omp for' in a same construct. 725 Expr *LB; 726 /// DistributeUpperBound - used when composing 'omp distribute' with 727 /// 'omp for' in a same construct. 728 Expr *UB; 729 /// DistributeEnsureUpperBound - used when composing 'omp distribute' 730 /// with 'omp for' in a same construct, EUB depends on DistUB 731 Expr *EUB; 732 /// Distribute loop iteration variable init used when composing 'omp 733 /// distribute' 734 /// with 'omp for' in a same construct 735 Expr *Init; 736 /// Distribute Loop condition used when composing 'omp distribute' 737 /// with 'omp for' in a same construct 738 Expr *Cond; 739 /// Update of LowerBound for statically scheduled omp loops for 740 /// outer loop in combined constructs (e.g. 'distribute parallel for') 741 Expr *NLB; 742 /// Update of UpperBound for statically scheduled omp loops for 743 /// outer loop in combined constructs (e.g. 'distribute parallel for') 744 Expr *NUB; 745 /// Distribute Loop condition used when composing 'omp distribute' 746 /// with 'omp for' in a same construct when schedule is chunked. 747 Expr *DistCond; 748 /// 'omp parallel for' loop condition used when composed with 749 /// 'omp distribute' in the same construct and when schedule is 750 /// chunked and the chunk size is 1. 751 Expr *ParForInDistCond; 752 }; 753 754 /// The expressions built for the OpenMP loop CodeGen for the 755 /// whole collapsed loop nest. 756 struct HelperExprs { 757 /// Loop iteration variable. 758 Expr *IterationVarRef; 759 /// Loop last iteration number. 760 Expr *LastIteration; 761 /// Loop number of iterations. 762 Expr *NumIterations; 763 /// Calculation of last iteration. 764 Expr *CalcLastIteration; 765 /// Loop pre-condition. 766 Expr *PreCond; 767 /// Loop condition. 768 Expr *Cond; 769 /// Loop iteration variable init. 770 Expr *Init; 771 /// Loop increment. 772 Expr *Inc; 773 /// IsLastIteration - local flag variable passed to runtime. 774 Expr *IL; 775 /// LowerBound - local variable passed to runtime. 776 Expr *LB; 777 /// UpperBound - local variable passed to runtime. 778 Expr *UB; 779 /// Stride - local variable passed to runtime. 780 Expr *ST; 781 /// EnsureUpperBound -- expression UB = min(UB, NumIterations). 782 Expr *EUB; 783 /// Update of LowerBound for statically scheduled 'omp for' loops. 784 Expr *NLB; 785 /// Update of UpperBound for statically scheduled 'omp for' loops. 786 Expr *NUB; 787 /// PreviousLowerBound - local variable passed to runtime in the 788 /// enclosing schedule or null if that does not apply. 789 Expr *PrevLB; 790 /// PreviousUpperBound - local variable passed to runtime in the 791 /// enclosing schedule or null if that does not apply. 792 Expr *PrevUB; 793 /// DistInc - increment expression for distribute loop when found 794 /// combined with a further loop level (e.g. in 'distribute parallel for') 795 /// expression IV = IV + ST 796 Expr *DistInc; 797 /// PrevEUB - expression similar to EUB but to be used when loop 798 /// scheduling uses PrevLB and PrevUB (e.g. in 'distribute parallel for' 799 /// when ensuring that the UB is either the calculated UB by the runtime or 800 /// the end of the assigned distribute chunk) 801 /// expression UB = min (UB, PrevUB) 802 Expr *PrevEUB; 803 /// Counters Loop counters. 804 SmallVector<Expr *, 4> Counters; 805 /// PrivateCounters Loop counters. 806 SmallVector<Expr *, 4> PrivateCounters; 807 /// Expressions for loop counters inits for CodeGen. 808 SmallVector<Expr *, 4> Inits; 809 /// Expressions for loop counters update for CodeGen. 810 SmallVector<Expr *, 4> Updates; 811 /// Final loop counter values for GodeGen. 812 SmallVector<Expr *, 4> Finals; 813 /// List of counters required for the generation of the non-rectangular 814 /// loops. 815 SmallVector<Expr *, 4> DependentCounters; 816 /// List of initializers required for the generation of the non-rectangular 817 /// loops. 818 SmallVector<Expr *, 4> DependentInits; 819 /// List of final conditions required for the generation of the 820 /// non-rectangular loops. 821 SmallVector<Expr *, 4> FinalsConditions; 822 /// Init statement for all captured expressions. 823 Stmt *PreInits; 824 825 /// Expressions used when combining OpenMP loop pragmas 826 DistCombinedHelperExprs DistCombinedFields; 827 828 /// Check if all the expressions are built (does not check the 829 /// worksharing ones). builtAllHelperExprs830 bool builtAll() { 831 return IterationVarRef != nullptr && LastIteration != nullptr && 832 NumIterations != nullptr && PreCond != nullptr && 833 Cond != nullptr && Init != nullptr && Inc != nullptr; 834 } 835 836 /// Initialize all the fields to null. 837 /// \param Size Number of elements in the 838 /// counters/finals/updates/dependent_counters/dependent_inits/finals_conditions 839 /// arrays. clearHelperExprs840 void clear(unsigned Size) { 841 IterationVarRef = nullptr; 842 LastIteration = nullptr; 843 CalcLastIteration = nullptr; 844 PreCond = nullptr; 845 Cond = nullptr; 846 Init = nullptr; 847 Inc = nullptr; 848 IL = nullptr; 849 LB = nullptr; 850 UB = nullptr; 851 ST = nullptr; 852 EUB = nullptr; 853 NLB = nullptr; 854 NUB = nullptr; 855 NumIterations = nullptr; 856 PrevLB = nullptr; 857 PrevUB = nullptr; 858 DistInc = nullptr; 859 PrevEUB = nullptr; 860 Counters.resize(Size); 861 PrivateCounters.resize(Size); 862 Inits.resize(Size); 863 Updates.resize(Size); 864 Finals.resize(Size); 865 DependentCounters.resize(Size); 866 DependentInits.resize(Size); 867 FinalsConditions.resize(Size); 868 for (unsigned I = 0; I < Size; ++I) { 869 Counters[I] = nullptr; 870 PrivateCounters[I] = nullptr; 871 Inits[I] = nullptr; 872 Updates[I] = nullptr; 873 Finals[I] = nullptr; 874 DependentCounters[I] = nullptr; 875 DependentInits[I] = nullptr; 876 FinalsConditions[I] = nullptr; 877 } 878 PreInits = nullptr; 879 DistCombinedFields.LB = nullptr; 880 DistCombinedFields.UB = nullptr; 881 DistCombinedFields.EUB = nullptr; 882 DistCombinedFields.Init = nullptr; 883 DistCombinedFields.Cond = nullptr; 884 DistCombinedFields.NLB = nullptr; 885 DistCombinedFields.NUB = nullptr; 886 DistCombinedFields.DistCond = nullptr; 887 DistCombinedFields.ParForInDistCond = nullptr; 888 } 889 }; 890 891 /// Get number of collapsed loops. getLoopsNumber()892 unsigned getLoopsNumber() const { return NumAssociatedLoops; } 893 894 /// Try to find the next loop sub-statement in the specified statement \p 895 /// CurStmt. 896 /// \param TryImperfectlyNestedLoops true, if we need to try to look for the 897 /// imperfectly nested loop. 898 static Stmt *tryToFindNextInnerLoop(Stmt *CurStmt, 899 bool TryImperfectlyNestedLoops); tryToFindNextInnerLoop(const Stmt * CurStmt,bool TryImperfectlyNestedLoops)900 static const Stmt *tryToFindNextInnerLoop(const Stmt *CurStmt, 901 bool TryImperfectlyNestedLoops) { 902 return tryToFindNextInnerLoop(const_cast<Stmt *>(CurStmt), 903 TryImperfectlyNestedLoops); 904 } 905 906 /// Calls the specified callback function for all the loops in \p CurStmt, 907 /// from the outermost to the innermost. 908 static bool 909 doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops, 910 unsigned NumLoops, 911 llvm::function_ref<bool(unsigned, Stmt *)> Callback, 912 llvm::function_ref<void(OMPLoopTransformationDirective *)> 913 OnTransformationCallback); 914 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)915 doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops, 916 unsigned NumLoops, 917 llvm::function_ref<bool(unsigned, const Stmt *)> Callback, 918 llvm::function_ref<void(const OMPLoopTransformationDirective *)> 919 OnTransformationCallback) { 920 auto &&NewCallback = [Callback](unsigned Cnt, Stmt *CurStmt) { 921 return Callback(Cnt, CurStmt); 922 }; 923 auto &&NewTransformCb = 924 [OnTransformationCallback](OMPLoopTransformationDirective *A) { 925 OnTransformationCallback(A); 926 }; 927 return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops, 928 NumLoops, NewCallback, NewTransformCb); 929 } 930 931 /// Calls the specified callback function for all the loops in \p CurStmt, 932 /// from the outermost to the innermost. 933 static bool doForAllLoops(Stmt * CurStmt,bool TryImperfectlyNestedLoops,unsigned NumLoops,llvm::function_ref<bool (unsigned,Stmt *)> Callback)934 doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops, 935 unsigned NumLoops, 936 llvm::function_ref<bool(unsigned, Stmt *)> Callback) { 937 auto &&TransformCb = [](OMPLoopTransformationDirective *) {}; 938 return doForAllLoops(CurStmt, TryImperfectlyNestedLoops, NumLoops, Callback, 939 TransformCb); 940 } 941 static bool doForAllLoops(const Stmt * CurStmt,bool TryImperfectlyNestedLoops,unsigned NumLoops,llvm::function_ref<bool (unsigned,const Stmt *)> Callback)942 doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops, 943 unsigned NumLoops, 944 llvm::function_ref<bool(unsigned, const Stmt *)> Callback) { 945 auto &&NewCallback = [Callback](unsigned Cnt, const Stmt *CurStmt) { 946 return Callback(Cnt, CurStmt); 947 }; 948 return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops, 949 NumLoops, NewCallback); 950 } 951 952 /// Calls the specified callback function for all the loop bodies in \p 953 /// CurStmt, from the outermost loop to the innermost. 954 static void doForAllLoopsBodies( 955 Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops, 956 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)957 static void doForAllLoopsBodies( 958 const Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops, 959 llvm::function_ref<void(unsigned, const Stmt *, const Stmt *)> Callback) { 960 auto &&NewCallback = [Callback](unsigned Cnt, Stmt *Loop, Stmt *Body) { 961 Callback(Cnt, Loop, Body); 962 }; 963 doForAllLoopsBodies(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops, 964 NumLoops, NewCallback); 965 } 966 classof(const Stmt * T)967 static bool classof(const Stmt *T) { 968 if (auto *D = dyn_cast<OMPExecutableDirective>(T)) 969 return isOpenMPLoopDirective(D->getDirectiveKind()); 970 return false; 971 } 972 }; 973 974 /// The base class for all loop transformation directives. 975 class OMPLoopTransformationDirective : public OMPLoopBasedDirective { 976 friend class ASTStmtReader; 977 978 /// Number of loops generated by this loop transformation. 979 unsigned NumGeneratedLoops = 0; 980 981 protected: OMPLoopTransformationDirective(StmtClass SC,OpenMPDirectiveKind Kind,SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumAssociatedLoops)982 explicit OMPLoopTransformationDirective(StmtClass SC, 983 OpenMPDirectiveKind Kind, 984 SourceLocation StartLoc, 985 SourceLocation EndLoc, 986 unsigned NumAssociatedLoops) 987 : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, NumAssociatedLoops) {} 988 989 /// Set the number of loops generated by this loop transformation. setNumGeneratedLoops(unsigned Num)990 void setNumGeneratedLoops(unsigned Num) { NumGeneratedLoops = Num; } 991 992 public: 993 /// Return the number of associated (consumed) loops. getNumAssociatedLoops()994 unsigned getNumAssociatedLoops() const { return getLoopsNumber(); } 995 996 /// Return the number of loops generated by this loop transformation. getNumGeneratedLoops()997 unsigned getNumGeneratedLoops() const { return NumGeneratedLoops; } 998 999 /// Get the de-sugared statements after the loop transformation. 1000 /// 1001 /// Might be nullptr if either the directive generates no loops and is handled 1002 /// directly in CodeGen, or resolving a template-dependence context is 1003 /// required. 1004 Stmt *getTransformedStmt() const; 1005 1006 /// Return preinits statement. 1007 Stmt *getPreInits() const; 1008 classof(const Stmt * T)1009 static bool classof(const Stmt *T) { 1010 Stmt::StmtClass C = T->getStmtClass(); 1011 return C == OMPTileDirectiveClass || C == OMPUnrollDirectiveClass || 1012 C == OMPReverseDirectiveClass || C == OMPInterchangeDirectiveClass; 1013 } 1014 }; 1015 1016 /// This is a common base class for loop directives ('omp simd', 'omp 1017 /// for', 'omp for simd' etc.). It is responsible for the loop code generation. 1018 /// 1019 class OMPLoopDirective : public OMPLoopBasedDirective { 1020 friend class ASTStmtReader; 1021 1022 /// Offsets to the stored exprs. 1023 /// This enumeration contains offsets to all the pointers to children 1024 /// expressions stored in OMPLoopDirective. 1025 /// The first 9 children are necessary for all the loop directives, 1026 /// the next 8 are specific to the worksharing ones, and the next 11 are 1027 /// used for combined constructs containing two pragmas associated to loops. 1028 /// After the fixed children, three arrays of length NumAssociatedLoops are 1029 /// allocated: loop counters, their updates and final values. 1030 /// PrevLowerBound and PrevUpperBound are used to communicate blocking 1031 /// information in composite constructs which require loop blocking 1032 /// DistInc is used to generate the increment expression for the distribute 1033 /// loop when combined with a further nested loop 1034 /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the 1035 /// for loop when combined with a previous distribute loop in the same pragma 1036 /// (e.g. 'distribute parallel for') 1037 /// 1038 enum { 1039 IterationVariableOffset = 0, 1040 LastIterationOffset = 1, 1041 CalcLastIterationOffset = 2, 1042 PreConditionOffset = 3, 1043 CondOffset = 4, 1044 InitOffset = 5, 1045 IncOffset = 6, 1046 PreInitsOffset = 7, 1047 // The '...End' enumerators do not correspond to child expressions - they 1048 // specify the offset to the end (and start of the following counters/ 1049 // updates/finals/dependent_counters/dependent_inits/finals_conditions 1050 // arrays). 1051 DefaultEnd = 8, 1052 // The following 8 exprs are used by worksharing and distribute loops only. 1053 IsLastIterVariableOffset = 8, 1054 LowerBoundVariableOffset = 9, 1055 UpperBoundVariableOffset = 10, 1056 StrideVariableOffset = 11, 1057 EnsureUpperBoundOffset = 12, 1058 NextLowerBoundOffset = 13, 1059 NextUpperBoundOffset = 14, 1060 NumIterationsOffset = 15, 1061 // Offset to the end for worksharing loop directives. 1062 WorksharingEnd = 16, 1063 PrevLowerBoundVariableOffset = 16, 1064 PrevUpperBoundVariableOffset = 17, 1065 DistIncOffset = 18, 1066 PrevEnsureUpperBoundOffset = 19, 1067 CombinedLowerBoundVariableOffset = 20, 1068 CombinedUpperBoundVariableOffset = 21, 1069 CombinedEnsureUpperBoundOffset = 22, 1070 CombinedInitOffset = 23, 1071 CombinedConditionOffset = 24, 1072 CombinedNextLowerBoundOffset = 25, 1073 CombinedNextUpperBoundOffset = 26, 1074 CombinedDistConditionOffset = 27, 1075 CombinedParForInDistConditionOffset = 28, 1076 // Offset to the end (and start of the following 1077 // counters/updates/finals/dependent_counters/dependent_inits/finals_conditions 1078 // arrays) for combined distribute loop directives. 1079 CombinedDistributeEnd = 29, 1080 }; 1081 1082 /// Get the counters storage. getCounters()1083 MutableArrayRef<Expr *> getCounters() { 1084 auto **Storage = reinterpret_cast<Expr **>( 1085 &Data->getChildren()[getArraysOffset(getDirectiveKind())]); 1086 return llvm::MutableArrayRef(Storage, getLoopsNumber()); 1087 } 1088 1089 /// Get the private counters storage. getPrivateCounters()1090 MutableArrayRef<Expr *> getPrivateCounters() { 1091 auto **Storage = reinterpret_cast<Expr **>( 1092 &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1093 getLoopsNumber()]); 1094 return llvm::MutableArrayRef(Storage, getLoopsNumber()); 1095 } 1096 1097 /// Get the updates storage. getInits()1098 MutableArrayRef<Expr *> getInits() { 1099 auto **Storage = reinterpret_cast<Expr **>( 1100 &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1101 2 * getLoopsNumber()]); 1102 return llvm::MutableArrayRef(Storage, getLoopsNumber()); 1103 } 1104 1105 /// Get the updates storage. getUpdates()1106 MutableArrayRef<Expr *> getUpdates() { 1107 auto **Storage = reinterpret_cast<Expr **>( 1108 &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1109 3 * getLoopsNumber()]); 1110 return llvm::MutableArrayRef(Storage, getLoopsNumber()); 1111 } 1112 1113 /// Get the final counter updates storage. getFinals()1114 MutableArrayRef<Expr *> getFinals() { 1115 auto **Storage = reinterpret_cast<Expr **>( 1116 &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1117 4 * getLoopsNumber()]); 1118 return llvm::MutableArrayRef(Storage, getLoopsNumber()); 1119 } 1120 1121 /// Get the dependent counters storage. getDependentCounters()1122 MutableArrayRef<Expr *> getDependentCounters() { 1123 auto **Storage = reinterpret_cast<Expr **>( 1124 &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1125 5 * getLoopsNumber()]); 1126 return llvm::MutableArrayRef(Storage, getLoopsNumber()); 1127 } 1128 1129 /// Get the dependent inits storage. getDependentInits()1130 MutableArrayRef<Expr *> getDependentInits() { 1131 auto **Storage = reinterpret_cast<Expr **>( 1132 &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1133 6 * getLoopsNumber()]); 1134 return llvm::MutableArrayRef(Storage, getLoopsNumber()); 1135 } 1136 1137 /// Get the finals conditions storage. getFinalsConditions()1138 MutableArrayRef<Expr *> getFinalsConditions() { 1139 auto **Storage = reinterpret_cast<Expr **>( 1140 &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1141 7 * getLoopsNumber()]); 1142 return llvm::MutableArrayRef(Storage, getLoopsNumber()); 1143 } 1144 1145 protected: 1146 /// Build instance of loop directive of class \a Kind. 1147 /// 1148 /// \param SC Statement class. 1149 /// \param Kind Kind of OpenMP directive. 1150 /// \param StartLoc Starting location of the directive (directive keyword). 1151 /// \param EndLoc Ending location of the directive. 1152 /// \param CollapsedNum Number of collapsed loops from 'collapse' clause. 1153 /// OMPLoopDirective(StmtClass SC,OpenMPDirectiveKind Kind,SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)1154 OMPLoopDirective(StmtClass SC, OpenMPDirectiveKind Kind, 1155 SourceLocation StartLoc, SourceLocation EndLoc, 1156 unsigned CollapsedNum) 1157 : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, CollapsedNum) {} 1158 1159 /// Offset to the start of children expression arrays. getArraysOffset(OpenMPDirectiveKind Kind)1160 static unsigned getArraysOffset(OpenMPDirectiveKind Kind) { 1161 if (isOpenMPLoopBoundSharingDirective(Kind)) 1162 return CombinedDistributeEnd; 1163 if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) || 1164 isOpenMPGenericLoopDirective(Kind) || isOpenMPDistributeDirective(Kind)) 1165 return WorksharingEnd; 1166 return DefaultEnd; 1167 } 1168 1169 /// Children number. numLoopChildren(unsigned CollapsedNum,OpenMPDirectiveKind Kind)1170 static unsigned numLoopChildren(unsigned CollapsedNum, 1171 OpenMPDirectiveKind Kind) { 1172 return getArraysOffset(Kind) + 1173 8 * CollapsedNum; // Counters, PrivateCounters, Inits, 1174 // Updates, Finals, DependentCounters, 1175 // DependentInits, FinalsConditions. 1176 } 1177 setIterationVariable(Expr * IV)1178 void setIterationVariable(Expr *IV) { 1179 Data->getChildren()[IterationVariableOffset] = IV; 1180 } setLastIteration(Expr * LI)1181 void setLastIteration(Expr *LI) { 1182 Data->getChildren()[LastIterationOffset] = LI; 1183 } setCalcLastIteration(Expr * CLI)1184 void setCalcLastIteration(Expr *CLI) { 1185 Data->getChildren()[CalcLastIterationOffset] = CLI; 1186 } setPreCond(Expr * PC)1187 void setPreCond(Expr *PC) { Data->getChildren()[PreConditionOffset] = PC; } setCond(Expr * Cond)1188 void setCond(Expr *Cond) { Data->getChildren()[CondOffset] = Cond; } setInit(Expr * Init)1189 void setInit(Expr *Init) { Data->getChildren()[InitOffset] = Init; } setInc(Expr * Inc)1190 void setInc(Expr *Inc) { Data->getChildren()[IncOffset] = Inc; } setPreInits(Stmt * PreInits)1191 void setPreInits(Stmt *PreInits) { 1192 Data->getChildren()[PreInitsOffset] = PreInits; 1193 } setIsLastIterVariable(Expr * IL)1194 void setIsLastIterVariable(Expr *IL) { 1195 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1196 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1197 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1198 isOpenMPDistributeDirective(getDirectiveKind())) && 1199 "expected worksharing loop directive"); 1200 Data->getChildren()[IsLastIterVariableOffset] = IL; 1201 } setLowerBoundVariable(Expr * LB)1202 void setLowerBoundVariable(Expr *LB) { 1203 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1204 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1205 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1206 isOpenMPDistributeDirective(getDirectiveKind())) && 1207 "expected worksharing loop directive"); 1208 Data->getChildren()[LowerBoundVariableOffset] = LB; 1209 } setUpperBoundVariable(Expr * UB)1210 void setUpperBoundVariable(Expr *UB) { 1211 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1212 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1213 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1214 isOpenMPDistributeDirective(getDirectiveKind())) && 1215 "expected worksharing loop directive"); 1216 Data->getChildren()[UpperBoundVariableOffset] = UB; 1217 } setStrideVariable(Expr * ST)1218 void setStrideVariable(Expr *ST) { 1219 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1220 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1221 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1222 isOpenMPDistributeDirective(getDirectiveKind())) && 1223 "expected worksharing loop directive"); 1224 Data->getChildren()[StrideVariableOffset] = ST; 1225 } setEnsureUpperBound(Expr * EUB)1226 void setEnsureUpperBound(Expr *EUB) { 1227 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1228 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1229 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1230 isOpenMPDistributeDirective(getDirectiveKind())) && 1231 "expected worksharing loop directive"); 1232 Data->getChildren()[EnsureUpperBoundOffset] = EUB; 1233 } setNextLowerBound(Expr * NLB)1234 void setNextLowerBound(Expr *NLB) { 1235 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1236 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1237 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1238 isOpenMPDistributeDirective(getDirectiveKind())) && 1239 "expected worksharing loop directive"); 1240 Data->getChildren()[NextLowerBoundOffset] = NLB; 1241 } setNextUpperBound(Expr * NUB)1242 void setNextUpperBound(Expr *NUB) { 1243 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1244 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1245 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1246 isOpenMPDistributeDirective(getDirectiveKind())) && 1247 "expected worksharing loop directive"); 1248 Data->getChildren()[NextUpperBoundOffset] = NUB; 1249 } setNumIterations(Expr * NI)1250 void setNumIterations(Expr *NI) { 1251 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1252 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1253 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1254 isOpenMPDistributeDirective(getDirectiveKind())) && 1255 "expected worksharing loop directive"); 1256 Data->getChildren()[NumIterationsOffset] = NI; 1257 } setPrevLowerBoundVariable(Expr * PrevLB)1258 void setPrevLowerBoundVariable(Expr *PrevLB) { 1259 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1260 "expected loop bound sharing directive"); 1261 Data->getChildren()[PrevLowerBoundVariableOffset] = PrevLB; 1262 } setPrevUpperBoundVariable(Expr * PrevUB)1263 void setPrevUpperBoundVariable(Expr *PrevUB) { 1264 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1265 "expected loop bound sharing directive"); 1266 Data->getChildren()[PrevUpperBoundVariableOffset] = PrevUB; 1267 } setDistInc(Expr * DistInc)1268 void setDistInc(Expr *DistInc) { 1269 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1270 "expected loop bound sharing directive"); 1271 Data->getChildren()[DistIncOffset] = DistInc; 1272 } setPrevEnsureUpperBound(Expr * PrevEUB)1273 void setPrevEnsureUpperBound(Expr *PrevEUB) { 1274 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1275 "expected loop bound sharing directive"); 1276 Data->getChildren()[PrevEnsureUpperBoundOffset] = PrevEUB; 1277 } setCombinedLowerBoundVariable(Expr * CombLB)1278 void setCombinedLowerBoundVariable(Expr *CombLB) { 1279 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1280 "expected loop bound sharing directive"); 1281 Data->getChildren()[CombinedLowerBoundVariableOffset] = CombLB; 1282 } setCombinedUpperBoundVariable(Expr * CombUB)1283 void setCombinedUpperBoundVariable(Expr *CombUB) { 1284 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1285 "expected loop bound sharing directive"); 1286 Data->getChildren()[CombinedUpperBoundVariableOffset] = CombUB; 1287 } setCombinedEnsureUpperBound(Expr * CombEUB)1288 void setCombinedEnsureUpperBound(Expr *CombEUB) { 1289 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1290 "expected loop bound sharing directive"); 1291 Data->getChildren()[CombinedEnsureUpperBoundOffset] = CombEUB; 1292 } setCombinedInit(Expr * CombInit)1293 void setCombinedInit(Expr *CombInit) { 1294 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1295 "expected loop bound sharing directive"); 1296 Data->getChildren()[CombinedInitOffset] = CombInit; 1297 } setCombinedCond(Expr * CombCond)1298 void setCombinedCond(Expr *CombCond) { 1299 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1300 "expected loop bound sharing directive"); 1301 Data->getChildren()[CombinedConditionOffset] = CombCond; 1302 } setCombinedNextLowerBound(Expr * CombNLB)1303 void setCombinedNextLowerBound(Expr *CombNLB) { 1304 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1305 "expected loop bound sharing directive"); 1306 Data->getChildren()[CombinedNextLowerBoundOffset] = CombNLB; 1307 } setCombinedNextUpperBound(Expr * CombNUB)1308 void setCombinedNextUpperBound(Expr *CombNUB) { 1309 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1310 "expected loop bound sharing directive"); 1311 Data->getChildren()[CombinedNextUpperBoundOffset] = CombNUB; 1312 } setCombinedDistCond(Expr * CombDistCond)1313 void setCombinedDistCond(Expr *CombDistCond) { 1314 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1315 "expected loop bound distribute sharing directive"); 1316 Data->getChildren()[CombinedDistConditionOffset] = CombDistCond; 1317 } setCombinedParForInDistCond(Expr * CombParForInDistCond)1318 void setCombinedParForInDistCond(Expr *CombParForInDistCond) { 1319 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1320 "expected loop bound distribute sharing directive"); 1321 Data->getChildren()[CombinedParForInDistConditionOffset] = 1322 CombParForInDistCond; 1323 } 1324 void setCounters(ArrayRef<Expr *> A); 1325 void setPrivateCounters(ArrayRef<Expr *> A); 1326 void setInits(ArrayRef<Expr *> A); 1327 void setUpdates(ArrayRef<Expr *> A); 1328 void setFinals(ArrayRef<Expr *> A); 1329 void setDependentCounters(ArrayRef<Expr *> A); 1330 void setDependentInits(ArrayRef<Expr *> A); 1331 void setFinalsConditions(ArrayRef<Expr *> A); 1332 1333 public: getIterationVariable()1334 Expr *getIterationVariable() const { 1335 return cast<Expr>(Data->getChildren()[IterationVariableOffset]); 1336 } getLastIteration()1337 Expr *getLastIteration() const { 1338 return cast<Expr>(Data->getChildren()[LastIterationOffset]); 1339 } getCalcLastIteration()1340 Expr *getCalcLastIteration() const { 1341 return cast<Expr>(Data->getChildren()[CalcLastIterationOffset]); 1342 } getPreCond()1343 Expr *getPreCond() const { 1344 return cast<Expr>(Data->getChildren()[PreConditionOffset]); 1345 } getCond()1346 Expr *getCond() const { return cast<Expr>(Data->getChildren()[CondOffset]); } getInit()1347 Expr *getInit() const { return cast<Expr>(Data->getChildren()[InitOffset]); } getInc()1348 Expr *getInc() const { return cast<Expr>(Data->getChildren()[IncOffset]); } getPreInits()1349 const Stmt *getPreInits() const { 1350 return Data->getChildren()[PreInitsOffset]; 1351 } getPreInits()1352 Stmt *getPreInits() { return Data->getChildren()[PreInitsOffset]; } getIsLastIterVariable()1353 Expr *getIsLastIterVariable() const { 1354 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1355 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1356 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1357 isOpenMPDistributeDirective(getDirectiveKind())) && 1358 "expected worksharing loop directive"); 1359 return cast<Expr>(Data->getChildren()[IsLastIterVariableOffset]); 1360 } getLowerBoundVariable()1361 Expr *getLowerBoundVariable() const { 1362 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1363 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1364 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1365 isOpenMPDistributeDirective(getDirectiveKind())) && 1366 "expected worksharing loop directive"); 1367 return cast<Expr>(Data->getChildren()[LowerBoundVariableOffset]); 1368 } getUpperBoundVariable()1369 Expr *getUpperBoundVariable() const { 1370 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1371 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1372 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1373 isOpenMPDistributeDirective(getDirectiveKind())) && 1374 "expected worksharing loop directive"); 1375 return cast<Expr>(Data->getChildren()[UpperBoundVariableOffset]); 1376 } getStrideVariable()1377 Expr *getStrideVariable() const { 1378 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1379 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1380 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1381 isOpenMPDistributeDirective(getDirectiveKind())) && 1382 "expected worksharing loop directive"); 1383 return cast<Expr>(Data->getChildren()[StrideVariableOffset]); 1384 } getEnsureUpperBound()1385 Expr *getEnsureUpperBound() const { 1386 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1387 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1388 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1389 isOpenMPDistributeDirective(getDirectiveKind())) && 1390 "expected worksharing loop directive"); 1391 return cast<Expr>(Data->getChildren()[EnsureUpperBoundOffset]); 1392 } getNextLowerBound()1393 Expr *getNextLowerBound() const { 1394 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1395 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1396 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1397 isOpenMPDistributeDirective(getDirectiveKind())) && 1398 "expected worksharing loop directive"); 1399 return cast<Expr>(Data->getChildren()[NextLowerBoundOffset]); 1400 } getNextUpperBound()1401 Expr *getNextUpperBound() const { 1402 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1403 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1404 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1405 isOpenMPDistributeDirective(getDirectiveKind())) && 1406 "expected worksharing loop directive"); 1407 return cast<Expr>(Data->getChildren()[NextUpperBoundOffset]); 1408 } getNumIterations()1409 Expr *getNumIterations() const { 1410 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1411 isOpenMPGenericLoopDirective(getDirectiveKind()) || 1412 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1413 isOpenMPDistributeDirective(getDirectiveKind())) && 1414 "expected worksharing loop directive"); 1415 return cast<Expr>(Data->getChildren()[NumIterationsOffset]); 1416 } getPrevLowerBoundVariable()1417 Expr *getPrevLowerBoundVariable() const { 1418 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1419 "expected loop bound sharing directive"); 1420 return cast<Expr>(Data->getChildren()[PrevLowerBoundVariableOffset]); 1421 } getPrevUpperBoundVariable()1422 Expr *getPrevUpperBoundVariable() const { 1423 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1424 "expected loop bound sharing directive"); 1425 return cast<Expr>(Data->getChildren()[PrevUpperBoundVariableOffset]); 1426 } getDistInc()1427 Expr *getDistInc() const { 1428 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1429 "expected loop bound sharing directive"); 1430 return cast<Expr>(Data->getChildren()[DistIncOffset]); 1431 } getPrevEnsureUpperBound()1432 Expr *getPrevEnsureUpperBound() const { 1433 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1434 "expected loop bound sharing directive"); 1435 return cast<Expr>(Data->getChildren()[PrevEnsureUpperBoundOffset]); 1436 } getCombinedLowerBoundVariable()1437 Expr *getCombinedLowerBoundVariable() const { 1438 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1439 "expected loop bound sharing directive"); 1440 return cast<Expr>(Data->getChildren()[CombinedLowerBoundVariableOffset]); 1441 } getCombinedUpperBoundVariable()1442 Expr *getCombinedUpperBoundVariable() const { 1443 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1444 "expected loop bound sharing directive"); 1445 return cast<Expr>(Data->getChildren()[CombinedUpperBoundVariableOffset]); 1446 } getCombinedEnsureUpperBound()1447 Expr *getCombinedEnsureUpperBound() const { 1448 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1449 "expected loop bound sharing directive"); 1450 return cast<Expr>(Data->getChildren()[CombinedEnsureUpperBoundOffset]); 1451 } getCombinedInit()1452 Expr *getCombinedInit() const { 1453 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1454 "expected loop bound sharing directive"); 1455 return cast<Expr>(Data->getChildren()[CombinedInitOffset]); 1456 } getCombinedCond()1457 Expr *getCombinedCond() const { 1458 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1459 "expected loop bound sharing directive"); 1460 return cast<Expr>(Data->getChildren()[CombinedConditionOffset]); 1461 } getCombinedNextLowerBound()1462 Expr *getCombinedNextLowerBound() const { 1463 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1464 "expected loop bound sharing directive"); 1465 return cast<Expr>(Data->getChildren()[CombinedNextLowerBoundOffset]); 1466 } getCombinedNextUpperBound()1467 Expr *getCombinedNextUpperBound() const { 1468 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1469 "expected loop bound sharing directive"); 1470 return cast<Expr>(Data->getChildren()[CombinedNextUpperBoundOffset]); 1471 } getCombinedDistCond()1472 Expr *getCombinedDistCond() const { 1473 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1474 "expected loop bound distribute sharing directive"); 1475 return cast<Expr>(Data->getChildren()[CombinedDistConditionOffset]); 1476 } getCombinedParForInDistCond()1477 Expr *getCombinedParForInDistCond() const { 1478 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1479 "expected loop bound distribute sharing directive"); 1480 return cast<Expr>(Data->getChildren()[CombinedParForInDistConditionOffset]); 1481 } 1482 Stmt *getBody(); getBody()1483 const Stmt *getBody() const { 1484 return const_cast<OMPLoopDirective *>(this)->getBody(); 1485 } 1486 counters()1487 ArrayRef<Expr *> counters() { return getCounters(); } 1488 counters()1489 ArrayRef<Expr *> counters() const { 1490 return const_cast<OMPLoopDirective *>(this)->getCounters(); 1491 } 1492 private_counters()1493 ArrayRef<Expr *> private_counters() { return getPrivateCounters(); } 1494 private_counters()1495 ArrayRef<Expr *> private_counters() const { 1496 return const_cast<OMPLoopDirective *>(this)->getPrivateCounters(); 1497 } 1498 inits()1499 ArrayRef<Expr *> inits() { return getInits(); } 1500 inits()1501 ArrayRef<Expr *> inits() const { 1502 return const_cast<OMPLoopDirective *>(this)->getInits(); 1503 } 1504 updates()1505 ArrayRef<Expr *> updates() { return getUpdates(); } 1506 updates()1507 ArrayRef<Expr *> updates() const { 1508 return const_cast<OMPLoopDirective *>(this)->getUpdates(); 1509 } 1510 finals()1511 ArrayRef<Expr *> finals() { return getFinals(); } 1512 finals()1513 ArrayRef<Expr *> finals() const { 1514 return const_cast<OMPLoopDirective *>(this)->getFinals(); 1515 } 1516 dependent_counters()1517 ArrayRef<Expr *> dependent_counters() { return getDependentCounters(); } 1518 dependent_counters()1519 ArrayRef<Expr *> dependent_counters() const { 1520 return const_cast<OMPLoopDirective *>(this)->getDependentCounters(); 1521 } 1522 dependent_inits()1523 ArrayRef<Expr *> dependent_inits() { return getDependentInits(); } 1524 dependent_inits()1525 ArrayRef<Expr *> dependent_inits() const { 1526 return const_cast<OMPLoopDirective *>(this)->getDependentInits(); 1527 } 1528 finals_conditions()1529 ArrayRef<Expr *> finals_conditions() { return getFinalsConditions(); } 1530 finals_conditions()1531 ArrayRef<Expr *> finals_conditions() const { 1532 return const_cast<OMPLoopDirective *>(this)->getFinalsConditions(); 1533 } 1534 classof(const Stmt * T)1535 static bool classof(const Stmt *T) { 1536 return T->getStmtClass() == OMPSimdDirectiveClass || 1537 T->getStmtClass() == OMPForDirectiveClass || 1538 T->getStmtClass() == OMPForSimdDirectiveClass || 1539 T->getStmtClass() == OMPParallelForDirectiveClass || 1540 T->getStmtClass() == OMPParallelForSimdDirectiveClass || 1541 T->getStmtClass() == OMPTaskLoopDirectiveClass || 1542 T->getStmtClass() == OMPTaskLoopSimdDirectiveClass || 1543 T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass || 1544 T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass || 1545 T->getStmtClass() == OMPMasterTaskLoopDirectiveClass || 1546 T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass || 1547 T->getStmtClass() == OMPGenericLoopDirectiveClass || 1548 T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass || 1549 T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass || 1550 T->getStmtClass() == OMPParallelGenericLoopDirectiveClass || 1551 T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass || 1552 T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass || 1553 T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass || 1554 T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass || 1555 T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass || 1556 T->getStmtClass() == OMPDistributeDirectiveClass || 1557 T->getStmtClass() == OMPTargetParallelForDirectiveClass || 1558 T->getStmtClass() == OMPDistributeParallelForDirectiveClass || 1559 T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass || 1560 T->getStmtClass() == OMPDistributeSimdDirectiveClass || 1561 T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass || 1562 T->getStmtClass() == OMPTargetSimdDirectiveClass || 1563 T->getStmtClass() == OMPTeamsDistributeDirectiveClass || 1564 T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass || 1565 T->getStmtClass() == 1566 OMPTeamsDistributeParallelForSimdDirectiveClass || 1567 T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass || 1568 T->getStmtClass() == 1569 OMPTargetTeamsDistributeParallelForDirectiveClass || 1570 T->getStmtClass() == 1571 OMPTargetTeamsDistributeParallelForSimdDirectiveClass || 1572 T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass || 1573 T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass; 1574 } 1575 }; 1576 1577 /// This represents '#pragma omp simd' directive. 1578 /// 1579 /// \code 1580 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d) 1581 /// \endcode 1582 /// In this example directive '#pragma omp simd' has clauses 'private' 1583 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and 1584 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. 1585 /// 1586 class OMPSimdDirective : public OMPLoopDirective { 1587 friend class ASTStmtReader; 1588 friend class OMPExecutableDirective; 1589 /// Build directive with the given start and end location. 1590 /// 1591 /// \param StartLoc Starting location of the directive kind. 1592 /// \param EndLoc Ending location of the directive. 1593 /// \param CollapsedNum Number of collapsed nested loops. 1594 /// OMPSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)1595 OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1596 unsigned CollapsedNum) 1597 : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, StartLoc, 1598 EndLoc, CollapsedNum) {} 1599 1600 /// Build an empty directive. 1601 /// 1602 /// \param CollapsedNum Number of collapsed nested loops. 1603 /// OMPSimdDirective(unsigned CollapsedNum)1604 explicit OMPSimdDirective(unsigned CollapsedNum) 1605 : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, 1606 SourceLocation(), SourceLocation(), CollapsedNum) {} 1607 1608 public: 1609 /// Creates directive with a list of \a Clauses. 1610 /// 1611 /// \param C AST context. 1612 /// \param StartLoc Starting location of the directive kind. 1613 /// \param EndLoc Ending Location of the directive. 1614 /// \param CollapsedNum Number of collapsed loops. 1615 /// \param Clauses List of clauses. 1616 /// \param AssociatedStmt Statement, associated with the directive. 1617 /// \param Exprs Helper expressions for CodeGen. 1618 /// 1619 static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc, 1620 SourceLocation EndLoc, unsigned CollapsedNum, 1621 ArrayRef<OMPClause *> Clauses, 1622 Stmt *AssociatedStmt, 1623 const HelperExprs &Exprs, 1624 OpenMPDirectiveKind ParamPrevMappedDirective); 1625 1626 /// Creates an empty directive with the place 1627 /// for \a NumClauses clauses. 1628 /// 1629 /// \param C AST context. 1630 /// \param CollapsedNum Number of collapsed nested loops. 1631 /// \param NumClauses Number of clauses. 1632 /// 1633 static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 1634 unsigned CollapsedNum, EmptyShell); 1635 classof(const Stmt * T)1636 static bool classof(const Stmt *T) { 1637 return T->getStmtClass() == OMPSimdDirectiveClass; 1638 } 1639 }; 1640 1641 /// This represents '#pragma omp for' directive. 1642 /// 1643 /// \code 1644 /// #pragma omp for private(a,b) reduction(+:c,d) 1645 /// \endcode 1646 /// In this example directive '#pragma omp for' has clauses 'private' with the 1647 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c' 1648 /// and 'd'. 1649 /// 1650 class OMPForDirective : public OMPLoopDirective { 1651 friend class ASTStmtReader; 1652 friend class OMPExecutableDirective; 1653 /// true if current directive has inner cancel directive. 1654 bool HasCancel = false; 1655 1656 /// Build directive with the given start and end location. 1657 /// 1658 /// \param StartLoc Starting location of the directive kind. 1659 /// \param EndLoc Ending location of the directive. 1660 /// \param CollapsedNum Number of collapsed nested loops. 1661 /// OMPForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)1662 OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1663 unsigned CollapsedNum) 1664 : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, StartLoc, 1665 EndLoc, CollapsedNum) {} 1666 1667 /// Build an empty directive. 1668 /// 1669 /// \param CollapsedNum Number of collapsed nested loops. 1670 /// OMPForDirective(unsigned CollapsedNum)1671 explicit OMPForDirective(unsigned CollapsedNum) 1672 : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, 1673 SourceLocation(), SourceLocation(), CollapsedNum) {} 1674 1675 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)1676 void setTaskReductionRefExpr(Expr *E) { 1677 Data->getChildren()[numLoopChildren(getLoopsNumber(), 1678 llvm::omp::OMPD_for)] = E; 1679 } 1680 1681 /// Set cancel state. setHasCancel(bool Has)1682 void setHasCancel(bool Has) { HasCancel = Has; } 1683 1684 public: 1685 /// Creates directive with a list of \a Clauses. 1686 /// 1687 /// \param C AST context. 1688 /// \param StartLoc Starting location of the directive kind. 1689 /// \param EndLoc Ending Location of the directive. 1690 /// \param CollapsedNum Number of collapsed loops. 1691 /// \param Clauses List of clauses. 1692 /// \param AssociatedStmt Statement, associated with the directive. 1693 /// \param Exprs Helper expressions for CodeGen. 1694 /// \param TaskRedRef Task reduction special reference expression to handle 1695 /// taskgroup descriptor. 1696 /// \param HasCancel true if current directive has inner cancel directive. 1697 /// 1698 static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc, 1699 SourceLocation EndLoc, unsigned CollapsedNum, 1700 ArrayRef<OMPClause *> Clauses, 1701 Stmt *AssociatedStmt, const HelperExprs &Exprs, 1702 Expr *TaskRedRef, bool HasCancel, 1703 OpenMPDirectiveKind ParamPrevMappedDirective); 1704 1705 /// Creates an empty directive with the place 1706 /// for \a NumClauses clauses. 1707 /// 1708 /// \param C AST context. 1709 /// \param CollapsedNum Number of collapsed nested loops. 1710 /// \param NumClauses Number of clauses. 1711 /// 1712 static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 1713 unsigned CollapsedNum, EmptyShell); 1714 1715 /// Returns special task reduction reference expression. getTaskReductionRefExpr()1716 Expr *getTaskReductionRefExpr() { 1717 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 1718 getLoopsNumber(), llvm::omp::OMPD_for)]); 1719 } getTaskReductionRefExpr()1720 const Expr *getTaskReductionRefExpr() const { 1721 return const_cast<OMPForDirective *>(this)->getTaskReductionRefExpr(); 1722 } 1723 1724 /// Return true if current directive has inner cancel directive. hasCancel()1725 bool hasCancel() const { return HasCancel; } 1726 classof(const Stmt * T)1727 static bool classof(const Stmt *T) { 1728 return T->getStmtClass() == OMPForDirectiveClass; 1729 } 1730 }; 1731 1732 /// This represents '#pragma omp for simd' directive. 1733 /// 1734 /// \code 1735 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d) 1736 /// \endcode 1737 /// In this example directive '#pragma omp for simd' has clauses 'private' 1738 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and 1739 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. 1740 /// 1741 class OMPForSimdDirective : public OMPLoopDirective { 1742 friend class ASTStmtReader; 1743 friend class OMPExecutableDirective; 1744 /// Build directive with the given start and end location. 1745 /// 1746 /// \param StartLoc Starting location of the directive kind. 1747 /// \param EndLoc Ending location of the directive. 1748 /// \param CollapsedNum Number of collapsed nested loops. 1749 /// OMPForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)1750 OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1751 unsigned CollapsedNum) 1752 : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd, 1753 StartLoc, EndLoc, CollapsedNum) {} 1754 1755 /// Build an empty directive. 1756 /// 1757 /// \param CollapsedNum Number of collapsed nested loops. 1758 /// OMPForSimdDirective(unsigned CollapsedNum)1759 explicit OMPForSimdDirective(unsigned CollapsedNum) 1760 : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd, 1761 SourceLocation(), SourceLocation(), CollapsedNum) {} 1762 1763 public: 1764 /// Creates directive with a list of \a Clauses. 1765 /// 1766 /// \param C AST context. 1767 /// \param StartLoc Starting location of the directive kind. 1768 /// \param EndLoc Ending Location of the directive. 1769 /// \param CollapsedNum Number of collapsed loops. 1770 /// \param Clauses List of clauses. 1771 /// \param AssociatedStmt Statement, associated with the directive. 1772 /// \param Exprs Helper expressions for CodeGen. 1773 /// 1774 static OMPForSimdDirective * 1775 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1776 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 1777 Stmt *AssociatedStmt, const HelperExprs &Exprs); 1778 1779 /// Creates an empty directive with the place 1780 /// for \a NumClauses clauses. 1781 /// 1782 /// \param C AST context. 1783 /// \param CollapsedNum Number of collapsed nested loops. 1784 /// \param NumClauses Number of clauses. 1785 /// 1786 static OMPForSimdDirective *CreateEmpty(const ASTContext &C, 1787 unsigned NumClauses, 1788 unsigned CollapsedNum, EmptyShell); 1789 classof(const Stmt * T)1790 static bool classof(const Stmt *T) { 1791 return T->getStmtClass() == OMPForSimdDirectiveClass; 1792 } 1793 }; 1794 1795 /// This represents '#pragma omp sections' directive. 1796 /// 1797 /// \code 1798 /// #pragma omp sections private(a,b) reduction(+:c,d) 1799 /// \endcode 1800 /// In this example directive '#pragma omp sections' has clauses 'private' with 1801 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables 1802 /// 'c' and 'd'. 1803 /// 1804 class OMPSectionsDirective : public OMPExecutableDirective { 1805 friend class ASTStmtReader; 1806 friend class OMPExecutableDirective; 1807 1808 /// true if current directive has inner cancel directive. 1809 bool HasCancel = false; 1810 1811 /// Build directive with the given start and end location. 1812 /// 1813 /// \param StartLoc Starting location of the directive kind. 1814 /// \param EndLoc Ending location of the directive. 1815 /// OMPSectionsDirective(SourceLocation StartLoc,SourceLocation EndLoc)1816 OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1817 : OMPExecutableDirective(OMPSectionsDirectiveClass, 1818 llvm::omp::OMPD_sections, StartLoc, EndLoc) {} 1819 1820 /// Build an empty directive. 1821 /// OMPSectionsDirective()1822 explicit OMPSectionsDirective() 1823 : OMPExecutableDirective(OMPSectionsDirectiveClass, 1824 llvm::omp::OMPD_sections, SourceLocation(), 1825 SourceLocation()) {} 1826 1827 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)1828 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 1829 1830 /// Set cancel state. setHasCancel(bool Has)1831 void setHasCancel(bool Has) { HasCancel = Has; } 1832 1833 public: 1834 /// Creates directive with a list of \a Clauses. 1835 /// 1836 /// \param C AST context. 1837 /// \param StartLoc Starting location of the directive kind. 1838 /// \param EndLoc Ending Location of the directive. 1839 /// \param Clauses List of clauses. 1840 /// \param AssociatedStmt Statement, associated with the directive. 1841 /// \param TaskRedRef Task reduction special reference expression to handle 1842 /// taskgroup descriptor. 1843 /// \param HasCancel true if current directive has inner directive. 1844 /// 1845 static OMPSectionsDirective * 1846 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1847 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 1848 bool HasCancel); 1849 1850 /// Creates an empty directive with the place for \a NumClauses 1851 /// clauses. 1852 /// 1853 /// \param C AST context. 1854 /// \param NumClauses Number of clauses. 1855 /// 1856 static OMPSectionsDirective *CreateEmpty(const ASTContext &C, 1857 unsigned NumClauses, EmptyShell); 1858 1859 /// Returns special task reduction reference expression. getTaskReductionRefExpr()1860 Expr *getTaskReductionRefExpr() { 1861 return cast_or_null<Expr>(Data->getChildren()[0]); 1862 } getTaskReductionRefExpr()1863 const Expr *getTaskReductionRefExpr() const { 1864 return const_cast<OMPSectionsDirective *>(this)->getTaskReductionRefExpr(); 1865 } 1866 1867 /// Return true if current directive has inner cancel directive. hasCancel()1868 bool hasCancel() const { return HasCancel; } 1869 classof(const Stmt * T)1870 static bool classof(const Stmt *T) { 1871 return T->getStmtClass() == OMPSectionsDirectiveClass; 1872 } 1873 }; 1874 1875 /// This represents '#pragma omp section' directive. 1876 /// 1877 /// \code 1878 /// #pragma omp section 1879 /// \endcode 1880 /// 1881 class OMPSectionDirective : public OMPExecutableDirective { 1882 friend class ASTStmtReader; 1883 friend class OMPExecutableDirective; 1884 1885 /// true if current directive has inner cancel directive. 1886 bool HasCancel = false; 1887 1888 /// Build directive with the given start and end location. 1889 /// 1890 /// \param StartLoc Starting location of the directive kind. 1891 /// \param EndLoc Ending location of the directive. 1892 /// OMPSectionDirective(SourceLocation StartLoc,SourceLocation EndLoc)1893 OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1894 : OMPExecutableDirective(OMPSectionDirectiveClass, 1895 llvm::omp::OMPD_section, StartLoc, EndLoc) {} 1896 1897 /// Build an empty directive. 1898 /// OMPSectionDirective()1899 explicit OMPSectionDirective() 1900 : OMPExecutableDirective(OMPSectionDirectiveClass, 1901 llvm::omp::OMPD_section, SourceLocation(), 1902 SourceLocation()) {} 1903 1904 public: 1905 /// Creates directive. 1906 /// 1907 /// \param C AST context. 1908 /// \param StartLoc Starting location of the directive kind. 1909 /// \param EndLoc Ending Location of the directive. 1910 /// \param AssociatedStmt Statement, associated with the directive. 1911 /// \param HasCancel true if current directive has inner directive. 1912 /// 1913 static OMPSectionDirective *Create(const ASTContext &C, 1914 SourceLocation StartLoc, 1915 SourceLocation EndLoc, 1916 Stmt *AssociatedStmt, bool HasCancel); 1917 1918 /// Creates an empty directive. 1919 /// 1920 /// \param C AST context. 1921 /// 1922 static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell); 1923 1924 /// Set cancel state. setHasCancel(bool Has)1925 void setHasCancel(bool Has) { HasCancel = Has; } 1926 1927 /// Return true if current directive has inner cancel directive. hasCancel()1928 bool hasCancel() const { return HasCancel; } 1929 classof(const Stmt * T)1930 static bool classof(const Stmt *T) { 1931 return T->getStmtClass() == OMPSectionDirectiveClass; 1932 } 1933 }; 1934 1935 /// This represents '#pragma omp scope' directive. 1936 /// \code 1937 /// #pragma omp scope private(a,b) nowait 1938 /// \endcode 1939 /// In this example directive '#pragma omp scope' has clauses 'private' with 1940 /// the variables 'a' and 'b' and nowait. 1941 /// 1942 class OMPScopeDirective final : public OMPExecutableDirective { 1943 friend class ASTStmtReader; 1944 friend class OMPExecutableDirective; 1945 1946 /// Build directive with the given start and end location. 1947 /// 1948 /// \param StartLoc Starting location of the directive kind. 1949 /// \param EndLoc Ending location of the directive. 1950 /// OMPScopeDirective(SourceLocation StartLoc,SourceLocation EndLoc)1951 OMPScopeDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1952 : OMPExecutableDirective(OMPScopeDirectiveClass, llvm::omp::OMPD_scope, 1953 StartLoc, EndLoc) {} 1954 1955 /// Build an empty directive. 1956 /// OMPScopeDirective()1957 explicit OMPScopeDirective() 1958 : OMPExecutableDirective(OMPScopeDirectiveClass, llvm::omp::OMPD_scope, 1959 SourceLocation(), SourceLocation()) {} 1960 1961 public: 1962 /// Creates directive. 1963 /// 1964 /// \param C AST context. 1965 /// \param StartLoc Starting location of the directive kind. 1966 /// \param EndLoc Ending Location of the directive. 1967 /// \param AssociatedStmt Statement, associated with the directive. 1968 /// 1969 static OMPScopeDirective *Create(const ASTContext &C, SourceLocation StartLoc, 1970 SourceLocation EndLoc, 1971 ArrayRef<OMPClause *> Clauses, 1972 Stmt *AssociatedStmt); 1973 1974 /// Creates an empty directive. 1975 /// 1976 /// \param C AST context. 1977 /// 1978 static OMPScopeDirective *CreateEmpty(const ASTContext &C, 1979 unsigned NumClauses, EmptyShell); 1980 classof(const Stmt * T)1981 static bool classof(const Stmt *T) { 1982 return T->getStmtClass() == OMPScopeDirectiveClass; 1983 } 1984 }; 1985 1986 /// This represents '#pragma omp single' directive. 1987 /// 1988 /// \code 1989 /// #pragma omp single private(a,b) copyprivate(c,d) 1990 /// \endcode 1991 /// In this example directive '#pragma omp single' has clauses 'private' with 1992 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'. 1993 /// 1994 class OMPSingleDirective : public OMPExecutableDirective { 1995 friend class ASTStmtReader; 1996 friend class OMPExecutableDirective; 1997 /// Build directive with the given start and end location. 1998 /// 1999 /// \param StartLoc Starting location of the directive kind. 2000 /// \param EndLoc Ending location of the directive. 2001 /// OMPSingleDirective(SourceLocation StartLoc,SourceLocation EndLoc)2002 OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2003 : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single, 2004 StartLoc, EndLoc) {} 2005 2006 /// Build an empty directive. 2007 /// OMPSingleDirective()2008 explicit OMPSingleDirective() 2009 : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single, 2010 SourceLocation(), SourceLocation()) {} 2011 2012 public: 2013 /// Creates directive with a list of \a Clauses. 2014 /// 2015 /// \param C AST context. 2016 /// \param StartLoc Starting location of the directive kind. 2017 /// \param EndLoc Ending Location of the directive. 2018 /// \param Clauses List of clauses. 2019 /// \param AssociatedStmt Statement, associated with the directive. 2020 /// 2021 static OMPSingleDirective * 2022 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2023 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 2024 2025 /// Creates an empty directive with the place for \a NumClauses 2026 /// clauses. 2027 /// 2028 /// \param C AST context. 2029 /// \param NumClauses Number of clauses. 2030 /// 2031 static OMPSingleDirective *CreateEmpty(const ASTContext &C, 2032 unsigned NumClauses, EmptyShell); 2033 classof(const Stmt * T)2034 static bool classof(const Stmt *T) { 2035 return T->getStmtClass() == OMPSingleDirectiveClass; 2036 } 2037 }; 2038 2039 /// This represents '#pragma omp master' directive. 2040 /// 2041 /// \code 2042 /// #pragma omp master 2043 /// \endcode 2044 /// 2045 class OMPMasterDirective : public OMPExecutableDirective { 2046 friend class ASTStmtReader; 2047 friend class OMPExecutableDirective; 2048 /// Build directive with the given start and end location. 2049 /// 2050 /// \param StartLoc Starting location of the directive kind. 2051 /// \param EndLoc Ending location of the directive. 2052 /// OMPMasterDirective(SourceLocation StartLoc,SourceLocation EndLoc)2053 OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2054 : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master, 2055 StartLoc, EndLoc) {} 2056 2057 /// Build an empty directive. 2058 /// OMPMasterDirective()2059 explicit OMPMasterDirective() 2060 : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master, 2061 SourceLocation(), SourceLocation()) {} 2062 2063 public: 2064 /// Creates directive. 2065 /// 2066 /// \param C AST context. 2067 /// \param StartLoc Starting location of the directive kind. 2068 /// \param EndLoc Ending Location of the directive. 2069 /// \param AssociatedStmt Statement, associated with the directive. 2070 /// 2071 static OMPMasterDirective *Create(const ASTContext &C, 2072 SourceLocation StartLoc, 2073 SourceLocation EndLoc, 2074 Stmt *AssociatedStmt); 2075 2076 /// Creates an empty directive. 2077 /// 2078 /// \param C AST context. 2079 /// 2080 static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell); 2081 classof(const Stmt * T)2082 static bool classof(const Stmt *T) { 2083 return T->getStmtClass() == OMPMasterDirectiveClass; 2084 } 2085 }; 2086 2087 /// This represents '#pragma omp critical' directive. 2088 /// 2089 /// \code 2090 /// #pragma omp critical 2091 /// \endcode 2092 /// 2093 class OMPCriticalDirective : public OMPExecutableDirective { 2094 friend class ASTStmtReader; 2095 friend class OMPExecutableDirective; 2096 /// Name of the directive. 2097 DeclarationNameInfo DirName; 2098 /// Build directive with the given start and end location. 2099 /// 2100 /// \param Name Name of the directive. 2101 /// \param StartLoc Starting location of the directive kind. 2102 /// \param EndLoc Ending location of the directive. 2103 /// OMPCriticalDirective(const DeclarationNameInfo & Name,SourceLocation StartLoc,SourceLocation EndLoc)2104 OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc, 2105 SourceLocation EndLoc) 2106 : OMPExecutableDirective(OMPCriticalDirectiveClass, 2107 llvm::omp::OMPD_critical, StartLoc, EndLoc), 2108 DirName(Name) {} 2109 2110 /// Build an empty directive. 2111 /// OMPCriticalDirective()2112 explicit OMPCriticalDirective() 2113 : OMPExecutableDirective(OMPCriticalDirectiveClass, 2114 llvm::omp::OMPD_critical, SourceLocation(), 2115 SourceLocation()) {} 2116 2117 /// Set name of the directive. 2118 /// 2119 /// \param Name Name of the directive. 2120 /// setDirectiveName(const DeclarationNameInfo & Name)2121 void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; } 2122 2123 public: 2124 /// Creates directive. 2125 /// 2126 /// \param C AST context. 2127 /// \param Name Name of the directive. 2128 /// \param StartLoc Starting location of the directive kind. 2129 /// \param EndLoc Ending Location of the directive. 2130 /// \param Clauses List of clauses. 2131 /// \param AssociatedStmt Statement, associated with the directive. 2132 /// 2133 static OMPCriticalDirective * 2134 Create(const ASTContext &C, const DeclarationNameInfo &Name, 2135 SourceLocation StartLoc, SourceLocation EndLoc, 2136 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 2137 2138 /// Creates an empty directive. 2139 /// 2140 /// \param C AST context. 2141 /// \param NumClauses Number of clauses. 2142 /// 2143 static OMPCriticalDirective *CreateEmpty(const ASTContext &C, 2144 unsigned NumClauses, EmptyShell); 2145 2146 /// Return name of the directive. 2147 /// getDirectiveName()2148 DeclarationNameInfo getDirectiveName() const { return DirName; } 2149 classof(const Stmt * T)2150 static bool classof(const Stmt *T) { 2151 return T->getStmtClass() == OMPCriticalDirectiveClass; 2152 } 2153 }; 2154 2155 /// This represents '#pragma omp parallel for' directive. 2156 /// 2157 /// \code 2158 /// #pragma omp parallel for private(a,b) reduction(+:c,d) 2159 /// \endcode 2160 /// In this example directive '#pragma omp parallel for' has clauses 'private' 2161 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and 2162 /// variables 'c' and 'd'. 2163 /// 2164 class OMPParallelForDirective : public OMPLoopDirective { 2165 friend class ASTStmtReader; 2166 friend class OMPExecutableDirective; 2167 2168 /// true if current region has inner cancel directive. 2169 bool HasCancel = false; 2170 2171 /// Build directive with the given start and end location. 2172 /// 2173 /// \param StartLoc Starting location of the directive kind. 2174 /// \param EndLoc Ending location of the directive. 2175 /// \param CollapsedNum Number of collapsed nested loops. 2176 /// OMPParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)2177 OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2178 unsigned CollapsedNum) 2179 : OMPLoopDirective(OMPParallelForDirectiveClass, 2180 llvm::omp::OMPD_parallel_for, StartLoc, EndLoc, 2181 CollapsedNum) {} 2182 2183 /// Build an empty directive. 2184 /// 2185 /// \param CollapsedNum Number of collapsed nested loops. 2186 /// OMPParallelForDirective(unsigned CollapsedNum)2187 explicit OMPParallelForDirective(unsigned CollapsedNum) 2188 : OMPLoopDirective(OMPParallelForDirectiveClass, 2189 llvm::omp::OMPD_parallel_for, SourceLocation(), 2190 SourceLocation(), CollapsedNum) {} 2191 2192 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)2193 void setTaskReductionRefExpr(Expr *E) { 2194 Data->getChildren()[numLoopChildren(getLoopsNumber(), 2195 llvm::omp::OMPD_parallel_for)] = E; 2196 } 2197 2198 /// Set cancel state. setHasCancel(bool Has)2199 void setHasCancel(bool Has) { HasCancel = Has; } 2200 2201 public: 2202 /// Creates directive with a list of \a Clauses. 2203 /// 2204 /// \param C AST context. 2205 /// \param StartLoc Starting location of the directive kind. 2206 /// \param EndLoc Ending Location of the directive. 2207 /// \param CollapsedNum Number of collapsed loops. 2208 /// \param Clauses List of clauses. 2209 /// \param AssociatedStmt Statement, associated with the directive. 2210 /// \param Exprs Helper expressions for CodeGen. 2211 /// \param TaskRedRef Task reduction special reference expression to handle 2212 /// taskgroup descriptor. 2213 /// \param HasCancel true if current directive has inner cancel directive. 2214 /// 2215 static OMPParallelForDirective * 2216 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2217 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 2218 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 2219 bool HasCancel); 2220 2221 /// Creates an empty directive with the place 2222 /// for \a NumClauses clauses. 2223 /// 2224 /// \param C AST context. 2225 /// \param CollapsedNum Number of collapsed nested loops. 2226 /// \param NumClauses Number of clauses. 2227 /// 2228 static OMPParallelForDirective *CreateEmpty(const ASTContext &C, 2229 unsigned NumClauses, 2230 unsigned CollapsedNum, 2231 EmptyShell); 2232 2233 /// Returns special task reduction reference expression. getTaskReductionRefExpr()2234 Expr *getTaskReductionRefExpr() { 2235 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 2236 getLoopsNumber(), llvm::omp::OMPD_parallel_for)]); 2237 } getTaskReductionRefExpr()2238 const Expr *getTaskReductionRefExpr() const { 2239 return const_cast<OMPParallelForDirective *>(this) 2240 ->getTaskReductionRefExpr(); 2241 } 2242 2243 /// Return true if current directive has inner cancel directive. hasCancel()2244 bool hasCancel() const { return HasCancel; } 2245 classof(const Stmt * T)2246 static bool classof(const Stmt *T) { 2247 return T->getStmtClass() == OMPParallelForDirectiveClass; 2248 } 2249 }; 2250 2251 /// This represents '#pragma omp parallel for simd' directive. 2252 /// 2253 /// \code 2254 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d) 2255 /// \endcode 2256 /// In this example directive '#pragma omp parallel for simd' has clauses 2257 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j' 2258 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and 2259 /// 'd'. 2260 /// 2261 class OMPParallelForSimdDirective : public OMPLoopDirective { 2262 friend class ASTStmtReader; 2263 friend class OMPExecutableDirective; 2264 /// Build directive with the given start and end location. 2265 /// 2266 /// \param StartLoc Starting location of the directive kind. 2267 /// \param EndLoc Ending location of the directive. 2268 /// \param CollapsedNum Number of collapsed nested loops. 2269 /// OMPParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)2270 OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2271 unsigned CollapsedNum) 2272 : OMPLoopDirective(OMPParallelForSimdDirectiveClass, 2273 llvm::omp::OMPD_parallel_for_simd, StartLoc, EndLoc, 2274 CollapsedNum) {} 2275 2276 /// Build an empty directive. 2277 /// 2278 /// \param CollapsedNum Number of collapsed nested loops. 2279 /// OMPParallelForSimdDirective(unsigned CollapsedNum)2280 explicit OMPParallelForSimdDirective(unsigned CollapsedNum) 2281 : OMPLoopDirective(OMPParallelForSimdDirectiveClass, 2282 llvm::omp::OMPD_parallel_for_simd, SourceLocation(), 2283 SourceLocation(), CollapsedNum) {} 2284 2285 public: 2286 /// Creates directive with a list of \a Clauses. 2287 /// 2288 /// \param C AST context. 2289 /// \param StartLoc Starting location of the directive kind. 2290 /// \param EndLoc Ending Location of the directive. 2291 /// \param CollapsedNum Number of collapsed loops. 2292 /// \param Clauses List of clauses. 2293 /// \param AssociatedStmt Statement, associated with the directive. 2294 /// \param Exprs Helper expressions for CodeGen. 2295 /// 2296 static OMPParallelForSimdDirective * 2297 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2298 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 2299 Stmt *AssociatedStmt, const HelperExprs &Exprs); 2300 2301 /// Creates an empty directive with the place 2302 /// for \a NumClauses clauses. 2303 /// 2304 /// \param C AST context. 2305 /// \param CollapsedNum Number of collapsed nested loops. 2306 /// \param NumClauses Number of clauses. 2307 /// 2308 static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C, 2309 unsigned NumClauses, 2310 unsigned CollapsedNum, 2311 EmptyShell); 2312 classof(const Stmt * T)2313 static bool classof(const Stmt *T) { 2314 return T->getStmtClass() == OMPParallelForSimdDirectiveClass; 2315 } 2316 }; 2317 2318 /// This represents '#pragma omp parallel master' directive. 2319 /// 2320 /// \code 2321 /// #pragma omp parallel master private(a,b) 2322 /// \endcode 2323 /// In this example directive '#pragma omp parallel master' has clauses 2324 /// 'private' with the variables 'a' and 'b' 2325 /// 2326 class OMPParallelMasterDirective : public OMPExecutableDirective { 2327 friend class ASTStmtReader; 2328 friend class OMPExecutableDirective; 2329 OMPParallelMasterDirective(SourceLocation StartLoc,SourceLocation EndLoc)2330 OMPParallelMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2331 : OMPExecutableDirective(OMPParallelMasterDirectiveClass, 2332 llvm::omp::OMPD_parallel_master, StartLoc, 2333 EndLoc) {} 2334 OMPParallelMasterDirective()2335 explicit OMPParallelMasterDirective() 2336 : OMPExecutableDirective(OMPParallelMasterDirectiveClass, 2337 llvm::omp::OMPD_parallel_master, 2338 SourceLocation(), SourceLocation()) {} 2339 2340 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)2341 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 2342 2343 public: 2344 /// Creates directive with a list of \a Clauses. 2345 /// 2346 /// \param C AST context. 2347 /// \param StartLoc Starting location of the directive kind. 2348 /// \param EndLoc Ending Location of the directive. 2349 /// \param Clauses List of clauses. 2350 /// \param AssociatedStmt Statement, associated with the directive. 2351 /// \param TaskRedRef Task reduction special reference expression to handle 2352 /// taskgroup descriptor. 2353 /// 2354 static OMPParallelMasterDirective * 2355 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2356 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef); 2357 2358 /// Creates an empty directive with the place for \a NumClauses 2359 /// clauses. 2360 /// 2361 /// \param C AST context. 2362 /// \param NumClauses Number of clauses. 2363 /// 2364 static OMPParallelMasterDirective * 2365 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 2366 2367 /// Returns special task reduction reference expression. getTaskReductionRefExpr()2368 Expr *getTaskReductionRefExpr() { 2369 return cast_or_null<Expr>(Data->getChildren()[0]); 2370 } getTaskReductionRefExpr()2371 const Expr *getTaskReductionRefExpr() const { 2372 return const_cast<OMPParallelMasterDirective *>(this) 2373 ->getTaskReductionRefExpr(); 2374 } 2375 classof(const Stmt * T)2376 static bool classof(const Stmt *T) { 2377 return T->getStmtClass() == OMPParallelMasterDirectiveClass; 2378 } 2379 }; 2380 2381 /// This represents '#pragma omp parallel masked' directive. 2382 /// 2383 /// \code 2384 /// #pragma omp parallel masked filter(tid) 2385 /// \endcode 2386 /// In this example directive '#pragma omp parallel masked' has a clause 2387 /// 'filter' with the variable tid 2388 /// 2389 class OMPParallelMaskedDirective final : public OMPExecutableDirective { 2390 friend class ASTStmtReader; 2391 friend class OMPExecutableDirective; 2392 OMPParallelMaskedDirective(SourceLocation StartLoc,SourceLocation EndLoc)2393 OMPParallelMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2394 : OMPExecutableDirective(OMPParallelMaskedDirectiveClass, 2395 llvm::omp::OMPD_parallel_masked, StartLoc, 2396 EndLoc) {} 2397 OMPParallelMaskedDirective()2398 explicit OMPParallelMaskedDirective() 2399 : OMPExecutableDirective(OMPParallelMaskedDirectiveClass, 2400 llvm::omp::OMPD_parallel_masked, 2401 SourceLocation(), SourceLocation()) {} 2402 2403 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)2404 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 2405 2406 public: 2407 /// Creates directive with a list of \a Clauses. 2408 /// 2409 /// \param C AST context. 2410 /// \param StartLoc Starting location of the directive kind. 2411 /// \param EndLoc Ending Location of the directive. 2412 /// \param Clauses List of clauses. 2413 /// \param AssociatedStmt Statement, associated with the directive. 2414 /// \param TaskRedRef Task reduction special reference expression to handle 2415 /// taskgroup descriptor. 2416 /// 2417 static OMPParallelMaskedDirective * 2418 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2419 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef); 2420 2421 /// Creates an empty directive with the place for \a NumClauses 2422 /// clauses. 2423 /// 2424 /// \param C AST context. 2425 /// \param NumClauses Number of clauses. 2426 /// 2427 static OMPParallelMaskedDirective * 2428 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 2429 2430 /// Returns special task reduction reference expression. getTaskReductionRefExpr()2431 Expr *getTaskReductionRefExpr() { 2432 return cast_or_null<Expr>(Data->getChildren()[0]); 2433 } getTaskReductionRefExpr()2434 const Expr *getTaskReductionRefExpr() const { 2435 return const_cast<OMPParallelMaskedDirective *>(this) 2436 ->getTaskReductionRefExpr(); 2437 } 2438 classof(const Stmt * T)2439 static bool classof(const Stmt *T) { 2440 return T->getStmtClass() == OMPParallelMaskedDirectiveClass; 2441 } 2442 }; 2443 2444 /// This represents '#pragma omp parallel sections' directive. 2445 /// 2446 /// \code 2447 /// #pragma omp parallel sections private(a,b) reduction(+:c,d) 2448 /// \endcode 2449 /// In this example directive '#pragma omp parallel sections' has clauses 2450 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' 2451 /// and variables 'c' and 'd'. 2452 /// 2453 class OMPParallelSectionsDirective : public OMPExecutableDirective { 2454 friend class ASTStmtReader; 2455 friend class OMPExecutableDirective; 2456 2457 /// true if current directive has inner cancel directive. 2458 bool HasCancel = false; 2459 2460 /// Build directive with the given start and end location. 2461 /// 2462 /// \param StartLoc Starting location of the directive kind. 2463 /// \param EndLoc Ending location of the directive. 2464 /// OMPParallelSectionsDirective(SourceLocation StartLoc,SourceLocation EndLoc)2465 OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2466 : OMPExecutableDirective(OMPParallelSectionsDirectiveClass, 2467 llvm::omp::OMPD_parallel_sections, StartLoc, 2468 EndLoc) {} 2469 2470 /// Build an empty directive. 2471 /// OMPParallelSectionsDirective()2472 explicit OMPParallelSectionsDirective() 2473 : OMPExecutableDirective(OMPParallelSectionsDirectiveClass, 2474 llvm::omp::OMPD_parallel_sections, 2475 SourceLocation(), SourceLocation()) {} 2476 2477 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)2478 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 2479 2480 /// Set cancel state. setHasCancel(bool Has)2481 void setHasCancel(bool Has) { HasCancel = Has; } 2482 2483 public: 2484 /// Creates directive with a list of \a Clauses. 2485 /// 2486 /// \param C AST context. 2487 /// \param StartLoc Starting location of the directive kind. 2488 /// \param EndLoc Ending Location of the directive. 2489 /// \param Clauses List of clauses. 2490 /// \param AssociatedStmt Statement, associated with the directive. 2491 /// \param TaskRedRef Task reduction special reference expression to handle 2492 /// taskgroup descriptor. 2493 /// \param HasCancel true if current directive has inner cancel directive. 2494 /// 2495 static OMPParallelSectionsDirective * 2496 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2497 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 2498 bool HasCancel); 2499 2500 /// Creates an empty directive with the place for \a NumClauses 2501 /// clauses. 2502 /// 2503 /// \param C AST context. 2504 /// \param NumClauses Number of clauses. 2505 /// 2506 static OMPParallelSectionsDirective * 2507 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 2508 2509 /// Returns special task reduction reference expression. getTaskReductionRefExpr()2510 Expr *getTaskReductionRefExpr() { 2511 return cast_or_null<Expr>(Data->getChildren()[0]); 2512 } getTaskReductionRefExpr()2513 const Expr *getTaskReductionRefExpr() const { 2514 return const_cast<OMPParallelSectionsDirective *>(this) 2515 ->getTaskReductionRefExpr(); 2516 } 2517 2518 /// Return true if current directive has inner cancel directive. hasCancel()2519 bool hasCancel() const { return HasCancel; } 2520 classof(const Stmt * T)2521 static bool classof(const Stmt *T) { 2522 return T->getStmtClass() == OMPParallelSectionsDirectiveClass; 2523 } 2524 }; 2525 2526 /// This represents '#pragma omp task' directive. 2527 /// 2528 /// \code 2529 /// #pragma omp task private(a,b) final(d) 2530 /// \endcode 2531 /// In this example directive '#pragma omp task' has clauses 'private' with the 2532 /// variables 'a' and 'b' and 'final' with condition 'd'. 2533 /// 2534 class OMPTaskDirective : public OMPExecutableDirective { 2535 friend class ASTStmtReader; 2536 friend class OMPExecutableDirective; 2537 /// true if this directive has inner cancel directive. 2538 bool HasCancel = false; 2539 2540 /// Build directive with the given start and end location. 2541 /// 2542 /// \param StartLoc Starting location of the directive kind. 2543 /// \param EndLoc Ending location of the directive. 2544 /// OMPTaskDirective(SourceLocation StartLoc,SourceLocation EndLoc)2545 OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2546 : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task, 2547 StartLoc, EndLoc) {} 2548 2549 /// Build an empty directive. 2550 /// OMPTaskDirective()2551 explicit OMPTaskDirective() 2552 : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task, 2553 SourceLocation(), SourceLocation()) {} 2554 2555 /// Set cancel state. setHasCancel(bool Has)2556 void setHasCancel(bool Has) { HasCancel = Has; } 2557 2558 public: 2559 /// Creates directive with a list of \a Clauses. 2560 /// 2561 /// \param C AST context. 2562 /// \param StartLoc Starting location of the directive kind. 2563 /// \param EndLoc Ending Location of the directive. 2564 /// \param Clauses List of clauses. 2565 /// \param AssociatedStmt Statement, associated with the directive. 2566 /// \param HasCancel true, if current directive has inner cancel directive. 2567 /// 2568 static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc, 2569 SourceLocation EndLoc, 2570 ArrayRef<OMPClause *> Clauses, 2571 Stmt *AssociatedStmt, bool HasCancel); 2572 2573 /// Creates an empty directive with the place for \a NumClauses 2574 /// clauses. 2575 /// 2576 /// \param C AST context. 2577 /// \param NumClauses Number of clauses. 2578 /// 2579 static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 2580 EmptyShell); 2581 2582 /// Return true if current directive has inner cancel directive. hasCancel()2583 bool hasCancel() const { return HasCancel; } 2584 classof(const Stmt * T)2585 static bool classof(const Stmt *T) { 2586 return T->getStmtClass() == OMPTaskDirectiveClass; 2587 } 2588 }; 2589 2590 /// This represents '#pragma omp taskyield' directive. 2591 /// 2592 /// \code 2593 /// #pragma omp taskyield 2594 /// \endcode 2595 /// 2596 class OMPTaskyieldDirective : public OMPExecutableDirective { 2597 friend class ASTStmtReader; 2598 friend class OMPExecutableDirective; 2599 /// Build directive with the given start and end location. 2600 /// 2601 /// \param StartLoc Starting location of the directive kind. 2602 /// \param EndLoc Ending location of the directive. 2603 /// OMPTaskyieldDirective(SourceLocation StartLoc,SourceLocation EndLoc)2604 OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2605 : OMPExecutableDirective(OMPTaskyieldDirectiveClass, 2606 llvm::omp::OMPD_taskyield, StartLoc, EndLoc) {} 2607 2608 /// Build an empty directive. 2609 /// OMPTaskyieldDirective()2610 explicit OMPTaskyieldDirective() 2611 : OMPExecutableDirective(OMPTaskyieldDirectiveClass, 2612 llvm::omp::OMPD_taskyield, SourceLocation(), 2613 SourceLocation()) {} 2614 2615 public: 2616 /// Creates directive. 2617 /// 2618 /// \param C AST context. 2619 /// \param StartLoc Starting location of the directive kind. 2620 /// \param EndLoc Ending Location of the directive. 2621 /// 2622 static OMPTaskyieldDirective * 2623 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); 2624 2625 /// Creates an empty directive. 2626 /// 2627 /// \param C AST context. 2628 /// 2629 static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell); 2630 classof(const Stmt * T)2631 static bool classof(const Stmt *T) { 2632 return T->getStmtClass() == OMPTaskyieldDirectiveClass; 2633 } 2634 }; 2635 2636 /// This represents '#pragma omp barrier' directive. 2637 /// 2638 /// \code 2639 /// #pragma omp barrier 2640 /// \endcode 2641 /// 2642 class OMPBarrierDirective : public OMPExecutableDirective { 2643 friend class ASTStmtReader; 2644 friend class OMPExecutableDirective; 2645 /// Build directive with the given start and end location. 2646 /// 2647 /// \param StartLoc Starting location of the directive kind. 2648 /// \param EndLoc Ending location of the directive. 2649 /// OMPBarrierDirective(SourceLocation StartLoc,SourceLocation EndLoc)2650 OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2651 : OMPExecutableDirective(OMPBarrierDirectiveClass, 2652 llvm::omp::OMPD_barrier, StartLoc, EndLoc) {} 2653 2654 /// Build an empty directive. 2655 /// OMPBarrierDirective()2656 explicit OMPBarrierDirective() 2657 : OMPExecutableDirective(OMPBarrierDirectiveClass, 2658 llvm::omp::OMPD_barrier, SourceLocation(), 2659 SourceLocation()) {} 2660 2661 public: 2662 /// Creates directive. 2663 /// 2664 /// \param C AST context. 2665 /// \param StartLoc Starting location of the directive kind. 2666 /// \param EndLoc Ending Location of the directive. 2667 /// 2668 static OMPBarrierDirective * 2669 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); 2670 2671 /// Creates an empty directive. 2672 /// 2673 /// \param C AST context. 2674 /// 2675 static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell); 2676 classof(const Stmt * T)2677 static bool classof(const Stmt *T) { 2678 return T->getStmtClass() == OMPBarrierDirectiveClass; 2679 } 2680 }; 2681 2682 /// This represents '#pragma omp taskwait' directive. 2683 /// 2684 /// \code 2685 /// #pragma omp taskwait 2686 /// \endcode 2687 /// 2688 class OMPTaskwaitDirective : public OMPExecutableDirective { 2689 friend class ASTStmtReader; 2690 friend class OMPExecutableDirective; 2691 /// Build directive with the given start and end location. 2692 /// 2693 /// \param StartLoc Starting location of the directive kind. 2694 /// \param EndLoc Ending location of the directive. 2695 /// OMPTaskwaitDirective(SourceLocation StartLoc,SourceLocation EndLoc)2696 OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2697 : OMPExecutableDirective(OMPTaskwaitDirectiveClass, 2698 llvm::omp::OMPD_taskwait, StartLoc, EndLoc) {} 2699 2700 /// Build an empty directive. 2701 /// OMPTaskwaitDirective()2702 explicit OMPTaskwaitDirective() 2703 : OMPExecutableDirective(OMPTaskwaitDirectiveClass, 2704 llvm::omp::OMPD_taskwait, SourceLocation(), 2705 SourceLocation()) {} 2706 2707 public: 2708 /// Creates directive. 2709 /// 2710 /// \param C AST context. 2711 /// \param StartLoc Starting location of the directive kind. 2712 /// \param EndLoc Ending Location of the directive. 2713 /// \param Clauses List of clauses. 2714 /// 2715 static OMPTaskwaitDirective *Create(const ASTContext &C, 2716 SourceLocation StartLoc, 2717 SourceLocation EndLoc, 2718 ArrayRef<OMPClause *> Clauses); 2719 2720 /// Creates an empty directive. 2721 /// 2722 /// \param C AST context. 2723 /// \param NumClauses Number of clauses. 2724 /// 2725 static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, 2726 unsigned NumClauses, EmptyShell); 2727 classof(const Stmt * T)2728 static bool classof(const Stmt *T) { 2729 return T->getStmtClass() == OMPTaskwaitDirectiveClass; 2730 } 2731 }; 2732 2733 /// This represents '#pragma omp taskgroup' directive. 2734 /// 2735 /// \code 2736 /// #pragma omp taskgroup 2737 /// \endcode 2738 /// 2739 class OMPTaskgroupDirective : public OMPExecutableDirective { 2740 friend class ASTStmtReader; 2741 friend class OMPExecutableDirective; 2742 /// Build directive with the given start and end location. 2743 /// 2744 /// \param StartLoc Starting location of the directive kind. 2745 /// \param EndLoc Ending location of the directive. 2746 /// OMPTaskgroupDirective(SourceLocation StartLoc,SourceLocation EndLoc)2747 OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2748 : OMPExecutableDirective(OMPTaskgroupDirectiveClass, 2749 llvm::omp::OMPD_taskgroup, StartLoc, EndLoc) {} 2750 2751 /// Build an empty directive. 2752 /// OMPTaskgroupDirective()2753 explicit OMPTaskgroupDirective() 2754 : OMPExecutableDirective(OMPTaskgroupDirectiveClass, 2755 llvm::omp::OMPD_taskgroup, SourceLocation(), 2756 SourceLocation()) {} 2757 2758 /// Sets the task_reduction return variable. setReductionRef(Expr * RR)2759 void setReductionRef(Expr *RR) { Data->getChildren()[0] = RR; } 2760 2761 public: 2762 /// Creates directive. 2763 /// 2764 /// \param C AST context. 2765 /// \param StartLoc Starting location of the directive kind. 2766 /// \param EndLoc Ending Location of the directive. 2767 /// \param Clauses List of clauses. 2768 /// \param AssociatedStmt Statement, associated with the directive. 2769 /// \param ReductionRef Reference to the task_reduction return variable. 2770 /// 2771 static OMPTaskgroupDirective * 2772 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2773 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, 2774 Expr *ReductionRef); 2775 2776 /// Creates an empty directive. 2777 /// 2778 /// \param C AST context. 2779 /// \param NumClauses Number of clauses. 2780 /// 2781 static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, 2782 unsigned NumClauses, EmptyShell); 2783 2784 2785 /// Returns reference to the task_reduction return variable. getReductionRef()2786 const Expr *getReductionRef() const { 2787 return const_cast<OMPTaskgroupDirective *>(this)->getReductionRef(); 2788 } getReductionRef()2789 Expr *getReductionRef() { return cast_or_null<Expr>(Data->getChildren()[0]); } 2790 classof(const Stmt * T)2791 static bool classof(const Stmt *T) { 2792 return T->getStmtClass() == OMPTaskgroupDirectiveClass; 2793 } 2794 }; 2795 2796 /// This represents '#pragma omp flush' directive. 2797 /// 2798 /// \code 2799 /// #pragma omp flush(a,b) 2800 /// \endcode 2801 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a' 2802 /// and 'b'. 2803 /// 'omp flush' directive does not have clauses but have an optional list of 2804 /// variables to flush. This list of variables is stored within some fake clause 2805 /// FlushClause. 2806 class OMPFlushDirective : public OMPExecutableDirective { 2807 friend class ASTStmtReader; 2808 friend class OMPExecutableDirective; 2809 /// Build directive with the given start and end location. 2810 /// 2811 /// \param StartLoc Starting location of the directive kind. 2812 /// \param EndLoc Ending location of the directive. 2813 /// OMPFlushDirective(SourceLocation StartLoc,SourceLocation EndLoc)2814 OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2815 : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush, 2816 StartLoc, EndLoc) {} 2817 2818 /// Build an empty directive. 2819 /// OMPFlushDirective()2820 explicit OMPFlushDirective() 2821 : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush, 2822 SourceLocation(), SourceLocation()) {} 2823 2824 public: 2825 /// Creates directive with a list of \a Clauses. 2826 /// 2827 /// \param C AST context. 2828 /// \param StartLoc Starting location of the directive kind. 2829 /// \param EndLoc Ending Location of the directive. 2830 /// \param Clauses List of clauses (only single OMPFlushClause clause is 2831 /// allowed). 2832 /// 2833 static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc, 2834 SourceLocation EndLoc, 2835 ArrayRef<OMPClause *> Clauses); 2836 2837 /// Creates an empty directive with the place for \a NumClauses 2838 /// clauses. 2839 /// 2840 /// \param C AST context. 2841 /// \param NumClauses Number of clauses. 2842 /// 2843 static OMPFlushDirective *CreateEmpty(const ASTContext &C, 2844 unsigned NumClauses, EmptyShell); 2845 classof(const Stmt * T)2846 static bool classof(const Stmt *T) { 2847 return T->getStmtClass() == OMPFlushDirectiveClass; 2848 } 2849 }; 2850 2851 /// This represents '#pragma omp depobj' directive. 2852 /// 2853 /// \code 2854 /// #pragma omp depobj(a) depend(in:x,y) 2855 /// \endcode 2856 /// In this example directive '#pragma omp depobj' initializes a depobj object 2857 /// 'a' with dependence type 'in' and a list with 'x' and 'y' locators. 2858 class OMPDepobjDirective final : public OMPExecutableDirective { 2859 friend class ASTStmtReader; 2860 friend class OMPExecutableDirective; 2861 2862 /// Build directive with the given start and end location. 2863 /// 2864 /// \param StartLoc Starting location of the directive kind. 2865 /// \param EndLoc Ending location of the directive. 2866 /// OMPDepobjDirective(SourceLocation StartLoc,SourceLocation EndLoc)2867 OMPDepobjDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2868 : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj, 2869 StartLoc, EndLoc) {} 2870 2871 /// Build an empty directive. 2872 /// OMPDepobjDirective()2873 explicit OMPDepobjDirective() 2874 : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj, 2875 SourceLocation(), SourceLocation()) {} 2876 2877 public: 2878 /// Creates directive with a list of \a Clauses. 2879 /// 2880 /// \param C AST context. 2881 /// \param StartLoc Starting location of the directive kind. 2882 /// \param EndLoc Ending Location of the directive. 2883 /// \param Clauses List of clauses. 2884 /// 2885 static OMPDepobjDirective *Create(const ASTContext &C, 2886 SourceLocation StartLoc, 2887 SourceLocation EndLoc, 2888 ArrayRef<OMPClause *> Clauses); 2889 2890 /// Creates an empty directive with the place for \a NumClauses 2891 /// clauses. 2892 /// 2893 /// \param C AST context. 2894 /// \param NumClauses Number of clauses. 2895 /// 2896 static OMPDepobjDirective *CreateEmpty(const ASTContext &C, 2897 unsigned NumClauses, EmptyShell); 2898 classof(const Stmt * T)2899 static bool classof(const Stmt *T) { 2900 return T->getStmtClass() == OMPDepobjDirectiveClass; 2901 } 2902 }; 2903 2904 /// This represents '#pragma omp ordered' directive. 2905 /// 2906 /// \code 2907 /// #pragma omp ordered 2908 /// \endcode 2909 /// 2910 class OMPOrderedDirective : public OMPExecutableDirective { 2911 friend class ASTStmtReader; 2912 friend class OMPExecutableDirective; 2913 /// Build directive with the given start and end location. 2914 /// 2915 /// \param StartLoc Starting location of the directive kind. 2916 /// \param EndLoc Ending location of the directive. 2917 /// OMPOrderedDirective(SourceLocation StartLoc,SourceLocation EndLoc)2918 OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2919 : OMPExecutableDirective(OMPOrderedDirectiveClass, 2920 llvm::omp::OMPD_ordered, StartLoc, EndLoc) {} 2921 2922 /// Build an empty directive. 2923 /// OMPOrderedDirective()2924 explicit OMPOrderedDirective() 2925 : OMPExecutableDirective(OMPOrderedDirectiveClass, 2926 llvm::omp::OMPD_ordered, SourceLocation(), 2927 SourceLocation()) {} 2928 2929 public: 2930 /// Creates directive. 2931 /// 2932 /// \param C AST context. 2933 /// \param StartLoc Starting location of the directive kind. 2934 /// \param EndLoc Ending Location of the directive. 2935 /// \param Clauses List of clauses. 2936 /// \param AssociatedStmt Statement, associated with the directive. 2937 /// 2938 static OMPOrderedDirective * 2939 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2940 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 2941 2942 /// Creates an empty directive. 2943 /// 2944 /// \param C AST context. 2945 /// \param NumClauses Number of clauses. 2946 /// \param IsStandalone true, if the standalone directive is created. 2947 /// 2948 static OMPOrderedDirective *CreateEmpty(const ASTContext &C, 2949 unsigned NumClauses, 2950 bool IsStandalone, EmptyShell); 2951 classof(const Stmt * T)2952 static bool classof(const Stmt *T) { 2953 return T->getStmtClass() == OMPOrderedDirectiveClass; 2954 } 2955 }; 2956 2957 /// This represents '#pragma omp atomic' directive. 2958 /// 2959 /// \code 2960 /// #pragma omp atomic capture 2961 /// \endcode 2962 /// In this example directive '#pragma omp atomic' has clause 'capture'. 2963 /// 2964 class OMPAtomicDirective : public OMPExecutableDirective { 2965 friend class ASTStmtReader; 2966 friend class OMPExecutableDirective; 2967 2968 struct FlagTy { 2969 /// Used for 'atomic update' or 'atomic capture' constructs. They may 2970 /// have atomic expressions of forms: 2971 /// \code 2972 /// x = x binop expr; 2973 /// x = expr binop x; 2974 /// \endcode 2975 /// This field is 1 for the first form of the expression and 0 for the 2976 /// second. Required for correct codegen of non-associative operations (like 2977 /// << or >>). 2978 LLVM_PREFERRED_TYPE(bool) 2979 uint8_t IsXLHSInRHSPart : 1; 2980 /// Used for 'atomic update' or 'atomic capture' constructs. They may 2981 /// have atomic expressions of forms: 2982 /// \code 2983 /// v = x; <update x>; 2984 /// <update x>; v = x; 2985 /// \endcode 2986 /// This field is 1 for the first(postfix) form of the expression and 0 2987 /// otherwise. 2988 LLVM_PREFERRED_TYPE(bool) 2989 uint8_t IsPostfixUpdate : 1; 2990 /// 1 if 'v' is updated only when the condition is false (compare capture 2991 /// only). 2992 LLVM_PREFERRED_TYPE(bool) 2993 uint8_t IsFailOnly : 1; 2994 } Flags; 2995 2996 /// Build directive with the given start and end location. 2997 /// 2998 /// \param StartLoc Starting location of the directive kind. 2999 /// \param EndLoc Ending location of the directive. 3000 /// OMPAtomicDirective(SourceLocation StartLoc,SourceLocation EndLoc)3001 OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3002 : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic, 3003 StartLoc, EndLoc) {} 3004 3005 /// Build an empty directive. 3006 /// OMPAtomicDirective()3007 explicit OMPAtomicDirective() 3008 : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic, 3009 SourceLocation(), SourceLocation()) {} 3010 3011 enum DataPositionTy : size_t { 3012 POS_X = 0, 3013 POS_V, 3014 POS_E, 3015 POS_UpdateExpr, 3016 POS_D, 3017 POS_Cond, 3018 POS_R, 3019 }; 3020 3021 /// Set 'x' part of the associated expression/statement. setX(Expr * X)3022 void setX(Expr *X) { Data->getChildren()[DataPositionTy::POS_X] = X; } 3023 /// Set helper expression of the form 3024 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 3025 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. setUpdateExpr(Expr * UE)3026 void setUpdateExpr(Expr *UE) { 3027 Data->getChildren()[DataPositionTy::POS_UpdateExpr] = UE; 3028 } 3029 /// Set 'v' part of the associated expression/statement. setV(Expr * V)3030 void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; } 3031 /// Set 'r' part of the associated expression/statement. setR(Expr * R)3032 void setR(Expr *R) { Data->getChildren()[DataPositionTy::POS_R] = R; } 3033 /// Set 'expr' part of the associated expression/statement. setExpr(Expr * E)3034 void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; } 3035 /// Set 'd' part of the associated expression/statement. setD(Expr * D)3036 void setD(Expr *D) { Data->getChildren()[DataPositionTy::POS_D] = D; } 3037 /// Set conditional expression in `atomic compare`. setCond(Expr * C)3038 void setCond(Expr *C) { Data->getChildren()[DataPositionTy::POS_Cond] = C; } 3039 3040 public: 3041 struct Expressions { 3042 /// 'x' part of the associated expression/statement. 3043 Expr *X = nullptr; 3044 /// 'v' part of the associated expression/statement. 3045 Expr *V = nullptr; 3046 // 'r' part of the associated expression/statement. 3047 Expr *R = nullptr; 3048 /// 'expr' part of the associated expression/statement. 3049 Expr *E = nullptr; 3050 /// UE Helper expression of the form: 3051 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 3052 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 3053 Expr *UE = nullptr; 3054 /// 'd' part of the associated expression/statement. 3055 Expr *D = nullptr; 3056 /// Conditional expression in `atomic compare` construct. 3057 Expr *Cond = nullptr; 3058 /// True if UE has the first form and false if the second. 3059 bool IsXLHSInRHSPart; 3060 /// True if original value of 'x' must be stored in 'v', not an updated one. 3061 bool IsPostfixUpdate; 3062 /// True if 'v' is updated only when the condition is false (compare capture 3063 /// only). 3064 bool IsFailOnly; 3065 }; 3066 3067 /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr' 3068 /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for 3069 /// detailed description of 'x', 'v' and 'expr'). 3070 /// 3071 /// \param C AST context. 3072 /// \param StartLoc Starting location of the directive kind. 3073 /// \param EndLoc Ending Location of the directive. 3074 /// \param Clauses List of clauses. 3075 /// \param AssociatedStmt Statement, associated with the directive. 3076 /// \param Exprs Associated expressions or statements. 3077 static OMPAtomicDirective *Create(const ASTContext &C, 3078 SourceLocation StartLoc, 3079 SourceLocation EndLoc, 3080 ArrayRef<OMPClause *> Clauses, 3081 Stmt *AssociatedStmt, Expressions Exprs); 3082 3083 /// Creates an empty directive with the place for \a NumClauses 3084 /// clauses. 3085 /// 3086 /// \param C AST context. 3087 /// \param NumClauses Number of clauses. 3088 /// 3089 static OMPAtomicDirective *CreateEmpty(const ASTContext &C, 3090 unsigned NumClauses, EmptyShell); 3091 3092 /// Get 'x' part of the associated expression/statement. getX()3093 Expr *getX() { 3094 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]); 3095 } getX()3096 const Expr *getX() const { 3097 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]); 3098 } 3099 /// Get helper expression of the form 3100 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 3101 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. getUpdateExpr()3102 Expr *getUpdateExpr() { 3103 return cast_or_null<Expr>( 3104 Data->getChildren()[DataPositionTy::POS_UpdateExpr]); 3105 } getUpdateExpr()3106 const Expr *getUpdateExpr() const { 3107 return cast_or_null<Expr>( 3108 Data->getChildren()[DataPositionTy::POS_UpdateExpr]); 3109 } 3110 /// Return true if helper update expression has form 3111 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form 3112 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. isXLHSInRHSPart()3113 bool isXLHSInRHSPart() const { return Flags.IsXLHSInRHSPart; } 3114 /// Return true if 'v' expression must be updated to original value of 3115 /// 'x', false if 'v' must be updated to the new value of 'x'. isPostfixUpdate()3116 bool isPostfixUpdate() const { return Flags.IsPostfixUpdate; } 3117 /// Return true if 'v' is updated only when the condition is evaluated false 3118 /// (compare capture only). isFailOnly()3119 bool isFailOnly() const { return Flags.IsFailOnly; } 3120 /// Get 'v' part of the associated expression/statement. getV()3121 Expr *getV() { 3122 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]); 3123 } getV()3124 const Expr *getV() const { 3125 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]); 3126 } 3127 /// Get 'r' part of the associated expression/statement. getR()3128 Expr *getR() { 3129 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]); 3130 } getR()3131 const Expr *getR() const { 3132 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]); 3133 } 3134 /// Get 'expr' part of the associated expression/statement. getExpr()3135 Expr *getExpr() { 3136 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]); 3137 } getExpr()3138 const Expr *getExpr() const { 3139 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]); 3140 } 3141 /// Get 'd' part of the associated expression/statement. getD()3142 Expr *getD() { 3143 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]); 3144 } getD()3145 Expr *getD() const { 3146 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]); 3147 } 3148 /// Get the 'cond' part of the source atomic expression. getCondExpr()3149 Expr *getCondExpr() { 3150 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]); 3151 } getCondExpr()3152 Expr *getCondExpr() const { 3153 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]); 3154 } 3155 classof(const Stmt * T)3156 static bool classof(const Stmt *T) { 3157 return T->getStmtClass() == OMPAtomicDirectiveClass; 3158 } 3159 }; 3160 3161 /// This represents '#pragma omp target' directive. 3162 /// 3163 /// \code 3164 /// #pragma omp target if(a) 3165 /// \endcode 3166 /// In this example directive '#pragma omp target' has clause 'if' with 3167 /// condition 'a'. 3168 /// 3169 class OMPTargetDirective : public OMPExecutableDirective { 3170 friend class ASTStmtReader; 3171 friend class OMPExecutableDirective; 3172 /// Build directive with the given start and end location. 3173 /// 3174 /// \param StartLoc Starting location of the directive kind. 3175 /// \param EndLoc Ending location of the directive. 3176 /// OMPTargetDirective(SourceLocation StartLoc,SourceLocation EndLoc)3177 OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3178 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target, 3179 StartLoc, EndLoc) {} 3180 3181 /// Build an empty directive. 3182 /// OMPTargetDirective()3183 explicit OMPTargetDirective() 3184 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target, 3185 SourceLocation(), SourceLocation()) {} 3186 3187 public: 3188 /// Creates directive with a list of \a Clauses. 3189 /// 3190 /// \param C AST context. 3191 /// \param StartLoc Starting location of the directive kind. 3192 /// \param EndLoc Ending Location of the directive. 3193 /// \param Clauses List of clauses. 3194 /// \param AssociatedStmt Statement, associated with the directive. 3195 /// 3196 static OMPTargetDirective * 3197 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3198 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 3199 3200 /// Creates an empty directive with the place for \a NumClauses 3201 /// clauses. 3202 /// 3203 /// \param C AST context. 3204 /// \param NumClauses Number of clauses. 3205 /// 3206 static OMPTargetDirective *CreateEmpty(const ASTContext &C, 3207 unsigned NumClauses, EmptyShell); 3208 classof(const Stmt * T)3209 static bool classof(const Stmt *T) { 3210 return T->getStmtClass() == OMPTargetDirectiveClass; 3211 } 3212 }; 3213 3214 /// This represents '#pragma omp target data' directive. 3215 /// 3216 /// \code 3217 /// #pragma omp target data device(0) if(a) map(b[:]) 3218 /// \endcode 3219 /// In this example directive '#pragma omp target data' has clauses 'device' 3220 /// with the value '0', 'if' with condition 'a' and 'map' with array 3221 /// section 'b[:]'. 3222 /// 3223 class OMPTargetDataDirective : public OMPExecutableDirective { 3224 friend class ASTStmtReader; 3225 friend class OMPExecutableDirective; 3226 /// Build directive with the given start and end location. 3227 /// 3228 /// \param StartLoc Starting location of the directive kind. 3229 /// \param EndLoc Ending Location of the directive. 3230 /// OMPTargetDataDirective(SourceLocation StartLoc,SourceLocation EndLoc)3231 OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3232 : OMPExecutableDirective(OMPTargetDataDirectiveClass, 3233 llvm::omp::OMPD_target_data, StartLoc, EndLoc) {} 3234 3235 /// Build an empty directive. 3236 /// OMPTargetDataDirective()3237 explicit OMPTargetDataDirective() 3238 : OMPExecutableDirective(OMPTargetDataDirectiveClass, 3239 llvm::omp::OMPD_target_data, SourceLocation(), 3240 SourceLocation()) {} 3241 3242 public: 3243 /// Creates directive with a list of \a Clauses. 3244 /// 3245 /// \param C AST context. 3246 /// \param StartLoc Starting location of the directive kind. 3247 /// \param EndLoc Ending Location of the directive. 3248 /// \param Clauses List of clauses. 3249 /// \param AssociatedStmt Statement, associated with the directive. 3250 /// 3251 static OMPTargetDataDirective * 3252 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3253 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 3254 3255 /// Creates an empty directive with the place for \a N clauses. 3256 /// 3257 /// \param C AST context. 3258 /// \param N The number of clauses. 3259 /// 3260 static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N, 3261 EmptyShell); 3262 classof(const Stmt * T)3263 static bool classof(const Stmt *T) { 3264 return T->getStmtClass() == OMPTargetDataDirectiveClass; 3265 } 3266 }; 3267 3268 /// This represents '#pragma omp target enter data' directive. 3269 /// 3270 /// \code 3271 /// #pragma omp target enter data device(0) if(a) map(b[:]) 3272 /// \endcode 3273 /// In this example directive '#pragma omp target enter data' has clauses 3274 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array 3275 /// section 'b[:]'. 3276 /// 3277 class OMPTargetEnterDataDirective : public OMPExecutableDirective { 3278 friend class ASTStmtReader; 3279 friend class OMPExecutableDirective; 3280 /// Build directive with the given start and end location. 3281 /// 3282 /// \param StartLoc Starting location of the directive kind. 3283 /// \param EndLoc Ending Location of the directive. 3284 /// OMPTargetEnterDataDirective(SourceLocation StartLoc,SourceLocation EndLoc)3285 OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3286 : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass, 3287 llvm::omp::OMPD_target_enter_data, StartLoc, 3288 EndLoc) {} 3289 3290 /// Build an empty directive. 3291 /// OMPTargetEnterDataDirective()3292 explicit OMPTargetEnterDataDirective() 3293 : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass, 3294 llvm::omp::OMPD_target_enter_data, 3295 SourceLocation(), SourceLocation()) {} 3296 3297 public: 3298 /// Creates directive with a list of \a Clauses. 3299 /// 3300 /// \param C AST context. 3301 /// \param StartLoc Starting location of the directive kind. 3302 /// \param EndLoc Ending Location of the directive. 3303 /// \param Clauses List of clauses. 3304 /// \param AssociatedStmt Statement, associated with the directive. 3305 /// 3306 static OMPTargetEnterDataDirective * 3307 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3308 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 3309 3310 /// Creates an empty directive with the place for \a N clauses. 3311 /// 3312 /// \param C AST context. 3313 /// \param N The number of clauses. 3314 /// 3315 static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C, 3316 unsigned N, EmptyShell); 3317 classof(const Stmt * T)3318 static bool classof(const Stmt *T) { 3319 return T->getStmtClass() == OMPTargetEnterDataDirectiveClass; 3320 } 3321 }; 3322 3323 /// This represents '#pragma omp target exit data' directive. 3324 /// 3325 /// \code 3326 /// #pragma omp target exit data device(0) if(a) map(b[:]) 3327 /// \endcode 3328 /// In this example directive '#pragma omp target exit data' has clauses 3329 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array 3330 /// section 'b[:]'. 3331 /// 3332 class OMPTargetExitDataDirective : public OMPExecutableDirective { 3333 friend class ASTStmtReader; 3334 friend class OMPExecutableDirective; 3335 /// Build directive with the given start and end location. 3336 /// 3337 /// \param StartLoc Starting location of the directive kind. 3338 /// \param EndLoc Ending Location of the directive. 3339 /// OMPTargetExitDataDirective(SourceLocation StartLoc,SourceLocation EndLoc)3340 OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3341 : OMPExecutableDirective(OMPTargetExitDataDirectiveClass, 3342 llvm::omp::OMPD_target_exit_data, StartLoc, 3343 EndLoc) {} 3344 3345 /// Build an empty directive. 3346 /// OMPTargetExitDataDirective()3347 explicit OMPTargetExitDataDirective() 3348 : OMPExecutableDirective(OMPTargetExitDataDirectiveClass, 3349 llvm::omp::OMPD_target_exit_data, 3350 SourceLocation(), SourceLocation()) {} 3351 3352 public: 3353 /// Creates directive with a list of \a Clauses. 3354 /// 3355 /// \param C AST context. 3356 /// \param StartLoc Starting location of the directive kind. 3357 /// \param EndLoc Ending Location of the directive. 3358 /// \param Clauses List of clauses. 3359 /// \param AssociatedStmt Statement, associated with the directive. 3360 /// 3361 static OMPTargetExitDataDirective * 3362 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3363 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 3364 3365 /// Creates an empty directive with the place for \a N clauses. 3366 /// 3367 /// \param C AST context. 3368 /// \param N The number of clauses. 3369 /// 3370 static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C, 3371 unsigned N, EmptyShell); 3372 classof(const Stmt * T)3373 static bool classof(const Stmt *T) { 3374 return T->getStmtClass() == OMPTargetExitDataDirectiveClass; 3375 } 3376 }; 3377 3378 /// This represents '#pragma omp target parallel' directive. 3379 /// 3380 /// \code 3381 /// #pragma omp target parallel if(a) 3382 /// \endcode 3383 /// In this example directive '#pragma omp target parallel' has clause 'if' with 3384 /// condition 'a'. 3385 /// 3386 class OMPTargetParallelDirective : public OMPExecutableDirective { 3387 friend class ASTStmtReader; 3388 friend class OMPExecutableDirective; 3389 /// true if the construct has inner cancel directive. 3390 bool HasCancel = false; 3391 3392 /// Build directive with the given start and end location. 3393 /// 3394 /// \param StartLoc Starting location of the directive kind. 3395 /// \param EndLoc Ending location of the directive. 3396 /// OMPTargetParallelDirective(SourceLocation StartLoc,SourceLocation EndLoc)3397 OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3398 : OMPExecutableDirective(OMPTargetParallelDirectiveClass, 3399 llvm::omp::OMPD_target_parallel, StartLoc, 3400 EndLoc) {} 3401 3402 /// Build an empty directive. 3403 /// OMPTargetParallelDirective()3404 explicit OMPTargetParallelDirective() 3405 : OMPExecutableDirective(OMPTargetParallelDirectiveClass, 3406 llvm::omp::OMPD_target_parallel, 3407 SourceLocation(), SourceLocation()) {} 3408 3409 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)3410 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 3411 /// Set cancel state. setHasCancel(bool Has)3412 void setHasCancel(bool Has) { HasCancel = Has; } 3413 3414 public: 3415 /// Creates directive with a list of \a Clauses. 3416 /// 3417 /// \param C AST context. 3418 /// \param StartLoc Starting location of the directive kind. 3419 /// \param EndLoc Ending Location of the directive. 3420 /// \param Clauses List of clauses. 3421 /// \param AssociatedStmt Statement, associated with the directive. 3422 /// \param TaskRedRef Task reduction special reference expression to handle 3423 /// taskgroup descriptor. 3424 /// \param HasCancel true if this directive has inner cancel directive. 3425 /// 3426 static OMPTargetParallelDirective * 3427 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3428 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 3429 bool HasCancel); 3430 3431 /// Creates an empty directive with the place for \a NumClauses 3432 /// clauses. 3433 /// 3434 /// \param C AST context. 3435 /// \param NumClauses Number of clauses. 3436 /// 3437 static OMPTargetParallelDirective * 3438 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 3439 3440 /// Returns special task reduction reference expression. getTaskReductionRefExpr()3441 Expr *getTaskReductionRefExpr() { 3442 return cast_or_null<Expr>(Data->getChildren()[0]); 3443 } getTaskReductionRefExpr()3444 const Expr *getTaskReductionRefExpr() const { 3445 return const_cast<OMPTargetParallelDirective *>(this) 3446 ->getTaskReductionRefExpr(); 3447 } 3448 3449 /// Return true if current directive has inner cancel directive. hasCancel()3450 bool hasCancel() const { return HasCancel; } 3451 classof(const Stmt * T)3452 static bool classof(const Stmt *T) { 3453 return T->getStmtClass() == OMPTargetParallelDirectiveClass; 3454 } 3455 }; 3456 3457 /// This represents '#pragma omp target parallel for' directive. 3458 /// 3459 /// \code 3460 /// #pragma omp target parallel for private(a,b) reduction(+:c,d) 3461 /// \endcode 3462 /// In this example directive '#pragma omp target parallel for' has clauses 3463 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' 3464 /// and variables 'c' and 'd'. 3465 /// 3466 class OMPTargetParallelForDirective : public OMPLoopDirective { 3467 friend class ASTStmtReader; 3468 friend class OMPExecutableDirective; 3469 3470 /// true if current region has inner cancel directive. 3471 bool HasCancel = false; 3472 3473 /// Build directive with the given start and end location. 3474 /// 3475 /// \param StartLoc Starting location of the directive kind. 3476 /// \param EndLoc Ending location of the directive. 3477 /// \param CollapsedNum Number of collapsed nested loops. 3478 /// OMPTargetParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)3479 OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3480 unsigned CollapsedNum) 3481 : OMPLoopDirective(OMPTargetParallelForDirectiveClass, 3482 llvm::omp::OMPD_target_parallel_for, StartLoc, EndLoc, 3483 CollapsedNum) {} 3484 3485 /// Build an empty directive. 3486 /// 3487 /// \param CollapsedNum Number of collapsed nested loops. 3488 /// OMPTargetParallelForDirective(unsigned CollapsedNum)3489 explicit OMPTargetParallelForDirective(unsigned CollapsedNum) 3490 : OMPLoopDirective(OMPTargetParallelForDirectiveClass, 3491 llvm::omp::OMPD_target_parallel_for, SourceLocation(), 3492 SourceLocation(), CollapsedNum) {} 3493 3494 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)3495 void setTaskReductionRefExpr(Expr *E) { 3496 Data->getChildren()[numLoopChildren( 3497 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)] = E; 3498 } 3499 3500 /// Set cancel state. setHasCancel(bool Has)3501 void setHasCancel(bool Has) { HasCancel = Has; } 3502 3503 public: 3504 /// Creates directive with a list of \a Clauses. 3505 /// 3506 /// \param C AST context. 3507 /// \param StartLoc Starting location of the directive kind. 3508 /// \param EndLoc Ending Location of the directive. 3509 /// \param CollapsedNum Number of collapsed loops. 3510 /// \param Clauses List of clauses. 3511 /// \param AssociatedStmt Statement, associated with the directive. 3512 /// \param Exprs Helper expressions for CodeGen. 3513 /// \param TaskRedRef Task reduction special reference expression to handle 3514 /// taskgroup descriptor. 3515 /// \param HasCancel true if current directive has inner cancel directive. 3516 /// 3517 static OMPTargetParallelForDirective * 3518 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3519 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3520 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 3521 bool HasCancel); 3522 3523 /// Creates an empty directive with the place 3524 /// for \a NumClauses clauses. 3525 /// 3526 /// \param C AST context. 3527 /// \param CollapsedNum Number of collapsed nested loops. 3528 /// \param NumClauses Number of clauses. 3529 /// 3530 static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C, 3531 unsigned NumClauses, 3532 unsigned CollapsedNum, 3533 EmptyShell); 3534 3535 /// Returns special task reduction reference expression. getTaskReductionRefExpr()3536 Expr *getTaskReductionRefExpr() { 3537 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 3538 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)]); 3539 } getTaskReductionRefExpr()3540 const Expr *getTaskReductionRefExpr() const { 3541 return const_cast<OMPTargetParallelForDirective *>(this) 3542 ->getTaskReductionRefExpr(); 3543 } 3544 3545 /// Return true if current directive has inner cancel directive. hasCancel()3546 bool hasCancel() const { return HasCancel; } 3547 classof(const Stmt * T)3548 static bool classof(const Stmt *T) { 3549 return T->getStmtClass() == OMPTargetParallelForDirectiveClass; 3550 } 3551 }; 3552 3553 /// This represents '#pragma omp teams' directive. 3554 /// 3555 /// \code 3556 /// #pragma omp teams if(a) 3557 /// \endcode 3558 /// In this example directive '#pragma omp teams' has clause 'if' with 3559 /// condition 'a'. 3560 /// 3561 class OMPTeamsDirective : public OMPExecutableDirective { 3562 friend class ASTStmtReader; 3563 friend class OMPExecutableDirective; 3564 /// Build directive with the given start and end location. 3565 /// 3566 /// \param StartLoc Starting location of the directive kind. 3567 /// \param EndLoc Ending location of the directive. 3568 /// OMPTeamsDirective(SourceLocation StartLoc,SourceLocation EndLoc)3569 OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3570 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams, 3571 StartLoc, EndLoc) {} 3572 3573 /// Build an empty directive. 3574 /// OMPTeamsDirective()3575 explicit OMPTeamsDirective() 3576 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams, 3577 SourceLocation(), SourceLocation()) {} 3578 3579 public: 3580 /// Creates directive with a list of \a Clauses. 3581 /// 3582 /// \param C AST context. 3583 /// \param StartLoc Starting location of the directive kind. 3584 /// \param EndLoc Ending Location of the directive. 3585 /// \param Clauses List of clauses. 3586 /// \param AssociatedStmt Statement, associated with the directive. 3587 /// 3588 static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc, 3589 SourceLocation EndLoc, 3590 ArrayRef<OMPClause *> Clauses, 3591 Stmt *AssociatedStmt); 3592 3593 /// Creates an empty directive with the place for \a NumClauses 3594 /// clauses. 3595 /// 3596 /// \param C AST context. 3597 /// \param NumClauses Number of clauses. 3598 /// 3599 static OMPTeamsDirective *CreateEmpty(const ASTContext &C, 3600 unsigned NumClauses, EmptyShell); 3601 classof(const Stmt * T)3602 static bool classof(const Stmt *T) { 3603 return T->getStmtClass() == OMPTeamsDirectiveClass; 3604 } 3605 }; 3606 3607 /// This represents '#pragma omp cancellation point' directive. 3608 /// 3609 /// \code 3610 /// #pragma omp cancellation point for 3611 /// \endcode 3612 /// 3613 /// In this example a cancellation point is created for innermost 'for' region. 3614 class OMPCancellationPointDirective : public OMPExecutableDirective { 3615 friend class ASTStmtReader; 3616 friend class OMPExecutableDirective; 3617 OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown; 3618 /// Build directive with the given start and end location. 3619 /// 3620 /// \param StartLoc Starting location of the directive kind. 3621 /// \param EndLoc Ending location of the directive. 3622 /// statements and child expressions. 3623 /// OMPCancellationPointDirective(SourceLocation StartLoc,SourceLocation EndLoc)3624 OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3625 : OMPExecutableDirective(OMPCancellationPointDirectiveClass, 3626 llvm::omp::OMPD_cancellation_point, StartLoc, 3627 EndLoc) {} 3628 3629 /// Build an empty directive. OMPCancellationPointDirective()3630 explicit OMPCancellationPointDirective() 3631 : OMPExecutableDirective(OMPCancellationPointDirectiveClass, 3632 llvm::omp::OMPD_cancellation_point, 3633 SourceLocation(), SourceLocation()) {} 3634 3635 /// Set cancel region for current cancellation point. 3636 /// \param CR Cancellation region. setCancelRegion(OpenMPDirectiveKind CR)3637 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } 3638 3639 public: 3640 /// Creates directive. 3641 /// 3642 /// \param C AST context. 3643 /// \param StartLoc Starting location of the directive kind. 3644 /// \param EndLoc Ending Location of the directive. 3645 /// 3646 static OMPCancellationPointDirective * 3647 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3648 OpenMPDirectiveKind CancelRegion); 3649 3650 /// Creates an empty directive. 3651 /// 3652 /// \param C AST context. 3653 /// 3654 static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C, 3655 EmptyShell); 3656 3657 /// Get cancellation region for the current cancellation point. getCancelRegion()3658 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } 3659 classof(const Stmt * T)3660 static bool classof(const Stmt *T) { 3661 return T->getStmtClass() == OMPCancellationPointDirectiveClass; 3662 } 3663 }; 3664 3665 /// This represents '#pragma omp cancel' directive. 3666 /// 3667 /// \code 3668 /// #pragma omp cancel for 3669 /// \endcode 3670 /// 3671 /// In this example a cancel is created for innermost 'for' region. 3672 class OMPCancelDirective : public OMPExecutableDirective { 3673 friend class ASTStmtReader; 3674 friend class OMPExecutableDirective; 3675 OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown; 3676 /// Build directive with the given start and end location. 3677 /// 3678 /// \param StartLoc Starting location of the directive kind. 3679 /// \param EndLoc Ending location of the directive. 3680 /// OMPCancelDirective(SourceLocation StartLoc,SourceLocation EndLoc)3681 OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3682 : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel, 3683 StartLoc, EndLoc) {} 3684 3685 /// Build an empty directive. 3686 /// OMPCancelDirective()3687 explicit OMPCancelDirective() 3688 : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel, 3689 SourceLocation(), SourceLocation()) {} 3690 3691 /// Set cancel region for current cancellation point. 3692 /// \param CR Cancellation region. setCancelRegion(OpenMPDirectiveKind CR)3693 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } 3694 3695 public: 3696 /// Creates directive. 3697 /// 3698 /// \param C AST context. 3699 /// \param StartLoc Starting location of the directive kind. 3700 /// \param EndLoc Ending Location of the directive. 3701 /// \param Clauses List of clauses. 3702 /// 3703 static OMPCancelDirective * 3704 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3705 ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion); 3706 3707 /// Creates an empty directive. 3708 /// 3709 /// \param C AST context. 3710 /// \param NumClauses Number of clauses. 3711 /// 3712 static OMPCancelDirective *CreateEmpty(const ASTContext &C, 3713 unsigned NumClauses, EmptyShell); 3714 3715 /// Get cancellation region for the current cancellation point. getCancelRegion()3716 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } 3717 classof(const Stmt * T)3718 static bool classof(const Stmt *T) { 3719 return T->getStmtClass() == OMPCancelDirectiveClass; 3720 } 3721 }; 3722 3723 /// This represents '#pragma omp taskloop' directive. 3724 /// 3725 /// \code 3726 /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num) 3727 /// \endcode 3728 /// In this example directive '#pragma omp taskloop' has clauses 'private' 3729 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and 3730 /// 'num_tasks' with expression 'num'. 3731 /// 3732 class OMPTaskLoopDirective : public OMPLoopDirective { 3733 friend class ASTStmtReader; 3734 friend class OMPExecutableDirective; 3735 /// true if the construct has inner cancel directive. 3736 bool HasCancel = false; 3737 3738 /// Build directive with the given start and end location. 3739 /// 3740 /// \param StartLoc Starting location of the directive kind. 3741 /// \param EndLoc Ending location of the directive. 3742 /// \param CollapsedNum Number of collapsed nested loops. 3743 /// OMPTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)3744 OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3745 unsigned CollapsedNum) 3746 : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop, 3747 StartLoc, EndLoc, CollapsedNum) {} 3748 3749 /// Build an empty directive. 3750 /// 3751 /// \param CollapsedNum Number of collapsed nested loops. 3752 /// OMPTaskLoopDirective(unsigned CollapsedNum)3753 explicit OMPTaskLoopDirective(unsigned CollapsedNum) 3754 : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop, 3755 SourceLocation(), SourceLocation(), CollapsedNum) {} 3756 3757 /// Set cancel state. setHasCancel(bool Has)3758 void setHasCancel(bool Has) { HasCancel = Has; } 3759 3760 public: 3761 /// Creates directive with a list of \a Clauses. 3762 /// 3763 /// \param C AST context. 3764 /// \param StartLoc Starting location of the directive kind. 3765 /// \param EndLoc Ending Location of the directive. 3766 /// \param CollapsedNum Number of collapsed loops. 3767 /// \param Clauses List of clauses. 3768 /// \param AssociatedStmt Statement, associated with the directive. 3769 /// \param Exprs Helper expressions for CodeGen. 3770 /// \param HasCancel true if this directive has inner cancel directive. 3771 /// 3772 static OMPTaskLoopDirective * 3773 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3774 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3775 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 3776 3777 /// Creates an empty directive with the place 3778 /// for \a NumClauses clauses. 3779 /// 3780 /// \param C AST context. 3781 /// \param CollapsedNum Number of collapsed nested loops. 3782 /// \param NumClauses Number of clauses. 3783 /// 3784 static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C, 3785 unsigned NumClauses, 3786 unsigned CollapsedNum, EmptyShell); 3787 3788 /// Return true if current directive has inner cancel directive. hasCancel()3789 bool hasCancel() const { return HasCancel; } 3790 classof(const Stmt * T)3791 static bool classof(const Stmt *T) { 3792 return T->getStmtClass() == OMPTaskLoopDirectiveClass; 3793 } 3794 }; 3795 3796 /// This represents '#pragma omp taskloop simd' directive. 3797 /// 3798 /// \code 3799 /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num) 3800 /// \endcode 3801 /// In this example directive '#pragma omp taskloop simd' has clauses 'private' 3802 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and 3803 /// 'num_tasks' with expression 'num'. 3804 /// 3805 class OMPTaskLoopSimdDirective : public OMPLoopDirective { 3806 friend class ASTStmtReader; 3807 friend class OMPExecutableDirective; 3808 /// Build directive with the given start and end location. 3809 /// 3810 /// \param StartLoc Starting location of the directive kind. 3811 /// \param EndLoc Ending location of the directive. 3812 /// \param CollapsedNum Number of collapsed nested loops. 3813 /// OMPTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)3814 OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3815 unsigned CollapsedNum) 3816 : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass, 3817 llvm::omp::OMPD_taskloop_simd, StartLoc, EndLoc, 3818 CollapsedNum) {} 3819 3820 /// Build an empty directive. 3821 /// 3822 /// \param CollapsedNum Number of collapsed nested loops. 3823 /// OMPTaskLoopSimdDirective(unsigned CollapsedNum)3824 explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum) 3825 : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass, 3826 llvm::omp::OMPD_taskloop_simd, SourceLocation(), 3827 SourceLocation(), CollapsedNum) {} 3828 3829 public: 3830 /// Creates directive with a list of \a Clauses. 3831 /// 3832 /// \param C AST context. 3833 /// \param StartLoc Starting location of the directive kind. 3834 /// \param EndLoc Ending Location of the directive. 3835 /// \param CollapsedNum Number of collapsed loops. 3836 /// \param Clauses List of clauses. 3837 /// \param AssociatedStmt Statement, associated with the directive. 3838 /// \param Exprs Helper expressions for CodeGen. 3839 /// 3840 static OMPTaskLoopSimdDirective * 3841 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3842 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3843 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3844 3845 /// Creates an empty directive with the place 3846 /// for \a NumClauses clauses. 3847 /// 3848 /// \param C AST context. 3849 /// \param CollapsedNum Number of collapsed nested loops. 3850 /// \param NumClauses Number of clauses. 3851 /// 3852 static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, 3853 unsigned NumClauses, 3854 unsigned CollapsedNum, 3855 EmptyShell); 3856 classof(const Stmt * T)3857 static bool classof(const Stmt *T) { 3858 return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass; 3859 } 3860 }; 3861 3862 /// This represents '#pragma omp master taskloop' directive. 3863 /// 3864 /// \code 3865 /// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num) 3866 /// \endcode 3867 /// In this example directive '#pragma omp master taskloop' has clauses 3868 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 3869 /// and 'num_tasks' with expression 'num'. 3870 /// 3871 class OMPMasterTaskLoopDirective : public OMPLoopDirective { 3872 friend class ASTStmtReader; 3873 friend class OMPExecutableDirective; 3874 /// true if the construct has inner cancel directive. 3875 bool HasCancel = false; 3876 3877 /// Build directive with the given start and end location. 3878 /// 3879 /// \param StartLoc Starting location of the directive kind. 3880 /// \param EndLoc Ending location of the directive. 3881 /// \param CollapsedNum Number of collapsed nested loops. 3882 /// OMPMasterTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)3883 OMPMasterTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3884 unsigned CollapsedNum) 3885 : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass, 3886 llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc, 3887 CollapsedNum) {} 3888 3889 /// Build an empty directive. 3890 /// 3891 /// \param CollapsedNum Number of collapsed nested loops. 3892 /// OMPMasterTaskLoopDirective(unsigned CollapsedNum)3893 explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum) 3894 : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass, 3895 llvm::omp::OMPD_master_taskloop, SourceLocation(), 3896 SourceLocation(), CollapsedNum) {} 3897 3898 /// Set cancel state. setHasCancel(bool Has)3899 void setHasCancel(bool Has) { HasCancel = Has; } 3900 3901 public: 3902 /// Creates directive with a list of \a Clauses. 3903 /// 3904 /// \param C AST context. 3905 /// \param StartLoc Starting location of the directive kind. 3906 /// \param EndLoc Ending Location of the directive. 3907 /// \param CollapsedNum Number of collapsed loops. 3908 /// \param Clauses List of clauses. 3909 /// \param AssociatedStmt Statement, associated with the directive. 3910 /// \param Exprs Helper expressions for CodeGen. 3911 /// \param HasCancel true if this directive has inner cancel directive. 3912 /// 3913 static OMPMasterTaskLoopDirective * 3914 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3915 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3916 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 3917 3918 /// Creates an empty directive with the place 3919 /// for \a NumClauses clauses. 3920 /// 3921 /// \param C AST context. 3922 /// \param CollapsedNum Number of collapsed nested loops. 3923 /// \param NumClauses Number of clauses. 3924 /// 3925 static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C, 3926 unsigned NumClauses, 3927 unsigned CollapsedNum, 3928 EmptyShell); 3929 3930 /// Return true if current directive has inner cancel directive. hasCancel()3931 bool hasCancel() const { return HasCancel; } 3932 classof(const Stmt * T)3933 static bool classof(const Stmt *T) { 3934 return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass; 3935 } 3936 }; 3937 3938 /// This represents '#pragma omp masked taskloop' directive. 3939 /// 3940 /// \code 3941 /// #pragma omp masked taskloop private(a,b) grainsize(val) num_tasks(num) 3942 /// \endcode 3943 /// In this example directive '#pragma omp masked taskloop' has clauses 3944 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 3945 /// and 'num_tasks' with expression 'num'. 3946 /// 3947 class OMPMaskedTaskLoopDirective final : public OMPLoopDirective { 3948 friend class ASTStmtReader; 3949 friend class OMPExecutableDirective; 3950 /// true if the construct has inner cancel directive. 3951 bool HasCancel = false; 3952 3953 /// Build directive with the given start and end location. 3954 /// 3955 /// \param StartLoc Starting location of the directive kind. 3956 /// \param EndLoc Ending location of the directive. 3957 /// \param CollapsedNum Number of collapsed nested loops. 3958 /// OMPMaskedTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)3959 OMPMaskedTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3960 unsigned CollapsedNum) 3961 : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass, 3962 llvm::omp::OMPD_masked_taskloop, StartLoc, EndLoc, 3963 CollapsedNum) {} 3964 3965 /// Build an empty directive. 3966 /// 3967 /// \param CollapsedNum Number of collapsed nested loops. 3968 /// OMPMaskedTaskLoopDirective(unsigned CollapsedNum)3969 explicit OMPMaskedTaskLoopDirective(unsigned CollapsedNum) 3970 : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass, 3971 llvm::omp::OMPD_masked_taskloop, SourceLocation(), 3972 SourceLocation(), CollapsedNum) {} 3973 3974 /// Set cancel state. setHasCancel(bool Has)3975 void setHasCancel(bool Has) { HasCancel = Has; } 3976 3977 public: 3978 /// Creates directive with a list of \a Clauses. 3979 /// 3980 /// \param C AST context. 3981 /// \param StartLoc Starting location of the directive kind. 3982 /// \param EndLoc Ending Location of the directive. 3983 /// \param CollapsedNum Number of collapsed loops. 3984 /// \param Clauses List of clauses. 3985 /// \param AssociatedStmt Statement, associated with the directive. 3986 /// \param Exprs Helper expressions for CodeGen. 3987 /// \param HasCancel true if this directive has inner cancel directive. 3988 /// 3989 static OMPMaskedTaskLoopDirective * 3990 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3991 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3992 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 3993 3994 /// Creates an empty directive with the place 3995 /// for \a NumClauses clauses. 3996 /// 3997 /// \param C AST context. 3998 /// \param CollapsedNum Number of collapsed nested loops. 3999 /// \param NumClauses Number of clauses. 4000 /// 4001 static OMPMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C, 4002 unsigned NumClauses, 4003 unsigned CollapsedNum, 4004 EmptyShell); 4005 4006 /// Return true if current directive has inner cancel directive. hasCancel()4007 bool hasCancel() const { return HasCancel; } 4008 classof(const Stmt * T)4009 static bool classof(const Stmt *T) { 4010 return T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass; 4011 } 4012 }; 4013 4014 /// This represents '#pragma omp master taskloop simd' directive. 4015 /// 4016 /// \code 4017 /// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num) 4018 /// \endcode 4019 /// In this example directive '#pragma omp master taskloop simd' has clauses 4020 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 4021 /// and 'num_tasks' with expression 'num'. 4022 /// 4023 class OMPMasterTaskLoopSimdDirective : public OMPLoopDirective { 4024 friend class ASTStmtReader; 4025 friend class OMPExecutableDirective; 4026 /// Build directive with the given start and end location. 4027 /// 4028 /// \param StartLoc Starting location of the directive kind. 4029 /// \param EndLoc Ending location of the directive. 4030 /// \param CollapsedNum Number of collapsed nested loops. 4031 /// OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4032 OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4033 unsigned CollapsedNum) 4034 : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass, 4035 llvm::omp::OMPD_master_taskloop_simd, StartLoc, EndLoc, 4036 CollapsedNum) {} 4037 4038 /// Build an empty directive. 4039 /// 4040 /// \param CollapsedNum Number of collapsed nested loops. 4041 /// OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum)4042 explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum) 4043 : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass, 4044 llvm::omp::OMPD_master_taskloop_simd, SourceLocation(), 4045 SourceLocation(), CollapsedNum) {} 4046 4047 public: 4048 /// Creates directive with a list of \p Clauses. 4049 /// 4050 /// \param C AST context. 4051 /// \param StartLoc Starting location of the directive kind. 4052 /// \param EndLoc Ending Location of the directive. 4053 /// \param CollapsedNum Number of collapsed loops. 4054 /// \param Clauses List of clauses. 4055 /// \param AssociatedStmt Statement, associated with the directive. 4056 /// \param Exprs Helper expressions for CodeGen. 4057 /// 4058 static OMPMasterTaskLoopSimdDirective * 4059 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4060 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4061 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4062 4063 /// Creates an empty directive with the place for \p NumClauses clauses. 4064 /// 4065 /// \param C AST context. 4066 /// \param CollapsedNum Number of collapsed nested loops. 4067 /// \param NumClauses Number of clauses. 4068 /// 4069 static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, 4070 unsigned NumClauses, 4071 unsigned CollapsedNum, 4072 EmptyShell); 4073 classof(const Stmt * T)4074 static bool classof(const Stmt *T) { 4075 return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass; 4076 } 4077 }; 4078 4079 /// This represents '#pragma omp masked taskloop simd' directive. 4080 /// 4081 /// \code 4082 /// #pragma omp masked taskloop simd private(a,b) grainsize(val) num_tasks(num) 4083 /// \endcode 4084 /// In this example directive '#pragma omp masked taskloop simd' has clauses 4085 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 4086 /// and 'num_tasks' with expression 'num'. 4087 /// 4088 class OMPMaskedTaskLoopSimdDirective final : public OMPLoopDirective { 4089 friend class ASTStmtReader; 4090 friend class OMPExecutableDirective; 4091 /// Build directive with the given start and end location. 4092 /// 4093 /// \param StartLoc Starting location of the directive kind. 4094 /// \param EndLoc Ending location of the directive. 4095 /// \param CollapsedNum Number of collapsed nested loops. 4096 /// OMPMaskedTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4097 OMPMaskedTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4098 unsigned CollapsedNum) 4099 : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass, 4100 llvm::omp::OMPD_masked_taskloop_simd, StartLoc, EndLoc, 4101 CollapsedNum) {} 4102 4103 /// Build an empty directive. 4104 /// 4105 /// \param CollapsedNum Number of collapsed nested loops. 4106 /// OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum)4107 explicit OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum) 4108 : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass, 4109 llvm::omp::OMPD_masked_taskloop_simd, SourceLocation(), 4110 SourceLocation(), CollapsedNum) {} 4111 4112 public: 4113 /// Creates directive with a list of \p Clauses. 4114 /// 4115 /// \param C AST context. 4116 /// \param StartLoc Starting location of the directive kind. 4117 /// \param EndLoc Ending Location of the directive. 4118 /// \param CollapsedNum Number of collapsed loops. 4119 /// \param Clauses List of clauses. 4120 /// \param AssociatedStmt Statement, associated with the directive. 4121 /// \param Exprs Helper expressions for CodeGen. 4122 /// 4123 static OMPMaskedTaskLoopSimdDirective * 4124 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4125 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4126 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4127 4128 /// Creates an empty directive with the place for \p NumClauses clauses. 4129 /// 4130 /// \param C AST context. 4131 /// \param CollapsedNum Number of collapsed nested loops. 4132 /// \param NumClauses Number of clauses. 4133 /// 4134 static OMPMaskedTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, 4135 unsigned NumClauses, 4136 unsigned CollapsedNum, 4137 EmptyShell); 4138 classof(const Stmt * T)4139 static bool classof(const Stmt *T) { 4140 return T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass; 4141 } 4142 }; 4143 4144 /// This represents '#pragma omp parallel master taskloop' directive. 4145 /// 4146 /// \code 4147 /// #pragma omp parallel master taskloop private(a,b) grainsize(val) 4148 /// num_tasks(num) 4149 /// \endcode 4150 /// In this example directive '#pragma omp parallel master taskloop' has clauses 4151 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 4152 /// and 'num_tasks' with expression 'num'. 4153 /// 4154 class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective { 4155 friend class ASTStmtReader; 4156 friend class OMPExecutableDirective; 4157 /// true if the construct has inner cancel directive. 4158 bool HasCancel = false; 4159 4160 /// Build directive with the given start and end location. 4161 /// 4162 /// \param StartLoc Starting location of the directive kind. 4163 /// \param EndLoc Ending location of the directive. 4164 /// \param CollapsedNum Number of collapsed nested loops. 4165 /// OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4166 OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc, 4167 SourceLocation EndLoc, 4168 unsigned CollapsedNum) 4169 : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass, 4170 llvm::omp::OMPD_parallel_master_taskloop, StartLoc, 4171 EndLoc, CollapsedNum) {} 4172 4173 /// Build an empty directive. 4174 /// 4175 /// \param CollapsedNum Number of collapsed nested loops. 4176 /// OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum)4177 explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum) 4178 : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass, 4179 llvm::omp::OMPD_parallel_master_taskloop, 4180 SourceLocation(), SourceLocation(), CollapsedNum) {} 4181 4182 /// Set cancel state. setHasCancel(bool Has)4183 void setHasCancel(bool Has) { HasCancel = Has; } 4184 4185 public: 4186 /// Creates directive with a list of \a Clauses. 4187 /// 4188 /// \param C AST context. 4189 /// \param StartLoc Starting location of the directive kind. 4190 /// \param EndLoc Ending Location of the directive. 4191 /// \param CollapsedNum Number of collapsed loops. 4192 /// \param Clauses List of clauses. 4193 /// \param AssociatedStmt Statement, associated with the directive. 4194 /// \param Exprs Helper expressions for CodeGen. 4195 /// \param HasCancel true if this directive has inner cancel directive. 4196 /// 4197 static OMPParallelMasterTaskLoopDirective * 4198 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4199 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4200 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 4201 4202 /// Creates an empty directive with the place 4203 /// for \a NumClauses clauses. 4204 /// 4205 /// \param C AST context. 4206 /// \param CollapsedNum Number of collapsed nested loops. 4207 /// \param NumClauses Number of clauses. 4208 /// 4209 static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C, 4210 unsigned NumClauses, 4211 unsigned CollapsedNum, 4212 EmptyShell); 4213 4214 /// Return true if current directive has inner cancel directive. hasCancel()4215 bool hasCancel() const { return HasCancel; } 4216 classof(const Stmt * T)4217 static bool classof(const Stmt *T) { 4218 return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass; 4219 } 4220 }; 4221 4222 /// This represents '#pragma omp parallel masked taskloop' directive. 4223 /// 4224 /// \code 4225 /// #pragma omp parallel masked taskloop private(a,b) grainsize(val) 4226 /// num_tasks(num) 4227 /// \endcode 4228 /// In this example directive '#pragma omp parallel masked taskloop' has clauses 4229 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 4230 /// and 'num_tasks' with expression 'num'. 4231 /// 4232 class OMPParallelMaskedTaskLoopDirective final : public OMPLoopDirective { 4233 friend class ASTStmtReader; 4234 friend class OMPExecutableDirective; 4235 /// true if the construct has inner cancel directive. 4236 bool HasCancel = false; 4237 4238 /// Build directive with the given start and end location. 4239 /// 4240 /// \param StartLoc Starting location of the directive kind. 4241 /// \param EndLoc Ending location of the directive. 4242 /// \param CollapsedNum Number of collapsed nested loops. 4243 /// OMPParallelMaskedTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4244 OMPParallelMaskedTaskLoopDirective(SourceLocation StartLoc, 4245 SourceLocation EndLoc, 4246 unsigned CollapsedNum) 4247 : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass, 4248 llvm::omp::OMPD_parallel_masked_taskloop, StartLoc, 4249 EndLoc, CollapsedNum) {} 4250 4251 /// Build an empty directive. 4252 /// 4253 /// \param CollapsedNum Number of collapsed nested loops. 4254 /// OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum)4255 explicit OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum) 4256 : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass, 4257 llvm::omp::OMPD_parallel_masked_taskloop, 4258 SourceLocation(), SourceLocation(), CollapsedNum) {} 4259 4260 /// Set cancel state. setHasCancel(bool Has)4261 void setHasCancel(bool Has) { HasCancel = Has; } 4262 4263 public: 4264 /// Creates directive with a list of \a Clauses. 4265 /// 4266 /// \param C AST context. 4267 /// \param StartLoc Starting location of the directive kind. 4268 /// \param EndLoc Ending Location of the directive. 4269 /// \param CollapsedNum Number of collapsed loops. 4270 /// \param Clauses List of clauses. 4271 /// \param AssociatedStmt Statement, associated with the directive. 4272 /// \param Exprs Helper expressions for CodeGen. 4273 /// \param HasCancel true if this directive has inner cancel directive. 4274 /// 4275 static OMPParallelMaskedTaskLoopDirective * 4276 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4277 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4278 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 4279 4280 /// Creates an empty directive with the place 4281 /// for \a NumClauses clauses. 4282 /// 4283 /// \param C AST context. 4284 /// \param CollapsedNum Number of collapsed nested loops. 4285 /// \param NumClauses Number of clauses. 4286 /// 4287 static OMPParallelMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C, 4288 unsigned NumClauses, 4289 unsigned CollapsedNum, 4290 EmptyShell); 4291 4292 /// Return true if current directive has inner cancel directive. hasCancel()4293 bool hasCancel() const { return HasCancel; } 4294 classof(const Stmt * T)4295 static bool classof(const Stmt *T) { 4296 return T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass; 4297 } 4298 }; 4299 4300 /// This represents '#pragma omp parallel master taskloop simd' directive. 4301 /// 4302 /// \code 4303 /// #pragma omp parallel master taskloop simd private(a,b) grainsize(val) 4304 /// num_tasks(num) 4305 /// \endcode 4306 /// In this example directive '#pragma omp parallel master taskloop simd' has 4307 /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with 4308 /// expression 'val' and 'num_tasks' with expression 'num'. 4309 /// 4310 class OMPParallelMasterTaskLoopSimdDirective : public OMPLoopDirective { 4311 friend class ASTStmtReader; 4312 friend class OMPExecutableDirective; 4313 /// Build directive with the given start and end location. 4314 /// 4315 /// \param StartLoc Starting location of the directive kind. 4316 /// \param EndLoc Ending location of the directive. 4317 /// \param CollapsedNum Number of collapsed nested loops. 4318 /// OMPParallelMasterTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4319 OMPParallelMasterTaskLoopSimdDirective(SourceLocation StartLoc, 4320 SourceLocation EndLoc, 4321 unsigned CollapsedNum) 4322 : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass, 4323 llvm::omp::OMPD_parallel_master_taskloop_simd, 4324 StartLoc, EndLoc, CollapsedNum) {} 4325 4326 /// Build an empty directive. 4327 /// 4328 /// \param CollapsedNum Number of collapsed nested loops. 4329 /// OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum)4330 explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum) 4331 : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass, 4332 llvm::omp::OMPD_parallel_master_taskloop_simd, 4333 SourceLocation(), SourceLocation(), CollapsedNum) {} 4334 4335 public: 4336 /// Creates directive with a list of \p Clauses. 4337 /// 4338 /// \param C AST context. 4339 /// \param StartLoc Starting location of the directive kind. 4340 /// \param EndLoc Ending Location of the directive. 4341 /// \param CollapsedNum Number of collapsed loops. 4342 /// \param Clauses List of clauses. 4343 /// \param AssociatedStmt Statement, associated with the directive. 4344 /// \param Exprs Helper expressions for CodeGen. 4345 /// 4346 static OMPParallelMasterTaskLoopSimdDirective * 4347 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4348 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4349 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4350 4351 /// Creates an empty directive with the place 4352 /// for \a NumClauses clauses. 4353 /// 4354 /// \param C AST context. 4355 /// \param CollapsedNum Number of collapsed nested loops. 4356 /// \param NumClauses Number of clauses. 4357 /// 4358 static OMPParallelMasterTaskLoopSimdDirective * 4359 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4360 EmptyShell); 4361 classof(const Stmt * T)4362 static bool classof(const Stmt *T) { 4363 return T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass; 4364 } 4365 }; 4366 4367 /// This represents '#pragma omp parallel masked taskloop simd' directive. 4368 /// 4369 /// \code 4370 /// #pragma omp parallel masked taskloop simd private(a,b) grainsize(val) 4371 /// num_tasks(num) 4372 /// \endcode 4373 /// In this example directive '#pragma omp parallel masked taskloop simd' has 4374 /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with 4375 /// expression 'val' and 'num_tasks' with expression 'num'. 4376 /// 4377 class OMPParallelMaskedTaskLoopSimdDirective final : public OMPLoopDirective { 4378 friend class ASTStmtReader; 4379 friend class OMPExecutableDirective; 4380 /// Build directive with the given start and end location. 4381 /// 4382 /// \param StartLoc Starting location of the directive kind. 4383 /// \param EndLoc Ending location of the directive. 4384 /// \param CollapsedNum Number of collapsed nested loops. 4385 /// OMPParallelMaskedTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4386 OMPParallelMaskedTaskLoopSimdDirective(SourceLocation StartLoc, 4387 SourceLocation EndLoc, 4388 unsigned CollapsedNum) 4389 : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass, 4390 llvm::omp::OMPD_parallel_masked_taskloop_simd, 4391 StartLoc, EndLoc, CollapsedNum) {} 4392 4393 /// Build an empty directive. 4394 /// 4395 /// \param CollapsedNum Number of collapsed nested loops. 4396 /// OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum)4397 explicit OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum) 4398 : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass, 4399 llvm::omp::OMPD_parallel_masked_taskloop_simd, 4400 SourceLocation(), SourceLocation(), CollapsedNum) {} 4401 4402 public: 4403 /// Creates directive with a list of \p Clauses. 4404 /// 4405 /// \param C AST context. 4406 /// \param StartLoc Starting location of the directive kind. 4407 /// \param EndLoc Ending Location of the directive. 4408 /// \param CollapsedNum Number of collapsed loops. 4409 /// \param Clauses List of clauses. 4410 /// \param AssociatedStmt Statement, associated with the directive. 4411 /// \param Exprs Helper expressions for CodeGen. 4412 /// 4413 static OMPParallelMaskedTaskLoopSimdDirective * 4414 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4415 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4416 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4417 4418 /// Creates an empty directive with the place 4419 /// for \a NumClauses clauses. 4420 /// 4421 /// \param C AST context. 4422 /// \param CollapsedNum Number of collapsed nested loops. 4423 /// \param NumClauses Number of clauses. 4424 /// 4425 static OMPParallelMaskedTaskLoopSimdDirective * 4426 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4427 EmptyShell); 4428 classof(const Stmt * T)4429 static bool classof(const Stmt *T) { 4430 return T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass; 4431 } 4432 }; 4433 4434 /// This represents '#pragma omp distribute' directive. 4435 /// 4436 /// \code 4437 /// #pragma omp distribute private(a,b) 4438 /// \endcode 4439 /// In this example directive '#pragma omp distribute' has clauses 'private' 4440 /// with the variables 'a' and 'b' 4441 /// 4442 class OMPDistributeDirective : public OMPLoopDirective { 4443 friend class ASTStmtReader; 4444 friend class OMPExecutableDirective; 4445 4446 /// Build directive with the given start and end location. 4447 /// 4448 /// \param StartLoc Starting location of the directive kind. 4449 /// \param EndLoc Ending location of the directive. 4450 /// \param CollapsedNum Number of collapsed nested loops. 4451 /// OMPDistributeDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4452 OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4453 unsigned CollapsedNum) 4454 : OMPLoopDirective(OMPDistributeDirectiveClass, 4455 llvm::omp::OMPD_distribute, StartLoc, EndLoc, 4456 CollapsedNum) {} 4457 4458 /// Build an empty directive. 4459 /// 4460 /// \param CollapsedNum Number of collapsed nested loops. 4461 /// OMPDistributeDirective(unsigned CollapsedNum)4462 explicit OMPDistributeDirective(unsigned CollapsedNum) 4463 : OMPLoopDirective(OMPDistributeDirectiveClass, 4464 llvm::omp::OMPD_distribute, SourceLocation(), 4465 SourceLocation(), CollapsedNum) {} 4466 4467 public: 4468 /// Creates directive with a list of \a Clauses. 4469 /// 4470 /// \param C AST context. 4471 /// \param StartLoc Starting location of the directive kind. 4472 /// \param EndLoc Ending Location of the directive. 4473 /// \param CollapsedNum Number of collapsed loops. 4474 /// \param Clauses List of clauses. 4475 /// \param AssociatedStmt Statement, associated with the directive. 4476 /// \param Exprs Helper expressions for CodeGen. 4477 /// 4478 static OMPDistributeDirective * 4479 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4480 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4481 Stmt *AssociatedStmt, const HelperExprs &Exprs, 4482 OpenMPDirectiveKind ParamPrevMappedDirective); 4483 4484 /// Creates an empty directive with the place 4485 /// for \a NumClauses clauses. 4486 /// 4487 /// \param C AST context. 4488 /// \param CollapsedNum Number of collapsed nested loops. 4489 /// \param NumClauses Number of clauses. 4490 /// 4491 static OMPDistributeDirective *CreateEmpty(const ASTContext &C, 4492 unsigned NumClauses, 4493 unsigned CollapsedNum, EmptyShell); 4494 classof(const Stmt * T)4495 static bool classof(const Stmt *T) { 4496 return T->getStmtClass() == OMPDistributeDirectiveClass; 4497 } 4498 }; 4499 4500 /// This represents '#pragma omp target update' directive. 4501 /// 4502 /// \code 4503 /// #pragma omp target update to(a) from(b) device(1) 4504 /// \endcode 4505 /// In this example directive '#pragma omp target update' has clause 'to' with 4506 /// argument 'a', clause 'from' with argument 'b' and clause 'device' with 4507 /// argument '1'. 4508 /// 4509 class OMPTargetUpdateDirective : public OMPExecutableDirective { 4510 friend class ASTStmtReader; 4511 friend class OMPExecutableDirective; 4512 /// Build directive with the given start and end location. 4513 /// 4514 /// \param StartLoc Starting location of the directive kind. 4515 /// \param EndLoc Ending Location of the directive. 4516 /// OMPTargetUpdateDirective(SourceLocation StartLoc,SourceLocation EndLoc)4517 OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc) 4518 : OMPExecutableDirective(OMPTargetUpdateDirectiveClass, 4519 llvm::omp::OMPD_target_update, StartLoc, 4520 EndLoc) {} 4521 4522 /// Build an empty directive. 4523 /// OMPTargetUpdateDirective()4524 explicit OMPTargetUpdateDirective() 4525 : OMPExecutableDirective(OMPTargetUpdateDirectiveClass, 4526 llvm::omp::OMPD_target_update, SourceLocation(), 4527 SourceLocation()) {} 4528 4529 public: 4530 /// Creates directive with a list of \a Clauses. 4531 /// 4532 /// \param C AST context. 4533 /// \param StartLoc Starting location of the directive kind. 4534 /// \param EndLoc Ending Location of the directive. 4535 /// \param Clauses List of clauses. 4536 /// \param AssociatedStmt Statement, associated with the directive. 4537 /// 4538 static OMPTargetUpdateDirective * 4539 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4540 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 4541 4542 /// Creates an empty directive with the place for \a NumClauses 4543 /// clauses. 4544 /// 4545 /// \param C AST context. 4546 /// \param NumClauses The number of clauses. 4547 /// 4548 static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C, 4549 unsigned NumClauses, EmptyShell); 4550 classof(const Stmt * T)4551 static bool classof(const Stmt *T) { 4552 return T->getStmtClass() == OMPTargetUpdateDirectiveClass; 4553 } 4554 }; 4555 4556 /// This represents '#pragma omp distribute parallel for' composite 4557 /// directive. 4558 /// 4559 /// \code 4560 /// #pragma omp distribute parallel for private(a,b) 4561 /// \endcode 4562 /// In this example directive '#pragma omp distribute parallel for' has clause 4563 /// 'private' with the variables 'a' and 'b' 4564 /// 4565 class OMPDistributeParallelForDirective : public OMPLoopDirective { 4566 friend class ASTStmtReader; 4567 friend class OMPExecutableDirective; 4568 /// true if the construct has inner cancel directive. 4569 bool HasCancel = false; 4570 4571 /// Build directive with the given start and end location. 4572 /// 4573 /// \param StartLoc Starting location of the directive kind. 4574 /// \param EndLoc Ending location of the directive. 4575 /// \param CollapsedNum Number of collapsed nested loops. 4576 /// OMPDistributeParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4577 OMPDistributeParallelForDirective(SourceLocation StartLoc, 4578 SourceLocation EndLoc, 4579 unsigned CollapsedNum) 4580 : OMPLoopDirective(OMPDistributeParallelForDirectiveClass, 4581 llvm::omp::OMPD_distribute_parallel_for, StartLoc, 4582 EndLoc, CollapsedNum) {} 4583 4584 /// Build an empty directive. 4585 /// 4586 /// \param CollapsedNum Number of collapsed nested loops. 4587 /// OMPDistributeParallelForDirective(unsigned CollapsedNum)4588 explicit OMPDistributeParallelForDirective(unsigned CollapsedNum) 4589 : OMPLoopDirective(OMPDistributeParallelForDirectiveClass, 4590 llvm::omp::OMPD_distribute_parallel_for, 4591 SourceLocation(), SourceLocation(), CollapsedNum) {} 4592 4593 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)4594 void setTaskReductionRefExpr(Expr *E) { 4595 Data->getChildren()[numLoopChildren( 4596 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)] = E; 4597 } 4598 4599 /// Set cancel state. setHasCancel(bool Has)4600 void setHasCancel(bool Has) { HasCancel = Has; } 4601 4602 public: 4603 /// Creates directive with a list of \a Clauses. 4604 /// 4605 /// \param C AST context. 4606 /// \param StartLoc Starting location of the directive kind. 4607 /// \param EndLoc Ending Location of the directive. 4608 /// \param CollapsedNum Number of collapsed loops. 4609 /// \param Clauses List of clauses. 4610 /// \param AssociatedStmt Statement, associated with the directive. 4611 /// \param Exprs Helper expressions for CodeGen. 4612 /// \param TaskRedRef Task reduction special reference expression to handle 4613 /// taskgroup descriptor. 4614 /// \param HasCancel true if this directive has inner cancel directive. 4615 /// 4616 static OMPDistributeParallelForDirective * 4617 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4618 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4619 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 4620 bool HasCancel); 4621 4622 /// Creates an empty directive with the place 4623 /// for \a NumClauses clauses. 4624 /// 4625 /// \param C AST context. 4626 /// \param CollapsedNum Number of collapsed nested loops. 4627 /// \param NumClauses Number of clauses. 4628 /// 4629 static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C, 4630 unsigned NumClauses, 4631 unsigned CollapsedNum, 4632 EmptyShell); 4633 4634 /// Returns special task reduction reference expression. getTaskReductionRefExpr()4635 Expr *getTaskReductionRefExpr() { 4636 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 4637 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)]); 4638 } getTaskReductionRefExpr()4639 const Expr *getTaskReductionRefExpr() const { 4640 return const_cast<OMPDistributeParallelForDirective *>(this) 4641 ->getTaskReductionRefExpr(); 4642 } 4643 4644 /// Return true if current directive has inner cancel directive. hasCancel()4645 bool hasCancel() const { return HasCancel; } 4646 classof(const Stmt * T)4647 static bool classof(const Stmt *T) { 4648 return T->getStmtClass() == OMPDistributeParallelForDirectiveClass; 4649 } 4650 }; 4651 4652 /// This represents '#pragma omp distribute parallel for simd' composite 4653 /// directive. 4654 /// 4655 /// \code 4656 /// #pragma omp distribute parallel for simd private(x) 4657 /// \endcode 4658 /// In this example directive '#pragma omp distribute parallel for simd' has 4659 /// clause 'private' with the variables 'x' 4660 /// 4661 class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective { 4662 friend class ASTStmtReader; 4663 friend class OMPExecutableDirective; 4664 4665 /// Build directive with the given start and end location. 4666 /// 4667 /// \param StartLoc Starting location of the directive kind. 4668 /// \param EndLoc Ending location of the directive. 4669 /// \param CollapsedNum Number of collapsed nested loops. 4670 /// OMPDistributeParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4671 OMPDistributeParallelForSimdDirective(SourceLocation StartLoc, 4672 SourceLocation EndLoc, 4673 unsigned CollapsedNum) 4674 : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass, 4675 llvm::omp::OMPD_distribute_parallel_for_simd, StartLoc, 4676 EndLoc, CollapsedNum) {} 4677 4678 /// Build an empty directive. 4679 /// 4680 /// \param CollapsedNum Number of collapsed nested loops. 4681 /// OMPDistributeParallelForSimdDirective(unsigned CollapsedNum)4682 explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum) 4683 : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass, 4684 llvm::omp::OMPD_distribute_parallel_for_simd, 4685 SourceLocation(), SourceLocation(), CollapsedNum) {} 4686 4687 public: 4688 /// Creates directive with a list of \a Clauses. 4689 /// 4690 /// \param C AST context. 4691 /// \param StartLoc Starting location of the directive kind. 4692 /// \param EndLoc Ending Location of the directive. 4693 /// \param CollapsedNum Number of collapsed loops. 4694 /// \param Clauses List of clauses. 4695 /// \param AssociatedStmt Statement, associated with the directive. 4696 /// \param Exprs Helper expressions for CodeGen. 4697 /// 4698 static OMPDistributeParallelForSimdDirective *Create( 4699 const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4700 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4701 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4702 4703 /// Creates an empty directive with the place for \a NumClauses clauses. 4704 /// 4705 /// \param C AST context. 4706 /// \param CollapsedNum Number of collapsed nested loops. 4707 /// \param NumClauses Number of clauses. 4708 /// 4709 static OMPDistributeParallelForSimdDirective *CreateEmpty( 4710 const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4711 EmptyShell); 4712 classof(const Stmt * T)4713 static bool classof(const Stmt *T) { 4714 return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass; 4715 } 4716 }; 4717 4718 /// This represents '#pragma omp distribute simd' composite directive. 4719 /// 4720 /// \code 4721 /// #pragma omp distribute simd private(x) 4722 /// \endcode 4723 /// In this example directive '#pragma omp distribute simd' has clause 4724 /// 'private' with the variables 'x' 4725 /// 4726 class OMPDistributeSimdDirective final : public OMPLoopDirective { 4727 friend class ASTStmtReader; 4728 friend class OMPExecutableDirective; 4729 4730 /// Build directive with the given start and end location. 4731 /// 4732 /// \param StartLoc Starting location of the directive kind. 4733 /// \param EndLoc Ending location of the directive. 4734 /// \param CollapsedNum Number of collapsed nested loops. 4735 /// OMPDistributeSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4736 OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4737 unsigned CollapsedNum) 4738 : OMPLoopDirective(OMPDistributeSimdDirectiveClass, 4739 llvm::omp::OMPD_distribute_simd, StartLoc, EndLoc, 4740 CollapsedNum) {} 4741 4742 /// Build an empty directive. 4743 /// 4744 /// \param CollapsedNum Number of collapsed nested loops. 4745 /// OMPDistributeSimdDirective(unsigned CollapsedNum)4746 explicit OMPDistributeSimdDirective(unsigned CollapsedNum) 4747 : OMPLoopDirective(OMPDistributeSimdDirectiveClass, 4748 llvm::omp::OMPD_distribute_simd, SourceLocation(), 4749 SourceLocation(), CollapsedNum) {} 4750 4751 public: 4752 /// Creates directive with a list of \a Clauses. 4753 /// 4754 /// \param C AST context. 4755 /// \param StartLoc Starting location of the directive kind. 4756 /// \param EndLoc Ending Location of the directive. 4757 /// \param CollapsedNum Number of collapsed loops. 4758 /// \param Clauses List of clauses. 4759 /// \param AssociatedStmt Statement, associated with the directive. 4760 /// \param Exprs Helper expressions for CodeGen. 4761 /// 4762 static OMPDistributeSimdDirective * 4763 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4764 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4765 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4766 4767 /// Creates an empty directive with the place for \a NumClauses clauses. 4768 /// 4769 /// \param C AST context. 4770 /// \param CollapsedNum Number of collapsed nested loops. 4771 /// \param NumClauses Number of clauses. 4772 /// 4773 static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C, 4774 unsigned NumClauses, 4775 unsigned CollapsedNum, 4776 EmptyShell); 4777 classof(const Stmt * T)4778 static bool classof(const Stmt *T) { 4779 return T->getStmtClass() == OMPDistributeSimdDirectiveClass; 4780 } 4781 }; 4782 4783 /// This represents '#pragma omp target parallel for simd' directive. 4784 /// 4785 /// \code 4786 /// #pragma omp target parallel for simd private(a) map(b) safelen(c) 4787 /// \endcode 4788 /// In this example directive '#pragma omp target parallel for simd' has clauses 4789 /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen' 4790 /// with the variable 'c'. 4791 /// 4792 class OMPTargetParallelForSimdDirective final : public OMPLoopDirective { 4793 friend class ASTStmtReader; 4794 friend class OMPExecutableDirective; 4795 4796 /// Build directive with the given start and end location. 4797 /// 4798 /// \param StartLoc Starting location of the directive kind. 4799 /// \param EndLoc Ending location of the directive. 4800 /// \param CollapsedNum Number of collapsed nested loops. 4801 /// OMPTargetParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4802 OMPTargetParallelForSimdDirective(SourceLocation StartLoc, 4803 SourceLocation EndLoc, 4804 unsigned CollapsedNum) 4805 : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass, 4806 llvm::omp::OMPD_target_parallel_for_simd, StartLoc, 4807 EndLoc, CollapsedNum) {} 4808 4809 /// Build an empty directive. 4810 /// 4811 /// \param CollapsedNum Number of collapsed nested loops. 4812 /// OMPTargetParallelForSimdDirective(unsigned CollapsedNum)4813 explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum) 4814 : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass, 4815 llvm::omp::OMPD_target_parallel_for_simd, 4816 SourceLocation(), SourceLocation(), CollapsedNum) {} 4817 4818 public: 4819 /// Creates directive with a list of \a Clauses. 4820 /// 4821 /// \param C AST context. 4822 /// \param StartLoc Starting location of the directive kind. 4823 /// \param EndLoc Ending Location of the directive. 4824 /// \param CollapsedNum Number of collapsed loops. 4825 /// \param Clauses List of clauses. 4826 /// \param AssociatedStmt Statement, associated with the directive. 4827 /// \param Exprs Helper expressions for CodeGen. 4828 /// 4829 static OMPTargetParallelForSimdDirective * 4830 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4831 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4832 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4833 4834 /// Creates an empty directive with the place for \a NumClauses clauses. 4835 /// 4836 /// \param C AST context. 4837 /// \param CollapsedNum Number of collapsed nested loops. 4838 /// \param NumClauses Number of clauses. 4839 /// 4840 static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C, 4841 unsigned NumClauses, 4842 unsigned CollapsedNum, 4843 EmptyShell); 4844 classof(const Stmt * T)4845 static bool classof(const Stmt *T) { 4846 return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass; 4847 } 4848 }; 4849 4850 /// This represents '#pragma omp target simd' directive. 4851 /// 4852 /// \code 4853 /// #pragma omp target simd private(a) map(b) safelen(c) 4854 /// \endcode 4855 /// In this example directive '#pragma omp target simd' has clauses 'private' 4856 /// with the variable 'a', 'map' with the variable 'b' and 'safelen' with 4857 /// the variable 'c'. 4858 /// 4859 class OMPTargetSimdDirective final : public OMPLoopDirective { 4860 friend class ASTStmtReader; 4861 friend class OMPExecutableDirective; 4862 4863 /// Build directive with the given start and end location. 4864 /// 4865 /// \param StartLoc Starting location of the directive kind. 4866 /// \param EndLoc Ending location of the directive. 4867 /// \param CollapsedNum Number of collapsed nested loops. 4868 /// OMPTargetSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4869 OMPTargetSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4870 unsigned CollapsedNum) 4871 : OMPLoopDirective(OMPTargetSimdDirectiveClass, 4872 llvm::omp::OMPD_target_simd, StartLoc, EndLoc, 4873 CollapsedNum) {} 4874 4875 /// Build an empty directive. 4876 /// 4877 /// \param CollapsedNum Number of collapsed nested loops. 4878 /// OMPTargetSimdDirective(unsigned CollapsedNum)4879 explicit OMPTargetSimdDirective(unsigned CollapsedNum) 4880 : OMPLoopDirective(OMPTargetSimdDirectiveClass, 4881 llvm::omp::OMPD_target_simd, SourceLocation(), 4882 SourceLocation(), CollapsedNum) {} 4883 4884 public: 4885 /// Creates directive with a list of \a Clauses. 4886 /// 4887 /// \param C AST context. 4888 /// \param StartLoc Starting location of the directive kind. 4889 /// \param EndLoc Ending Location of the directive. 4890 /// \param CollapsedNum Number of collapsed loops. 4891 /// \param Clauses List of clauses. 4892 /// \param AssociatedStmt Statement, associated with the directive. 4893 /// \param Exprs Helper expressions for CodeGen. 4894 /// 4895 static OMPTargetSimdDirective * 4896 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4897 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4898 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4899 4900 /// Creates an empty directive with the place for \a NumClauses clauses. 4901 /// 4902 /// \param C AST context. 4903 /// \param CollapsedNum Number of collapsed nested loops. 4904 /// \param NumClauses Number of clauses. 4905 /// 4906 static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C, 4907 unsigned NumClauses, 4908 unsigned CollapsedNum, 4909 EmptyShell); 4910 classof(const Stmt * T)4911 static bool classof(const Stmt *T) { 4912 return T->getStmtClass() == OMPTargetSimdDirectiveClass; 4913 } 4914 }; 4915 4916 /// This represents '#pragma omp teams distribute' directive. 4917 /// 4918 /// \code 4919 /// #pragma omp teams distribute private(a,b) 4920 /// \endcode 4921 /// In this example directive '#pragma omp teams distribute' has clauses 4922 /// 'private' with the variables 'a' and 'b' 4923 /// 4924 class OMPTeamsDistributeDirective final : public OMPLoopDirective { 4925 friend class ASTStmtReader; 4926 friend class OMPExecutableDirective; 4927 4928 /// Build directive with the given start and end location. 4929 /// 4930 /// \param StartLoc Starting location of the directive kind. 4931 /// \param EndLoc Ending location of the directive. 4932 /// \param CollapsedNum Number of collapsed nested loops. 4933 /// OMPTeamsDistributeDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4934 OMPTeamsDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4935 unsigned CollapsedNum) 4936 : OMPLoopDirective(OMPTeamsDistributeDirectiveClass, 4937 llvm::omp::OMPD_teams_distribute, StartLoc, EndLoc, 4938 CollapsedNum) {} 4939 4940 /// Build an empty directive. 4941 /// 4942 /// \param CollapsedNum Number of collapsed nested loops. 4943 /// OMPTeamsDistributeDirective(unsigned CollapsedNum)4944 explicit OMPTeamsDistributeDirective(unsigned CollapsedNum) 4945 : OMPLoopDirective(OMPTeamsDistributeDirectiveClass, 4946 llvm::omp::OMPD_teams_distribute, SourceLocation(), 4947 SourceLocation(), CollapsedNum) {} 4948 4949 public: 4950 /// Creates directive with a list of \a Clauses. 4951 /// 4952 /// \param C AST context. 4953 /// \param StartLoc Starting location of the directive kind. 4954 /// \param EndLoc Ending Location of the directive. 4955 /// \param CollapsedNum Number of collapsed loops. 4956 /// \param Clauses List of clauses. 4957 /// \param AssociatedStmt Statement, associated with the directive. 4958 /// \param Exprs Helper expressions for CodeGen. 4959 /// 4960 static OMPTeamsDistributeDirective * 4961 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4962 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4963 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4964 4965 /// Creates an empty directive with the place for \a NumClauses clauses. 4966 /// 4967 /// \param C AST context. 4968 /// \param CollapsedNum Number of collapsed nested loops. 4969 /// \param NumClauses Number of clauses. 4970 /// 4971 static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C, 4972 unsigned NumClauses, 4973 unsigned CollapsedNum, 4974 EmptyShell); 4975 classof(const Stmt * T)4976 static bool classof(const Stmt *T) { 4977 return T->getStmtClass() == OMPTeamsDistributeDirectiveClass; 4978 } 4979 }; 4980 4981 /// This represents '#pragma omp teams distribute simd' 4982 /// combined directive. 4983 /// 4984 /// \code 4985 /// #pragma omp teams distribute simd private(a,b) 4986 /// \endcode 4987 /// In this example directive '#pragma omp teams distribute simd' 4988 /// has clause 'private' with the variables 'a' and 'b' 4989 /// 4990 class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective { 4991 friend class ASTStmtReader; 4992 friend class OMPExecutableDirective; 4993 4994 /// Build directive with the given start and end location. 4995 /// 4996 /// \param StartLoc Starting location of the directive kind. 4997 /// \param EndLoc Ending location of the directive. 4998 /// \param CollapsedNum Number of collapsed nested loops. 4999 /// OMPTeamsDistributeSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5000 OMPTeamsDistributeSimdDirective(SourceLocation StartLoc, 5001 SourceLocation EndLoc, unsigned CollapsedNum) 5002 : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass, 5003 llvm::omp::OMPD_teams_distribute_simd, StartLoc, 5004 EndLoc, CollapsedNum) {} 5005 5006 /// Build an empty directive. 5007 /// 5008 /// \param CollapsedNum Number of collapsed nested loops. 5009 /// OMPTeamsDistributeSimdDirective(unsigned CollapsedNum)5010 explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum) 5011 : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass, 5012 llvm::omp::OMPD_teams_distribute_simd, 5013 SourceLocation(), SourceLocation(), CollapsedNum) {} 5014 5015 public: 5016 /// Creates directive with a list of \a Clauses. 5017 /// 5018 /// \param C AST context. 5019 /// \param StartLoc Starting location of the directive kind. 5020 /// \param EndLoc Ending Location of the directive. 5021 /// \param CollapsedNum Number of collapsed loops. 5022 /// \param Clauses List of clauses. 5023 /// \param AssociatedStmt Statement, associated with the directive. 5024 /// \param Exprs Helper expressions for CodeGen. 5025 /// 5026 static OMPTeamsDistributeSimdDirective * 5027 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5028 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 5029 Stmt *AssociatedStmt, const HelperExprs &Exprs); 5030 5031 /// Creates an empty directive with the place 5032 /// for \a NumClauses clauses. 5033 /// 5034 /// \param C AST context. 5035 /// \param CollapsedNum Number of collapsed nested loops. 5036 /// \param NumClauses Number of clauses. 5037 /// 5038 static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C, 5039 unsigned NumClauses, 5040 unsigned CollapsedNum, 5041 EmptyShell); 5042 classof(const Stmt * T)5043 static bool classof(const Stmt *T) { 5044 return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass; 5045 } 5046 }; 5047 5048 /// This represents '#pragma omp teams distribute parallel for simd' composite 5049 /// directive. 5050 /// 5051 /// \code 5052 /// #pragma omp teams distribute parallel for simd private(x) 5053 /// \endcode 5054 /// In this example directive '#pragma omp teams distribute parallel for simd' 5055 /// has clause 'private' with the variables 'x' 5056 /// 5057 class OMPTeamsDistributeParallelForSimdDirective final 5058 : public OMPLoopDirective { 5059 friend class ASTStmtReader; 5060 friend class OMPExecutableDirective; 5061 5062 /// Build directive with the given start and end location. 5063 /// 5064 /// \param StartLoc Starting location of the directive kind. 5065 /// \param EndLoc Ending location of the directive. 5066 /// \param CollapsedNum Number of collapsed nested loops. 5067 /// OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5068 OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc, 5069 SourceLocation EndLoc, 5070 unsigned CollapsedNum) 5071 : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass, 5072 llvm::omp::OMPD_teams_distribute_parallel_for_simd, 5073 StartLoc, EndLoc, CollapsedNum) {} 5074 5075 /// Build an empty directive. 5076 /// 5077 /// \param CollapsedNum Number of collapsed nested loops. 5078 /// OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum)5079 explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum) 5080 : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass, 5081 llvm::omp::OMPD_teams_distribute_parallel_for_simd, 5082 SourceLocation(), SourceLocation(), CollapsedNum) {} 5083 5084 public: 5085 /// Creates directive with a list of \a Clauses. 5086 /// 5087 /// \param C AST context. 5088 /// \param StartLoc Starting location of the directive kind. 5089 /// \param EndLoc Ending Location of the directive. 5090 /// \param CollapsedNum Number of collapsed loops. 5091 /// \param Clauses List of clauses. 5092 /// \param AssociatedStmt Statement, associated with the directive. 5093 /// \param Exprs Helper expressions for CodeGen. 5094 /// 5095 static OMPTeamsDistributeParallelForSimdDirective * 5096 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5097 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 5098 Stmt *AssociatedStmt, const HelperExprs &Exprs); 5099 5100 /// Creates an empty directive with the place for \a NumClauses clauses. 5101 /// 5102 /// \param C AST context. 5103 /// \param CollapsedNum Number of collapsed nested loops. 5104 /// \param NumClauses Number of clauses. 5105 /// 5106 static OMPTeamsDistributeParallelForSimdDirective * 5107 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 5108 EmptyShell); 5109 classof(const Stmt * T)5110 static bool classof(const Stmt *T) { 5111 return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass; 5112 } 5113 }; 5114 5115 /// This represents '#pragma omp teams distribute parallel for' composite 5116 /// directive. 5117 /// 5118 /// \code 5119 /// #pragma omp teams distribute parallel for private(x) 5120 /// \endcode 5121 /// In this example directive '#pragma omp teams distribute parallel for' 5122 /// has clause 'private' with the variables 'x' 5123 /// 5124 class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective { 5125 friend class ASTStmtReader; 5126 friend class OMPExecutableDirective; 5127 /// true if the construct has inner cancel directive. 5128 bool HasCancel = false; 5129 5130 /// Build directive with the given start and end location. 5131 /// 5132 /// \param StartLoc Starting location of the directive kind. 5133 /// \param EndLoc Ending location of the directive. 5134 /// \param CollapsedNum Number of collapsed nested loops. 5135 /// OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5136 OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc, 5137 SourceLocation EndLoc, 5138 unsigned CollapsedNum) 5139 : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass, 5140 llvm::omp::OMPD_teams_distribute_parallel_for, 5141 StartLoc, EndLoc, CollapsedNum) {} 5142 5143 /// Build an empty directive. 5144 /// 5145 /// \param CollapsedNum Number of collapsed nested loops. 5146 /// OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum)5147 explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum) 5148 : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass, 5149 llvm::omp::OMPD_teams_distribute_parallel_for, 5150 SourceLocation(), SourceLocation(), CollapsedNum) {} 5151 5152 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)5153 void setTaskReductionRefExpr(Expr *E) { 5154 Data->getChildren()[numLoopChildren( 5155 getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)] = E; 5156 } 5157 5158 /// Set cancel state. setHasCancel(bool Has)5159 void setHasCancel(bool Has) { HasCancel = Has; } 5160 5161 public: 5162 /// Creates directive with a list of \a Clauses. 5163 /// 5164 /// \param C AST context. 5165 /// \param StartLoc Starting location of the directive kind. 5166 /// \param EndLoc Ending Location of the directive. 5167 /// \param CollapsedNum Number of collapsed loops. 5168 /// \param Clauses List of clauses. 5169 /// \param AssociatedStmt Statement, associated with the directive. 5170 /// \param Exprs Helper expressions for CodeGen. 5171 /// \param TaskRedRef Task reduction special reference expression to handle 5172 /// taskgroup descriptor. 5173 /// \param HasCancel true if this directive has inner cancel directive. 5174 /// 5175 static OMPTeamsDistributeParallelForDirective * 5176 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5177 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 5178 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 5179 bool HasCancel); 5180 5181 /// Creates an empty directive with the place for \a NumClauses clauses. 5182 /// 5183 /// \param C AST context. 5184 /// \param CollapsedNum Number of collapsed nested loops. 5185 /// \param NumClauses Number of clauses. 5186 /// 5187 static OMPTeamsDistributeParallelForDirective * 5188 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 5189 EmptyShell); 5190 5191 /// Returns special task reduction reference expression. getTaskReductionRefExpr()5192 Expr *getTaskReductionRefExpr() { 5193 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 5194 getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)]); 5195 } getTaskReductionRefExpr()5196 const Expr *getTaskReductionRefExpr() const { 5197 return const_cast<OMPTeamsDistributeParallelForDirective *>(this) 5198 ->getTaskReductionRefExpr(); 5199 } 5200 5201 /// Return true if current directive has inner cancel directive. hasCancel()5202 bool hasCancel() const { return HasCancel; } 5203 classof(const Stmt * T)5204 static bool classof(const Stmt *T) { 5205 return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass; 5206 } 5207 }; 5208 5209 /// This represents '#pragma omp target teams' directive. 5210 /// 5211 /// \code 5212 /// #pragma omp target teams if(a>0) 5213 /// \endcode 5214 /// In this example directive '#pragma omp target teams' has clause 'if' with 5215 /// condition 'a>0'. 5216 /// 5217 class OMPTargetTeamsDirective final : public OMPExecutableDirective { 5218 friend class ASTStmtReader; 5219 friend class OMPExecutableDirective; 5220 /// Build directive with the given start and end location. 5221 /// 5222 /// \param StartLoc Starting location of the directive kind. 5223 /// \param EndLoc Ending location of the directive. 5224 /// OMPTargetTeamsDirective(SourceLocation StartLoc,SourceLocation EndLoc)5225 OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5226 : OMPExecutableDirective(OMPTargetTeamsDirectiveClass, 5227 llvm::omp::OMPD_target_teams, StartLoc, EndLoc) { 5228 } 5229 5230 /// Build an empty directive. 5231 /// OMPTargetTeamsDirective()5232 explicit OMPTargetTeamsDirective() 5233 : OMPExecutableDirective(OMPTargetTeamsDirectiveClass, 5234 llvm::omp::OMPD_target_teams, SourceLocation(), 5235 SourceLocation()) {} 5236 5237 public: 5238 /// Creates directive with a list of \a Clauses. 5239 /// 5240 /// \param C AST context. 5241 /// \param StartLoc Starting location of the directive kind. 5242 /// \param EndLoc Ending Location of the directive. 5243 /// \param Clauses List of clauses. 5244 /// \param AssociatedStmt Statement, associated with the directive. 5245 /// 5246 static OMPTargetTeamsDirective *Create(const ASTContext &C, 5247 SourceLocation StartLoc, 5248 SourceLocation EndLoc, 5249 ArrayRef<OMPClause *> Clauses, 5250 Stmt *AssociatedStmt); 5251 5252 /// Creates an empty directive with the place for \a NumClauses clauses. 5253 /// 5254 /// \param C AST context. 5255 /// \param NumClauses Number of clauses. 5256 /// 5257 static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C, 5258 unsigned NumClauses, EmptyShell); 5259 classof(const Stmt * T)5260 static bool classof(const Stmt *T) { 5261 return T->getStmtClass() == OMPTargetTeamsDirectiveClass; 5262 } 5263 }; 5264 5265 /// This represents '#pragma omp target teams distribute' combined directive. 5266 /// 5267 /// \code 5268 /// #pragma omp target teams distribute private(x) 5269 /// \endcode 5270 /// In this example directive '#pragma omp target teams distribute' has clause 5271 /// 'private' with the variables 'x' 5272 /// 5273 class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective { 5274 friend class ASTStmtReader; 5275 friend class OMPExecutableDirective; 5276 5277 /// Build directive with the given start and end location. 5278 /// 5279 /// \param StartLoc Starting location of the directive kind. 5280 /// \param EndLoc Ending location of the directive. 5281 /// \param CollapsedNum Number of collapsed nested loops. 5282 /// OMPTargetTeamsDistributeDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5283 OMPTargetTeamsDistributeDirective(SourceLocation StartLoc, 5284 SourceLocation EndLoc, 5285 unsigned CollapsedNum) 5286 : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass, 5287 llvm::omp::OMPD_target_teams_distribute, StartLoc, 5288 EndLoc, CollapsedNum) {} 5289 5290 /// Build an empty directive. 5291 /// 5292 /// \param CollapsedNum Number of collapsed nested loops. 5293 /// OMPTargetTeamsDistributeDirective(unsigned CollapsedNum)5294 explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum) 5295 : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass, 5296 llvm::omp::OMPD_target_teams_distribute, 5297 SourceLocation(), SourceLocation(), CollapsedNum) {} 5298 5299 public: 5300 /// Creates directive with a list of \a Clauses. 5301 /// 5302 /// \param C AST context. 5303 /// \param StartLoc Starting location of the directive kind. 5304 /// \param EndLoc Ending Location of the directive. 5305 /// \param CollapsedNum Number of collapsed loops. 5306 /// \param Clauses List of clauses. 5307 /// \param AssociatedStmt Statement, associated with the directive. 5308 /// \param Exprs Helper expressions for CodeGen. 5309 /// 5310 static OMPTargetTeamsDistributeDirective * 5311 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5312 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 5313 Stmt *AssociatedStmt, const HelperExprs &Exprs); 5314 5315 /// Creates an empty directive with the place for \a NumClauses clauses. 5316 /// 5317 /// \param C AST context. 5318 /// \param CollapsedNum Number of collapsed nested loops. 5319 /// \param NumClauses Number of clauses. 5320 /// 5321 static OMPTargetTeamsDistributeDirective * 5322 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 5323 EmptyShell); 5324 classof(const Stmt * T)5325 static bool classof(const Stmt *T) { 5326 return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass; 5327 } 5328 }; 5329 5330 /// This represents '#pragma omp target teams distribute parallel for' combined 5331 /// directive. 5332 /// 5333 /// \code 5334 /// #pragma omp target teams distribute parallel for private(x) 5335 /// \endcode 5336 /// In this example directive '#pragma omp target teams distribute parallel 5337 /// for' has clause 'private' with the variables 'x' 5338 /// 5339 class OMPTargetTeamsDistributeParallelForDirective final 5340 : public OMPLoopDirective { 5341 friend class ASTStmtReader; 5342 friend class OMPExecutableDirective; 5343 /// true if the construct has inner cancel directive. 5344 bool HasCancel = false; 5345 5346 /// Build directive with the given start and end location. 5347 /// 5348 /// \param StartLoc Starting location of the directive kind. 5349 /// \param EndLoc Ending location of the directive. 5350 /// \param CollapsedNum Number of collapsed nested loops. 5351 /// OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5352 OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc, 5353 SourceLocation EndLoc, 5354 unsigned CollapsedNum) 5355 : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass, 5356 llvm::omp::OMPD_target_teams_distribute_parallel_for, 5357 StartLoc, EndLoc, CollapsedNum) {} 5358 5359 /// Build an empty directive. 5360 /// 5361 /// \param CollapsedNum Number of collapsed nested loops. 5362 /// OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum)5363 explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum) 5364 : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass, 5365 llvm::omp::OMPD_target_teams_distribute_parallel_for, 5366 SourceLocation(), SourceLocation(), CollapsedNum) {} 5367 5368 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)5369 void setTaskReductionRefExpr(Expr *E) { 5370 Data->getChildren()[numLoopChildren( 5371 getLoopsNumber(), 5372 llvm::omp::OMPD_target_teams_distribute_parallel_for)] = E; 5373 } 5374 5375 /// Set cancel state. setHasCancel(bool Has)5376 void setHasCancel(bool Has) { HasCancel = Has; } 5377 5378 public: 5379 /// Creates directive with a list of \a Clauses. 5380 /// 5381 /// \param C AST context. 5382 /// \param StartLoc Starting location of the directive kind. 5383 /// \param EndLoc Ending Location of the directive. 5384 /// \param CollapsedNum Number of collapsed loops. 5385 /// \param Clauses List of clauses. 5386 /// \param AssociatedStmt Statement, associated with the directive. 5387 /// \param Exprs Helper expressions for CodeGen. 5388 /// \param TaskRedRef Task reduction special reference expression to handle 5389 /// taskgroup descriptor. 5390 /// \param HasCancel true if this directive has inner cancel directive. 5391 /// 5392 static OMPTargetTeamsDistributeParallelForDirective * 5393 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5394 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 5395 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 5396 bool HasCancel); 5397 5398 /// Creates an empty directive with the place for \a NumClauses clauses. 5399 /// 5400 /// \param C AST context. 5401 /// \param CollapsedNum Number of collapsed nested loops. 5402 /// \param NumClauses Number of clauses. 5403 /// 5404 static OMPTargetTeamsDistributeParallelForDirective * 5405 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 5406 EmptyShell); 5407 5408 /// Returns special task reduction reference expression. getTaskReductionRefExpr()5409 Expr *getTaskReductionRefExpr() { 5410 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 5411 getLoopsNumber(), 5412 llvm::omp::OMPD_target_teams_distribute_parallel_for)]); 5413 } getTaskReductionRefExpr()5414 const Expr *getTaskReductionRefExpr() const { 5415 return const_cast<OMPTargetTeamsDistributeParallelForDirective *>(this) 5416 ->getTaskReductionRefExpr(); 5417 } 5418 5419 /// Return true if current directive has inner cancel directive. hasCancel()5420 bool hasCancel() const { return HasCancel; } 5421 classof(const Stmt * T)5422 static bool classof(const Stmt *T) { 5423 return T->getStmtClass() == 5424 OMPTargetTeamsDistributeParallelForDirectiveClass; 5425 } 5426 }; 5427 5428 /// This represents '#pragma omp target teams distribute parallel for simd' 5429 /// combined directive. 5430 /// 5431 /// \code 5432 /// #pragma omp target teams distribute parallel for simd private(x) 5433 /// \endcode 5434 /// In this example directive '#pragma omp target teams distribute parallel 5435 /// for simd' has clause 'private' with the variables 'x' 5436 /// 5437 class OMPTargetTeamsDistributeParallelForSimdDirective final 5438 : public OMPLoopDirective { 5439 friend class ASTStmtReader; 5440 friend class OMPExecutableDirective; 5441 5442 /// Build directive with the given start and end location. 5443 /// 5444 /// \param StartLoc Starting location of the directive kind. 5445 /// \param EndLoc Ending location of the directive. 5446 /// \param CollapsedNum Number of collapsed nested loops. 5447 /// OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5448 OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc, 5449 SourceLocation EndLoc, 5450 unsigned CollapsedNum) 5451 : OMPLoopDirective( 5452 OMPTargetTeamsDistributeParallelForSimdDirectiveClass, 5453 llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, StartLoc, 5454 EndLoc, CollapsedNum) {} 5455 5456 /// Build an empty directive. 5457 /// 5458 /// \param CollapsedNum Number of collapsed nested loops. 5459 /// OMPTargetTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum)5460 explicit OMPTargetTeamsDistributeParallelForSimdDirective( 5461 unsigned CollapsedNum) 5462 : OMPLoopDirective( 5463 OMPTargetTeamsDistributeParallelForSimdDirectiveClass, 5464 llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, 5465 SourceLocation(), SourceLocation(), CollapsedNum) {} 5466 5467 public: 5468 /// Creates directive with a list of \a Clauses. 5469 /// 5470 /// \param C AST context. 5471 /// \param StartLoc Starting location of the directive kind. 5472 /// \param EndLoc Ending Location of the directive. 5473 /// \param CollapsedNum Number of collapsed loops. 5474 /// \param Clauses List of clauses. 5475 /// \param AssociatedStmt Statement, associated with the directive. 5476 /// \param Exprs Helper expressions for CodeGen. 5477 /// 5478 static OMPTargetTeamsDistributeParallelForSimdDirective * 5479 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5480 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 5481 Stmt *AssociatedStmt, const HelperExprs &Exprs); 5482 5483 /// Creates an empty directive with the place for \a NumClauses clauses. 5484 /// 5485 /// \param C AST context. 5486 /// \param CollapsedNum Number of collapsed nested loops. 5487 /// \param NumClauses Number of clauses. 5488 /// 5489 static OMPTargetTeamsDistributeParallelForSimdDirective * 5490 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 5491 EmptyShell); 5492 classof(const Stmt * T)5493 static bool classof(const Stmt *T) { 5494 return T->getStmtClass() == 5495 OMPTargetTeamsDistributeParallelForSimdDirectiveClass; 5496 } 5497 }; 5498 5499 /// This represents '#pragma omp target teams distribute simd' combined 5500 /// directive. 5501 /// 5502 /// \code 5503 /// #pragma omp target teams distribute simd private(x) 5504 /// \endcode 5505 /// In this example directive '#pragma omp target teams distribute simd' 5506 /// has clause 'private' with the variables 'x' 5507 /// 5508 class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective { 5509 friend class ASTStmtReader; 5510 friend class OMPExecutableDirective; 5511 5512 /// Build directive with the given start and end location. 5513 /// 5514 /// \param StartLoc Starting location of the directive kind. 5515 /// \param EndLoc Ending location of the directive. 5516 /// \param CollapsedNum Number of collapsed nested loops. 5517 /// OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5518 OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc, 5519 SourceLocation EndLoc, 5520 unsigned CollapsedNum) 5521 : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass, 5522 llvm::omp::OMPD_target_teams_distribute_simd, StartLoc, 5523 EndLoc, CollapsedNum) {} 5524 5525 /// Build an empty directive. 5526 /// 5527 /// \param CollapsedNum Number of collapsed nested loops. 5528 /// OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum)5529 explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum) 5530 : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass, 5531 llvm::omp::OMPD_target_teams_distribute_simd, 5532 SourceLocation(), SourceLocation(), CollapsedNum) {} 5533 5534 public: 5535 /// Creates directive with a list of \a Clauses. 5536 /// 5537 /// \param C AST context. 5538 /// \param StartLoc Starting location of the directive kind. 5539 /// \param EndLoc Ending Location of the directive. 5540 /// \param CollapsedNum Number of collapsed loops. 5541 /// \param Clauses List of clauses. 5542 /// \param AssociatedStmt Statement, associated with the directive. 5543 /// \param Exprs Helper expressions for CodeGen. 5544 /// 5545 static OMPTargetTeamsDistributeSimdDirective * 5546 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5547 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 5548 Stmt *AssociatedStmt, const HelperExprs &Exprs); 5549 5550 /// Creates an empty directive with the place for \a NumClauses clauses. 5551 /// 5552 /// \param C AST context. 5553 /// \param CollapsedNum Number of collapsed nested loops. 5554 /// \param NumClauses Number of clauses. 5555 /// 5556 static OMPTargetTeamsDistributeSimdDirective * 5557 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 5558 EmptyShell); 5559 classof(const Stmt * T)5560 static bool classof(const Stmt *T) { 5561 return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass; 5562 } 5563 }; 5564 5565 /// This represents the '#pragma omp tile' loop transformation directive. 5566 class OMPTileDirective final : public OMPLoopTransformationDirective { 5567 friend class ASTStmtReader; 5568 friend class OMPExecutableDirective; 5569 5570 /// Default list of offsets. 5571 enum { 5572 PreInitsOffset = 0, 5573 TransformedStmtOffset, 5574 }; 5575 OMPTileDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumLoops)5576 explicit OMPTileDirective(SourceLocation StartLoc, SourceLocation EndLoc, 5577 unsigned NumLoops) 5578 : OMPLoopTransformationDirective(OMPTileDirectiveClass, 5579 llvm::omp::OMPD_tile, StartLoc, EndLoc, 5580 NumLoops) { 5581 setNumGeneratedLoops(3 * NumLoops); 5582 } 5583 setPreInits(Stmt * PreInits)5584 void setPreInits(Stmt *PreInits) { 5585 Data->getChildren()[PreInitsOffset] = PreInits; 5586 } 5587 setTransformedStmt(Stmt * S)5588 void setTransformedStmt(Stmt *S) { 5589 Data->getChildren()[TransformedStmtOffset] = S; 5590 } 5591 5592 public: 5593 /// Create a new AST node representation for '#pragma omp tile'. 5594 /// 5595 /// \param C Context of the AST. 5596 /// \param StartLoc Location of the introducer (e.g. the 'omp' token). 5597 /// \param EndLoc Location of the directive's end (e.g. the tok::eod). 5598 /// \param Clauses The directive's clauses. 5599 /// \param NumLoops Number of associated loops (number of items in the 5600 /// 'sizes' clause). 5601 /// \param AssociatedStmt The outermost associated loop. 5602 /// \param TransformedStmt The loop nest after tiling, or nullptr in 5603 /// dependent contexts. 5604 /// \param PreInits Helper preinits statements for the loop nest. 5605 static OMPTileDirective *Create(const ASTContext &C, SourceLocation StartLoc, 5606 SourceLocation EndLoc, 5607 ArrayRef<OMPClause *> Clauses, 5608 unsigned NumLoops, Stmt *AssociatedStmt, 5609 Stmt *TransformedStmt, Stmt *PreInits); 5610 5611 /// Build an empty '#pragma omp tile' AST node for deserialization. 5612 /// 5613 /// \param C Context of the AST. 5614 /// \param NumClauses Number of clauses to allocate. 5615 /// \param NumLoops Number of associated loops to allocate. 5616 static OMPTileDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 5617 unsigned NumLoops); 5618 5619 /// Gets/sets the associated loops after tiling. 5620 /// 5621 /// This is in de-sugared format stored as a CompoundStmt. 5622 /// 5623 /// \code 5624 /// for (...) 5625 /// ... 5626 /// \endcode 5627 /// 5628 /// Note that if the generated loops a become associated loops of another 5629 /// directive, they may need to be hoisted before them. getTransformedStmt()5630 Stmt *getTransformedStmt() const { 5631 return Data->getChildren()[TransformedStmtOffset]; 5632 } 5633 5634 /// Return preinits statement. getPreInits()5635 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } 5636 classof(const Stmt * T)5637 static bool classof(const Stmt *T) { 5638 return T->getStmtClass() == OMPTileDirectiveClass; 5639 } 5640 }; 5641 5642 /// This represents the '#pragma omp unroll' loop transformation directive. 5643 /// 5644 /// \code 5645 /// #pragma omp unroll 5646 /// for (int i = 0; i < 64; ++i) 5647 /// \endcode 5648 class OMPUnrollDirective final : public OMPLoopTransformationDirective { 5649 friend class ASTStmtReader; 5650 friend class OMPExecutableDirective; 5651 5652 /// Default list of offsets. 5653 enum { 5654 PreInitsOffset = 0, 5655 TransformedStmtOffset, 5656 }; 5657 OMPUnrollDirective(SourceLocation StartLoc,SourceLocation EndLoc)5658 explicit OMPUnrollDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5659 : OMPLoopTransformationDirective(OMPUnrollDirectiveClass, 5660 llvm::omp::OMPD_unroll, StartLoc, EndLoc, 5661 1) {} 5662 5663 /// Set the pre-init statements. setPreInits(Stmt * PreInits)5664 void setPreInits(Stmt *PreInits) { 5665 Data->getChildren()[PreInitsOffset] = PreInits; 5666 } 5667 5668 /// Set the de-sugared statement. setTransformedStmt(Stmt * S)5669 void setTransformedStmt(Stmt *S) { 5670 Data->getChildren()[TransformedStmtOffset] = S; 5671 } 5672 5673 public: 5674 /// Create a new AST node representation for '#pragma omp unroll'. 5675 /// 5676 /// \param C Context of the AST. 5677 /// \param StartLoc Location of the introducer (e.g. the 'omp' token). 5678 /// \param EndLoc Location of the directive's end (e.g. the tok::eod). 5679 /// \param Clauses The directive's clauses. 5680 /// \param AssociatedStmt The outermost associated loop. 5681 /// \param TransformedStmt The loop nest after tiling, or nullptr in 5682 /// dependent contexts. 5683 /// \param PreInits Helper preinits statements for the loop nest. 5684 static OMPUnrollDirective * 5685 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5686 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, 5687 unsigned NumGeneratedLoops, Stmt *TransformedStmt, Stmt *PreInits); 5688 5689 /// Build an empty '#pragma omp unroll' AST node for deserialization. 5690 /// 5691 /// \param C Context of the AST. 5692 /// \param NumClauses Number of clauses to allocate. 5693 static OMPUnrollDirective *CreateEmpty(const ASTContext &C, 5694 unsigned NumClauses); 5695 5696 /// Get the de-sugared associated loops after unrolling. 5697 /// 5698 /// This is only used if the unrolled loop becomes an associated loop of 5699 /// another directive, otherwise the loop is emitted directly using loop 5700 /// transformation metadata. When the unrolled loop cannot be used by another 5701 /// directive (e.g. because of the full clause), the transformed stmt can also 5702 /// be nullptr. getTransformedStmt()5703 Stmt *getTransformedStmt() const { 5704 return Data->getChildren()[TransformedStmtOffset]; 5705 } 5706 5707 /// Return the pre-init statements. getPreInits()5708 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } 5709 classof(const Stmt * T)5710 static bool classof(const Stmt *T) { 5711 return T->getStmtClass() == OMPUnrollDirectiveClass; 5712 } 5713 }; 5714 5715 /// Represents the '#pragma omp reverse' loop transformation directive. 5716 /// 5717 /// \code 5718 /// #pragma omp reverse 5719 /// for (int i = 0; i < n; ++i) 5720 /// ... 5721 /// \endcode 5722 class OMPReverseDirective final : public OMPLoopTransformationDirective { 5723 friend class ASTStmtReader; 5724 friend class OMPExecutableDirective; 5725 5726 /// Offsets of child members. 5727 enum { 5728 PreInitsOffset = 0, 5729 TransformedStmtOffset, 5730 }; 5731 OMPReverseDirective(SourceLocation StartLoc,SourceLocation EndLoc)5732 explicit OMPReverseDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5733 : OMPLoopTransformationDirective(OMPReverseDirectiveClass, 5734 llvm::omp::OMPD_reverse, StartLoc, 5735 EndLoc, 1) {} 5736 setPreInits(Stmt * PreInits)5737 void setPreInits(Stmt *PreInits) { 5738 Data->getChildren()[PreInitsOffset] = PreInits; 5739 } 5740 setTransformedStmt(Stmt * S)5741 void setTransformedStmt(Stmt *S) { 5742 Data->getChildren()[TransformedStmtOffset] = S; 5743 } 5744 5745 public: 5746 /// Create a new AST node representation for '#pragma omp reverse'. 5747 /// 5748 /// \param C Context of the AST. 5749 /// \param StartLoc Location of the introducer (e.g. the 'omp' token). 5750 /// \param EndLoc Location of the directive's end (e.g. the tok::eod). 5751 /// \param AssociatedStmt The outermost associated loop. 5752 /// \param TransformedStmt The loop nest after tiling, or nullptr in 5753 /// dependent contexts. 5754 /// \param PreInits Helper preinits statements for the loop nest. 5755 static OMPReverseDirective * 5756 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5757 Stmt *AssociatedStmt, Stmt *TransformedStmt, Stmt *PreInits); 5758 5759 /// Build an empty '#pragma omp reverse' AST node for deserialization. 5760 /// 5761 /// \param C Context of the AST. 5762 /// \param NumClauses Number of clauses to allocate. 5763 static OMPReverseDirective *CreateEmpty(const ASTContext &C); 5764 5765 /// Gets/sets the associated loops after the transformation, i.e. after 5766 /// de-sugaring. getTransformedStmt()5767 Stmt *getTransformedStmt() const { 5768 return Data->getChildren()[TransformedStmtOffset]; 5769 } 5770 5771 /// Return preinits statement. getPreInits()5772 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } 5773 classof(const Stmt * T)5774 static bool classof(const Stmt *T) { 5775 return T->getStmtClass() == OMPReverseDirectiveClass; 5776 } 5777 }; 5778 5779 /// Represents the '#pragma omp interchange' loop transformation directive. 5780 /// 5781 /// \code{c} 5782 /// #pragma omp interchange 5783 /// for (int i = 0; i < m; ++i) 5784 /// for (int j = 0; j < n; ++j) 5785 /// .. 5786 /// \endcode 5787 class OMPInterchangeDirective final : public OMPLoopTransformationDirective { 5788 friend class ASTStmtReader; 5789 friend class OMPExecutableDirective; 5790 5791 /// Offsets of child members. 5792 enum { 5793 PreInitsOffset = 0, 5794 TransformedStmtOffset, 5795 }; 5796 OMPInterchangeDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumLoops)5797 explicit OMPInterchangeDirective(SourceLocation StartLoc, 5798 SourceLocation EndLoc, unsigned NumLoops) 5799 : OMPLoopTransformationDirective(OMPInterchangeDirectiveClass, 5800 llvm::omp::OMPD_interchange, StartLoc, 5801 EndLoc, NumLoops) { 5802 setNumGeneratedLoops(3 * NumLoops); 5803 } 5804 setPreInits(Stmt * PreInits)5805 void setPreInits(Stmt *PreInits) { 5806 Data->getChildren()[PreInitsOffset] = PreInits; 5807 } 5808 setTransformedStmt(Stmt * S)5809 void setTransformedStmt(Stmt *S) { 5810 Data->getChildren()[TransformedStmtOffset] = S; 5811 } 5812 5813 public: 5814 /// Create a new AST node representation for '#pragma omp interchange'. 5815 /// 5816 /// \param C Context of the AST. 5817 /// \param StartLoc Location of the introducer (e.g. the 'omp' token). 5818 /// \param EndLoc Location of the directive's end (e.g. the tok::eod). 5819 /// \param Clauses The directive's clauses. 5820 /// \param NumLoops Number of affected loops 5821 /// (number of items in the 'permutation' clause if present). 5822 /// \param AssociatedStmt The outermost associated loop. 5823 /// \param TransformedStmt The loop nest after tiling, or nullptr in 5824 /// dependent contexts. 5825 /// \param PreInits Helper preinits statements for the loop nest. 5826 static OMPInterchangeDirective * 5827 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5828 ArrayRef<OMPClause *> Clauses, unsigned NumLoops, Stmt *AssociatedStmt, 5829 Stmt *TransformedStmt, Stmt *PreInits); 5830 5831 /// Build an empty '#pragma omp interchange' AST node for deserialization. 5832 /// 5833 /// \param C Context of the AST. 5834 /// \param NumClauses Number of clauses to allocate. 5835 /// \param NumLoops Number of associated loops to allocate. 5836 static OMPInterchangeDirective * 5837 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned NumLoops); 5838 5839 /// Gets the associated loops after the transformation. This is the de-sugared 5840 /// replacement or nullptr in dependent contexts. getTransformedStmt()5841 Stmt *getTransformedStmt() const { 5842 return Data->getChildren()[TransformedStmtOffset]; 5843 } 5844 5845 /// Return preinits statement. getPreInits()5846 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } 5847 classof(const Stmt * T)5848 static bool classof(const Stmt *T) { 5849 return T->getStmtClass() == OMPInterchangeDirectiveClass; 5850 } 5851 }; 5852 5853 /// This represents '#pragma omp scan' directive. 5854 /// 5855 /// \code 5856 /// #pragma omp scan inclusive(a) 5857 /// \endcode 5858 /// In this example directive '#pragma omp scan' has clause 'inclusive' with 5859 /// list item 'a'. 5860 class OMPScanDirective final : public OMPExecutableDirective { 5861 friend class ASTStmtReader; 5862 friend class OMPExecutableDirective; 5863 /// Build directive with the given start and end location. 5864 /// 5865 /// \param StartLoc Starting location of the directive kind. 5866 /// \param EndLoc Ending location of the directive. 5867 /// OMPScanDirective(SourceLocation StartLoc,SourceLocation EndLoc)5868 OMPScanDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5869 : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan, 5870 StartLoc, EndLoc) {} 5871 5872 /// Build an empty directive. 5873 /// OMPScanDirective()5874 explicit OMPScanDirective() 5875 : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan, 5876 SourceLocation(), SourceLocation()) {} 5877 5878 public: 5879 /// Creates directive with a list of \a Clauses. 5880 /// 5881 /// \param C AST context. 5882 /// \param StartLoc Starting location of the directive kind. 5883 /// \param EndLoc Ending Location of the directive. 5884 /// \param Clauses List of clauses (only single OMPFlushClause clause is 5885 /// allowed). 5886 /// 5887 static OMPScanDirective *Create(const ASTContext &C, SourceLocation StartLoc, 5888 SourceLocation EndLoc, 5889 ArrayRef<OMPClause *> Clauses); 5890 5891 /// Creates an empty directive with the place for \a NumClauses 5892 /// clauses. 5893 /// 5894 /// \param C AST context. 5895 /// \param NumClauses Number of clauses. 5896 /// 5897 static OMPScanDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 5898 EmptyShell); 5899 classof(const Stmt * T)5900 static bool classof(const Stmt *T) { 5901 return T->getStmtClass() == OMPScanDirectiveClass; 5902 } 5903 }; 5904 5905 /// This represents '#pragma omp interop' directive. 5906 /// 5907 /// \code 5908 /// #pragma omp interop init(target:obj) device(x) depend(inout:y) nowait 5909 /// \endcode 5910 /// In this example directive '#pragma omp interop' has 5911 /// clauses 'init', 'device', 'depend' and 'nowait'. 5912 /// 5913 class OMPInteropDirective final : public OMPExecutableDirective { 5914 friend class ASTStmtReader; 5915 friend class OMPExecutableDirective; 5916 5917 /// Build directive with the given start and end location. 5918 /// 5919 /// \param StartLoc Starting location of the directive. 5920 /// \param EndLoc Ending location of the directive. 5921 /// OMPInteropDirective(SourceLocation StartLoc,SourceLocation EndLoc)5922 OMPInteropDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5923 : OMPExecutableDirective(OMPInteropDirectiveClass, 5924 llvm::omp::OMPD_interop, StartLoc, EndLoc) {} 5925 5926 /// Build an empty directive. 5927 /// OMPInteropDirective()5928 explicit OMPInteropDirective() 5929 : OMPExecutableDirective(OMPInteropDirectiveClass, 5930 llvm::omp::OMPD_interop, SourceLocation(), 5931 SourceLocation()) {} 5932 5933 public: 5934 /// Creates directive. 5935 /// 5936 /// \param C AST context. 5937 /// \param StartLoc Starting location of the directive. 5938 /// \param EndLoc Ending Location of the directive. 5939 /// \param Clauses The directive's clauses. 5940 /// 5941 static OMPInteropDirective *Create(const ASTContext &C, 5942 SourceLocation StartLoc, 5943 SourceLocation EndLoc, 5944 ArrayRef<OMPClause *> Clauses); 5945 5946 /// Creates an empty directive. 5947 /// 5948 /// \param C AST context. 5949 /// 5950 static OMPInteropDirective *CreateEmpty(const ASTContext &C, 5951 unsigned NumClauses, EmptyShell); 5952 classof(const Stmt * T)5953 static bool classof(const Stmt *T) { 5954 return T->getStmtClass() == OMPInteropDirectiveClass; 5955 } 5956 }; 5957 5958 /// This represents '#pragma omp dispatch' directive. 5959 /// 5960 /// \code 5961 /// #pragma omp dispatch device(dnum) 5962 /// \endcode 5963 /// This example shows a directive '#pragma omp dispatch' with a 5964 /// device clause with variable 'dnum'. 5965 /// 5966 class OMPDispatchDirective final : public OMPExecutableDirective { 5967 friend class ASTStmtReader; 5968 friend class OMPExecutableDirective; 5969 5970 /// The location of the target-call. 5971 SourceLocation TargetCallLoc; 5972 5973 /// Set the location of the target-call. setTargetCallLoc(SourceLocation Loc)5974 void setTargetCallLoc(SourceLocation Loc) { TargetCallLoc = Loc; } 5975 5976 /// Build directive with the given start and end location. 5977 /// 5978 /// \param StartLoc Starting location of the directive kind. 5979 /// \param EndLoc Ending location of the directive. 5980 /// OMPDispatchDirective(SourceLocation StartLoc,SourceLocation EndLoc)5981 OMPDispatchDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5982 : OMPExecutableDirective(OMPDispatchDirectiveClass, 5983 llvm::omp::OMPD_dispatch, StartLoc, EndLoc) {} 5984 5985 /// Build an empty directive. 5986 /// OMPDispatchDirective()5987 explicit OMPDispatchDirective() 5988 : OMPExecutableDirective(OMPDispatchDirectiveClass, 5989 llvm::omp::OMPD_dispatch, SourceLocation(), 5990 SourceLocation()) {} 5991 5992 public: 5993 /// Creates directive with a list of \a Clauses. 5994 /// 5995 /// \param C AST context. 5996 /// \param StartLoc Starting location of the directive kind. 5997 /// \param EndLoc Ending Location of the directive. 5998 /// \param Clauses List of clauses. 5999 /// \param AssociatedStmt Statement, associated with the directive. 6000 /// \param TargetCallLoc Location of the target-call. 6001 /// 6002 static OMPDispatchDirective * 6003 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 6004 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, 6005 SourceLocation TargetCallLoc); 6006 6007 /// Creates an empty directive with the place for \a NumClauses 6008 /// clauses. 6009 /// 6010 /// \param C AST context. 6011 /// \param NumClauses Number of clauses. 6012 /// 6013 static OMPDispatchDirective *CreateEmpty(const ASTContext &C, 6014 unsigned NumClauses, EmptyShell); 6015 6016 /// Return location of target-call. getTargetCallLoc()6017 SourceLocation getTargetCallLoc() const { return TargetCallLoc; } 6018 classof(const Stmt * T)6019 static bool classof(const Stmt *T) { 6020 return T->getStmtClass() == OMPDispatchDirectiveClass; 6021 } 6022 }; 6023 6024 /// This represents '#pragma omp masked' directive. 6025 /// \code 6026 /// #pragma omp masked filter(tid) 6027 /// \endcode 6028 /// This example shows a directive '#pragma omp masked' with a filter clause 6029 /// with variable 'tid'. 6030 /// 6031 class OMPMaskedDirective final : public OMPExecutableDirective { 6032 friend class ASTStmtReader; 6033 friend class OMPExecutableDirective; 6034 6035 /// Build directive with the given start and end location. 6036 /// 6037 /// \param StartLoc Starting location of the directive kind. 6038 /// \param EndLoc Ending location of the directive. 6039 /// OMPMaskedDirective(SourceLocation StartLoc,SourceLocation EndLoc)6040 OMPMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc) 6041 : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked, 6042 StartLoc, EndLoc) {} 6043 6044 /// Build an empty directive. 6045 /// OMPMaskedDirective()6046 explicit OMPMaskedDirective() 6047 : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked, 6048 SourceLocation(), SourceLocation()) {} 6049 6050 public: 6051 /// Creates directive. 6052 /// 6053 /// \param C AST context. 6054 /// \param StartLoc Starting location of the directive kind. 6055 /// \param EndLoc Ending Location of the directive. 6056 /// \param AssociatedStmt Statement, associated with the directive. 6057 /// 6058 static OMPMaskedDirective * 6059 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 6060 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 6061 6062 /// Creates an empty directive. 6063 /// 6064 /// \param C AST context. 6065 /// 6066 static OMPMaskedDirective *CreateEmpty(const ASTContext &C, 6067 unsigned NumClauses, EmptyShell); 6068 classof(const Stmt * T)6069 static bool classof(const Stmt *T) { 6070 return T->getStmtClass() == OMPMaskedDirectiveClass; 6071 } 6072 }; 6073 6074 /// This represents '#pragma omp metadirective' directive. 6075 /// 6076 /// \code 6077 /// #pragma omp metadirective when(user={condition(N>10)}: parallel for) 6078 /// \endcode 6079 /// In this example directive '#pragma omp metadirective' has clauses 'when' 6080 /// with a dynamic user condition to check if a variable 'N > 10' 6081 /// 6082 class OMPMetaDirective final : public OMPExecutableDirective { 6083 friend class ASTStmtReader; 6084 friend class OMPExecutableDirective; 6085 Stmt *IfStmt; 6086 OMPMetaDirective(SourceLocation StartLoc,SourceLocation EndLoc)6087 OMPMetaDirective(SourceLocation StartLoc, SourceLocation EndLoc) 6088 : OMPExecutableDirective(OMPMetaDirectiveClass, 6089 llvm::omp::OMPD_metadirective, StartLoc, 6090 EndLoc) {} OMPMetaDirective()6091 explicit OMPMetaDirective() 6092 : OMPExecutableDirective(OMPMetaDirectiveClass, 6093 llvm::omp::OMPD_metadirective, SourceLocation(), 6094 SourceLocation()) {} 6095 setIfStmt(Stmt * S)6096 void setIfStmt(Stmt *S) { IfStmt = S; } 6097 6098 public: 6099 static OMPMetaDirective *Create(const ASTContext &C, SourceLocation StartLoc, 6100 SourceLocation EndLoc, 6101 ArrayRef<OMPClause *> Clauses, 6102 Stmt *AssociatedStmt, Stmt *IfStmt); 6103 static OMPMetaDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 6104 EmptyShell); getIfStmt()6105 Stmt *getIfStmt() const { return IfStmt; } 6106 classof(const Stmt * T)6107 static bool classof(const Stmt *T) { 6108 return T->getStmtClass() == OMPMetaDirectiveClass; 6109 } 6110 }; 6111 6112 /// This represents '#pragma omp loop' directive. 6113 /// 6114 /// \code 6115 /// #pragma omp loop private(a,b) binding(parallel) order(concurrent) 6116 /// \endcode 6117 /// In this example directive '#pragma omp loop' has 6118 /// clauses 'private' with the variables 'a' and 'b', 'binding' with 6119 /// modifier 'parallel' and 'order(concurrent). 6120 /// 6121 class OMPGenericLoopDirective final : public OMPLoopDirective { 6122 friend class ASTStmtReader; 6123 friend class OMPExecutableDirective; 6124 /// Build directive with the given start and end location. 6125 /// 6126 /// \param StartLoc Starting location of the directive kind. 6127 /// \param EndLoc Ending location of the directive. 6128 /// \param CollapsedNum Number of collapsed nested loops. 6129 /// OMPGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)6130 OMPGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 6131 unsigned CollapsedNum) 6132 : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop, 6133 StartLoc, EndLoc, CollapsedNum) {} 6134 6135 /// Build an empty directive. 6136 /// 6137 /// \param CollapsedNum Number of collapsed nested loops. 6138 /// OMPGenericLoopDirective(unsigned CollapsedNum)6139 explicit OMPGenericLoopDirective(unsigned CollapsedNum) 6140 : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop, 6141 SourceLocation(), SourceLocation(), CollapsedNum) {} 6142 6143 public: 6144 /// Creates directive with a list of \p Clauses. 6145 /// 6146 /// \param C AST context. 6147 /// \param StartLoc Starting location of the directive kind. 6148 /// \param EndLoc Ending Location of the directive. 6149 /// \param CollapsedNum Number of collapsed loops. 6150 /// \param Clauses List of clauses. 6151 /// \param AssociatedStmt Statement, associated with the directive. 6152 /// \param Exprs Helper expressions for CodeGen. 6153 /// 6154 static OMPGenericLoopDirective * 6155 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 6156 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 6157 Stmt *AssociatedStmt, const HelperExprs &Exprs); 6158 6159 /// Creates an empty directive with a place for \a NumClauses clauses. 6160 /// 6161 /// \param C AST context. 6162 /// \param NumClauses Number of clauses. 6163 /// \param CollapsedNum Number of collapsed nested loops. 6164 /// 6165 static OMPGenericLoopDirective *CreateEmpty(const ASTContext &C, 6166 unsigned NumClauses, 6167 unsigned CollapsedNum, 6168 EmptyShell); 6169 classof(const Stmt * T)6170 static bool classof(const Stmt *T) { 6171 return T->getStmtClass() == OMPGenericLoopDirectiveClass; 6172 } 6173 }; 6174 6175 /// This represents '#pragma omp teams loop' directive. 6176 /// 6177 /// \code 6178 /// #pragma omp teams loop private(a,b) order(concurrent) 6179 /// \endcode 6180 /// In this example directive '#pragma omp teams loop' has 6181 /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). 6182 /// 6183 class OMPTeamsGenericLoopDirective final : public OMPLoopDirective { 6184 friend class ASTStmtReader; 6185 friend class OMPExecutableDirective; 6186 /// Build directive with the given start and end location. 6187 /// 6188 /// \param StartLoc Starting location of the directive kind. 6189 /// \param EndLoc Ending location of the directive. 6190 /// \param CollapsedNum Number of collapsed nested loops. 6191 /// OMPTeamsGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)6192 OMPTeamsGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 6193 unsigned CollapsedNum) 6194 : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass, 6195 llvm::omp::OMPD_teams_loop, StartLoc, EndLoc, 6196 CollapsedNum) {} 6197 6198 /// Build an empty directive. 6199 /// 6200 /// \param CollapsedNum Number of collapsed nested loops. 6201 /// OMPTeamsGenericLoopDirective(unsigned CollapsedNum)6202 explicit OMPTeamsGenericLoopDirective(unsigned CollapsedNum) 6203 : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass, 6204 llvm::omp::OMPD_teams_loop, SourceLocation(), 6205 SourceLocation(), CollapsedNum) {} 6206 6207 public: 6208 /// Creates directive with a list of \p Clauses. 6209 /// 6210 /// \param C AST context. 6211 /// \param StartLoc Starting location of the directive kind. 6212 /// \param EndLoc Ending Location of the directive. 6213 /// \param CollapsedNum Number of collapsed loops. 6214 /// \param Clauses List of clauses. 6215 /// \param AssociatedStmt Statement, associated with the directive. 6216 /// \param Exprs Helper expressions for CodeGen. 6217 /// 6218 static OMPTeamsGenericLoopDirective * 6219 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 6220 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 6221 Stmt *AssociatedStmt, const HelperExprs &Exprs); 6222 6223 /// Creates an empty directive with the place 6224 /// for \a NumClauses clauses. 6225 /// 6226 /// \param C AST context. 6227 /// \param CollapsedNum Number of collapsed nested loops. 6228 /// \param NumClauses Number of clauses. 6229 /// 6230 static OMPTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C, 6231 unsigned NumClauses, 6232 unsigned CollapsedNum, 6233 EmptyShell); 6234 classof(const Stmt * T)6235 static bool classof(const Stmt *T) { 6236 return T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass; 6237 } 6238 }; 6239 6240 /// This represents '#pragma omp target teams loop' directive. 6241 /// 6242 /// \code 6243 /// #pragma omp target teams loop private(a,b) order(concurrent) 6244 /// \endcode 6245 /// In this example directive '#pragma omp target teams loop' has 6246 /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). 6247 /// 6248 class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective { 6249 friend class ASTStmtReader; 6250 friend class OMPExecutableDirective; 6251 /// true if loop directive's associated loop can be a parallel for. 6252 bool CanBeParallelFor = false; 6253 /// Build directive with the given start and end location. 6254 /// 6255 /// \param StartLoc Starting location of the directive kind. 6256 /// \param EndLoc Ending location of the directive. 6257 /// \param CollapsedNum Number of collapsed nested loops. 6258 /// OMPTargetTeamsGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)6259 OMPTargetTeamsGenericLoopDirective(SourceLocation StartLoc, 6260 SourceLocation EndLoc, 6261 unsigned CollapsedNum) 6262 : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass, 6263 llvm::omp::OMPD_target_teams_loop, StartLoc, EndLoc, 6264 CollapsedNum) {} 6265 6266 /// Build an empty directive. 6267 /// 6268 /// \param CollapsedNum Number of collapsed nested loops. 6269 /// OMPTargetTeamsGenericLoopDirective(unsigned CollapsedNum)6270 explicit OMPTargetTeamsGenericLoopDirective(unsigned CollapsedNum) 6271 : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass, 6272 llvm::omp::OMPD_target_teams_loop, SourceLocation(), 6273 SourceLocation(), CollapsedNum) {} 6274 6275 /// Set whether associated loop can be a parallel for. setCanBeParallelFor(bool ParFor)6276 void setCanBeParallelFor(bool ParFor) { CanBeParallelFor = ParFor; } 6277 6278 public: 6279 /// Creates directive with a list of \p Clauses. 6280 /// 6281 /// \param C AST context. 6282 /// \param StartLoc Starting location of the directive kind. 6283 /// \param EndLoc Ending Location of the directive. 6284 /// \param CollapsedNum Number of collapsed loops. 6285 /// \param Clauses List of clauses. 6286 /// \param AssociatedStmt Statement, associated with the directive. 6287 /// \param Exprs Helper expressions for CodeGen. 6288 /// 6289 static OMPTargetTeamsGenericLoopDirective * 6290 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 6291 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 6292 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool CanBeParallelFor); 6293 6294 /// Creates an empty directive with the place 6295 /// for \a NumClauses clauses. 6296 /// 6297 /// \param C AST context. 6298 /// \param CollapsedNum Number of collapsed nested loops. 6299 /// \param NumClauses Number of clauses. 6300 /// 6301 static OMPTargetTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C, 6302 unsigned NumClauses, 6303 unsigned CollapsedNum, 6304 EmptyShell); 6305 6306 /// Return true if current loop directive's associated loop can be a 6307 /// parallel for. canBeParallelFor()6308 bool canBeParallelFor() const { return CanBeParallelFor; } 6309 classof(const Stmt * T)6310 static bool classof(const Stmt *T) { 6311 return T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass; 6312 } 6313 }; 6314 6315 /// This represents '#pragma omp parallel loop' directive. 6316 /// 6317 /// \code 6318 /// #pragma omp parallel loop private(a,b) order(concurrent) 6319 /// \endcode 6320 /// In this example directive '#pragma omp parallel loop' has 6321 /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). 6322 /// 6323 class OMPParallelGenericLoopDirective final : public OMPLoopDirective { 6324 friend class ASTStmtReader; 6325 friend class OMPExecutableDirective; 6326 /// Build directive with the given start and end location. 6327 /// 6328 /// \param StartLoc Starting location of the directive kind. 6329 /// \param EndLoc Ending location of the directive. 6330 /// \param CollapsedNum Number of collapsed nested loops. 6331 /// OMPParallelGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)6332 OMPParallelGenericLoopDirective(SourceLocation StartLoc, 6333 SourceLocation EndLoc, unsigned CollapsedNum) 6334 : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass, 6335 llvm::omp::OMPD_parallel_loop, StartLoc, EndLoc, 6336 CollapsedNum) {} 6337 6338 /// Build an empty directive. 6339 /// 6340 /// \param CollapsedNum Number of collapsed nested loops. 6341 /// OMPParallelGenericLoopDirective(unsigned CollapsedNum)6342 explicit OMPParallelGenericLoopDirective(unsigned CollapsedNum) 6343 : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass, 6344 llvm::omp::OMPD_parallel_loop, SourceLocation(), 6345 SourceLocation(), CollapsedNum) {} 6346 6347 public: 6348 /// Creates directive with a list of \p Clauses. 6349 /// 6350 /// \param C AST context. 6351 /// \param StartLoc Starting location of the directive kind. 6352 /// \param EndLoc Ending Location of the directive. 6353 /// \param CollapsedNum Number of collapsed loops. 6354 /// \param Clauses List of clauses. 6355 /// \param AssociatedStmt Statement, associated with the directive. 6356 /// \param Exprs Helper expressions for CodeGen. 6357 /// 6358 static OMPParallelGenericLoopDirective * 6359 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 6360 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 6361 Stmt *AssociatedStmt, const HelperExprs &Exprs); 6362 6363 /// Creates an empty directive with the place 6364 /// for \a NumClauses clauses. 6365 /// 6366 /// \param C AST context. 6367 /// \param CollapsedNum Number of collapsed nested loops. 6368 /// \param NumClauses Number of clauses. 6369 /// 6370 static OMPParallelGenericLoopDirective *CreateEmpty(const ASTContext &C, 6371 unsigned NumClauses, 6372 unsigned CollapsedNum, 6373 EmptyShell); 6374 classof(const Stmt * T)6375 static bool classof(const Stmt *T) { 6376 return T->getStmtClass() == OMPParallelGenericLoopDirectiveClass; 6377 } 6378 }; 6379 6380 /// This represents '#pragma omp target parallel loop' directive. 6381 /// 6382 /// \code 6383 /// #pragma omp target parallel loop private(a,b) order(concurrent) 6384 /// \endcode 6385 /// In this example directive '#pragma omp target parallel loop' has 6386 /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). 6387 /// 6388 class OMPTargetParallelGenericLoopDirective final : public OMPLoopDirective { 6389 friend class ASTStmtReader; 6390 friend class OMPExecutableDirective; 6391 /// Build directive with the given start and end location. 6392 /// 6393 /// \param StartLoc Starting location of the directive kind. 6394 /// \param EndLoc Ending location of the directive. 6395 /// \param CollapsedNum Number of collapsed nested loops. 6396 /// OMPTargetParallelGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)6397 OMPTargetParallelGenericLoopDirective(SourceLocation StartLoc, 6398 SourceLocation EndLoc, 6399 unsigned CollapsedNum) 6400 : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass, 6401 llvm::omp::OMPD_target_parallel_loop, StartLoc, EndLoc, 6402 CollapsedNum) {} 6403 6404 /// Build an empty directive. 6405 /// 6406 /// \param CollapsedNum Number of collapsed nested loops. 6407 /// OMPTargetParallelGenericLoopDirective(unsigned CollapsedNum)6408 explicit OMPTargetParallelGenericLoopDirective(unsigned CollapsedNum) 6409 : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass, 6410 llvm::omp::OMPD_target_parallel_loop, SourceLocation(), 6411 SourceLocation(), CollapsedNum) {} 6412 6413 public: 6414 /// Creates directive with a list of \p Clauses. 6415 /// 6416 /// \param C AST context. 6417 /// \param StartLoc Starting location of the directive kind. 6418 /// \param EndLoc Ending Location of the directive. 6419 /// \param CollapsedNum Number of collapsed loops. 6420 /// \param Clauses List of clauses. 6421 /// \param AssociatedStmt Statement, associated with the directive. 6422 /// \param Exprs Helper expressions for CodeGen. 6423 /// 6424 static OMPTargetParallelGenericLoopDirective * 6425 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 6426 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 6427 Stmt *AssociatedStmt, const HelperExprs &Exprs); 6428 6429 /// Creates an empty directive with the place 6430 /// for \a NumClauses clauses. 6431 /// 6432 /// \param C AST context. 6433 /// \param CollapsedNum Number of collapsed nested loops. 6434 /// \param NumClauses Number of clauses. 6435 /// 6436 static OMPTargetParallelGenericLoopDirective * 6437 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 6438 EmptyShell); 6439 classof(const Stmt * T)6440 static bool classof(const Stmt *T) { 6441 return T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass; 6442 } 6443 }; 6444 6445 /// This represents '#pragma omp error' directive. 6446 /// 6447 /// \code 6448 /// #pragma omp error 6449 /// \endcode 6450 class OMPErrorDirective final : public OMPExecutableDirective { 6451 friend class ASTStmtReader; 6452 friend class OMPExecutableDirective; 6453 /// Build directive with the given start and end location. 6454 /// 6455 /// \param StartLoc Starting location of the directive kind. 6456 /// \param EndLoc Ending location of the directive. 6457 /// OMPErrorDirective(SourceLocation StartLoc,SourceLocation EndLoc)6458 OMPErrorDirective(SourceLocation StartLoc, SourceLocation EndLoc) 6459 : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error, 6460 StartLoc, EndLoc) {} 6461 /// Build an empty directive. 6462 /// OMPErrorDirective()6463 explicit OMPErrorDirective() 6464 : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error, 6465 SourceLocation(), SourceLocation()) {} 6466 6467 public: 6468 /// 6469 /// \param C AST context. 6470 /// \param StartLoc Starting location of the directive kind. 6471 /// \param EndLoc Ending Location of the directive. 6472 /// \param Clauses List of clauses. 6473 /// 6474 static OMPErrorDirective *Create(const ASTContext &C, SourceLocation StartLoc, 6475 SourceLocation EndLoc, 6476 ArrayRef<OMPClause *> Clauses); 6477 6478 /// Creates an empty directive. 6479 /// 6480 /// \param C AST context. 6481 /// 6482 static OMPErrorDirective *CreateEmpty(const ASTContext &C, 6483 unsigned NumClauses, EmptyShell); 6484 classof(const Stmt * T)6485 static bool classof(const Stmt *T) { 6486 return T->getStmtClass() == OMPErrorDirectiveClass; 6487 } 6488 }; 6489 } // end namespace clang 6490 6491 #endif 6492