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