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