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 doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops, 893 unsigned NumLoops, 894 llvm::function_ref<bool(unsigned, Stmt *)> Callback, 895 llvm::function_ref<void(OMPLoopBasedDirective *)> 896 OnTransformationCallback); 897 static bool 898 doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops, 899 unsigned NumLoops, 900 llvm::function_ref<bool(unsigned, const Stmt *)> Callback, 901 llvm::function_ref<void(const OMPLoopBasedDirective *)> 902 OnTransformationCallback) { 903 auto &&NewCallback = [Callback](unsigned Cnt, Stmt *CurStmt) { 904 return Callback(Cnt, CurStmt); 905 }; 906 auto &&NewTransformCb = 907 [OnTransformationCallback](OMPLoopBasedDirective *A) { 908 OnTransformationCallback(A); 909 }; 910 return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops, 911 NumLoops, NewCallback, NewTransformCb); 912 } 913 914 /// Calls the specified callback function for all the loops in \p CurStmt, 915 /// from the outermost to the innermost. 916 static bool 917 doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops, 918 unsigned NumLoops, 919 llvm::function_ref<bool(unsigned, Stmt *)> Callback) { 920 auto &&TransformCb = [](OMPLoopBasedDirective *) {}; 921 return doForAllLoops(CurStmt, TryImperfectlyNestedLoops, NumLoops, Callback, 922 TransformCb); 923 } 924 static bool 925 doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops, 926 unsigned NumLoops, 927 llvm::function_ref<bool(unsigned, const Stmt *)> Callback) { 928 auto &&NewCallback = [Callback](unsigned Cnt, const Stmt *CurStmt) { 929 return Callback(Cnt, CurStmt); 930 }; 931 return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops, 932 NumLoops, NewCallback); 933 } 934 935 /// Calls the specified callback function for all the loop bodies in \p 936 /// CurStmt, from the outermost loop to the innermost. 937 static void doForAllLoopsBodies( 938 Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops, 939 llvm::function_ref<void(unsigned, Stmt *, Stmt *)> Callback); 940 static void doForAllLoopsBodies( 941 const Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops, 942 llvm::function_ref<void(unsigned, const Stmt *, const Stmt *)> Callback) { 943 auto &&NewCallback = [Callback](unsigned Cnt, Stmt *Loop, Stmt *Body) { 944 Callback(Cnt, Loop, Body); 945 }; 946 doForAllLoopsBodies(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops, 947 NumLoops, NewCallback); 948 } 949 950 static bool classof(const Stmt *T) { 951 if (auto *D = dyn_cast<OMPExecutableDirective>(T)) 952 return isOpenMPLoopDirective(D->getDirectiveKind()); 953 return false; 954 } 955 }; 956 957 /// This is a common base class for loop directives ('omp simd', 'omp 958 /// for', 'omp for simd' etc.). It is responsible for the loop code generation. 959 /// 960 class OMPLoopDirective : public OMPLoopBasedDirective { 961 friend class ASTStmtReader; 962 963 /// Offsets to the stored exprs. 964 /// This enumeration contains offsets to all the pointers to children 965 /// expressions stored in OMPLoopDirective. 966 /// The first 9 children are necessary for all the loop directives, 967 /// the next 8 are specific to the worksharing ones, and the next 11 are 968 /// used for combined constructs containing two pragmas associated to loops. 969 /// After the fixed children, three arrays of length NumAssociatedLoops are 970 /// allocated: loop counters, their updates and final values. 971 /// PrevLowerBound and PrevUpperBound are used to communicate blocking 972 /// information in composite constructs which require loop blocking 973 /// DistInc is used to generate the increment expression for the distribute 974 /// loop when combined with a further nested loop 975 /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the 976 /// for loop when combined with a previous distribute loop in the same pragma 977 /// (e.g. 'distribute parallel for') 978 /// 979 enum { 980 IterationVariableOffset = 0, 981 LastIterationOffset = 1, 982 CalcLastIterationOffset = 2, 983 PreConditionOffset = 3, 984 CondOffset = 4, 985 InitOffset = 5, 986 IncOffset = 6, 987 PreInitsOffset = 7, 988 // The '...End' enumerators do not correspond to child expressions - they 989 // specify the offset to the end (and start of the following counters/ 990 // updates/finals/dependent_counters/dependent_inits/finals_conditions 991 // arrays). 992 DefaultEnd = 8, 993 // The following 8 exprs are used by worksharing and distribute loops only. 994 IsLastIterVariableOffset = 8, 995 LowerBoundVariableOffset = 9, 996 UpperBoundVariableOffset = 10, 997 StrideVariableOffset = 11, 998 EnsureUpperBoundOffset = 12, 999 NextLowerBoundOffset = 13, 1000 NextUpperBoundOffset = 14, 1001 NumIterationsOffset = 15, 1002 // Offset to the end for worksharing loop directives. 1003 WorksharingEnd = 16, 1004 PrevLowerBoundVariableOffset = 16, 1005 PrevUpperBoundVariableOffset = 17, 1006 DistIncOffset = 18, 1007 PrevEnsureUpperBoundOffset = 19, 1008 CombinedLowerBoundVariableOffset = 20, 1009 CombinedUpperBoundVariableOffset = 21, 1010 CombinedEnsureUpperBoundOffset = 22, 1011 CombinedInitOffset = 23, 1012 CombinedConditionOffset = 24, 1013 CombinedNextLowerBoundOffset = 25, 1014 CombinedNextUpperBoundOffset = 26, 1015 CombinedDistConditionOffset = 27, 1016 CombinedParForInDistConditionOffset = 28, 1017 // Offset to the end (and start of the following 1018 // counters/updates/finals/dependent_counters/dependent_inits/finals_conditions 1019 // arrays) for combined distribute loop directives. 1020 CombinedDistributeEnd = 29, 1021 }; 1022 1023 /// Get the counters storage. 1024 MutableArrayRef<Expr *> getCounters() { 1025 auto **Storage = reinterpret_cast<Expr **>( 1026 &Data->getChildren()[getArraysOffset(getDirectiveKind())]); 1027 return llvm::makeMutableArrayRef(Storage, getLoopsNumber()); 1028 } 1029 1030 /// Get the private counters storage. 1031 MutableArrayRef<Expr *> getPrivateCounters() { 1032 auto **Storage = reinterpret_cast<Expr **>( 1033 &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1034 getLoopsNumber()]); 1035 return llvm::makeMutableArrayRef(Storage, getLoopsNumber()); 1036 } 1037 1038 /// Get the updates storage. 1039 MutableArrayRef<Expr *> getInits() { 1040 auto **Storage = reinterpret_cast<Expr **>( 1041 &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1042 2 * getLoopsNumber()]); 1043 return llvm::makeMutableArrayRef(Storage, getLoopsNumber()); 1044 } 1045 1046 /// Get the updates storage. 1047 MutableArrayRef<Expr *> getUpdates() { 1048 auto **Storage = reinterpret_cast<Expr **>( 1049 &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1050 3 * getLoopsNumber()]); 1051 return llvm::makeMutableArrayRef(Storage, getLoopsNumber()); 1052 } 1053 1054 /// Get the final counter updates storage. 1055 MutableArrayRef<Expr *> getFinals() { 1056 auto **Storage = reinterpret_cast<Expr **>( 1057 &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1058 4 * getLoopsNumber()]); 1059 return llvm::makeMutableArrayRef(Storage, getLoopsNumber()); 1060 } 1061 1062 /// Get the dependent counters storage. 1063 MutableArrayRef<Expr *> getDependentCounters() { 1064 auto **Storage = reinterpret_cast<Expr **>( 1065 &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1066 5 * getLoopsNumber()]); 1067 return llvm::makeMutableArrayRef(Storage, getLoopsNumber()); 1068 } 1069 1070 /// Get the dependent inits storage. 1071 MutableArrayRef<Expr *> getDependentInits() { 1072 auto **Storage = reinterpret_cast<Expr **>( 1073 &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1074 6 * getLoopsNumber()]); 1075 return llvm::makeMutableArrayRef(Storage, getLoopsNumber()); 1076 } 1077 1078 /// Get the finals conditions storage. 1079 MutableArrayRef<Expr *> getFinalsConditions() { 1080 auto **Storage = reinterpret_cast<Expr **>( 1081 &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 1082 7 * getLoopsNumber()]); 1083 return llvm::makeMutableArrayRef(Storage, getLoopsNumber()); 1084 } 1085 1086 protected: 1087 /// Build instance of loop directive of class \a Kind. 1088 /// 1089 /// \param SC Statement class. 1090 /// \param Kind Kind of OpenMP directive. 1091 /// \param StartLoc Starting location of the directive (directive keyword). 1092 /// \param EndLoc Ending location of the directive. 1093 /// \param CollapsedNum Number of collapsed loops from 'collapse' clause. 1094 /// 1095 OMPLoopDirective(StmtClass SC, OpenMPDirectiveKind Kind, 1096 SourceLocation StartLoc, SourceLocation EndLoc, 1097 unsigned CollapsedNum) 1098 : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, CollapsedNum) {} 1099 1100 /// Offset to the start of children expression arrays. 1101 static unsigned getArraysOffset(OpenMPDirectiveKind Kind) { 1102 if (isOpenMPLoopBoundSharingDirective(Kind)) 1103 return CombinedDistributeEnd; 1104 if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) || 1105 isOpenMPDistributeDirective(Kind)) 1106 return WorksharingEnd; 1107 return DefaultEnd; 1108 } 1109 1110 /// Children number. 1111 static unsigned numLoopChildren(unsigned CollapsedNum, 1112 OpenMPDirectiveKind Kind) { 1113 return getArraysOffset(Kind) + 1114 8 * CollapsedNum; // Counters, PrivateCounters, Inits, 1115 // Updates, Finals, DependentCounters, 1116 // DependentInits, FinalsConditions. 1117 } 1118 1119 void setIterationVariable(Expr *IV) { 1120 Data->getChildren()[IterationVariableOffset] = IV; 1121 } 1122 void setLastIteration(Expr *LI) { 1123 Data->getChildren()[LastIterationOffset] = LI; 1124 } 1125 void setCalcLastIteration(Expr *CLI) { 1126 Data->getChildren()[CalcLastIterationOffset] = CLI; 1127 } 1128 void setPreCond(Expr *PC) { Data->getChildren()[PreConditionOffset] = PC; } 1129 void setCond(Expr *Cond) { Data->getChildren()[CondOffset] = Cond; } 1130 void setInit(Expr *Init) { Data->getChildren()[InitOffset] = Init; } 1131 void setInc(Expr *Inc) { Data->getChildren()[IncOffset] = Inc; } 1132 void setPreInits(Stmt *PreInits) { 1133 Data->getChildren()[PreInitsOffset] = PreInits; 1134 } 1135 void setIsLastIterVariable(Expr *IL) { 1136 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1137 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1138 isOpenMPDistributeDirective(getDirectiveKind())) && 1139 "expected worksharing loop directive"); 1140 Data->getChildren()[IsLastIterVariableOffset] = IL; 1141 } 1142 void setLowerBoundVariable(Expr *LB) { 1143 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1144 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1145 isOpenMPDistributeDirective(getDirectiveKind())) && 1146 "expected worksharing loop directive"); 1147 Data->getChildren()[LowerBoundVariableOffset] = LB; 1148 } 1149 void setUpperBoundVariable(Expr *UB) { 1150 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1151 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1152 isOpenMPDistributeDirective(getDirectiveKind())) && 1153 "expected worksharing loop directive"); 1154 Data->getChildren()[UpperBoundVariableOffset] = UB; 1155 } 1156 void setStrideVariable(Expr *ST) { 1157 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1158 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1159 isOpenMPDistributeDirective(getDirectiveKind())) && 1160 "expected worksharing loop directive"); 1161 Data->getChildren()[StrideVariableOffset] = ST; 1162 } 1163 void setEnsureUpperBound(Expr *EUB) { 1164 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1165 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1166 isOpenMPDistributeDirective(getDirectiveKind())) && 1167 "expected worksharing loop directive"); 1168 Data->getChildren()[EnsureUpperBoundOffset] = EUB; 1169 } 1170 void setNextLowerBound(Expr *NLB) { 1171 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1172 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1173 isOpenMPDistributeDirective(getDirectiveKind())) && 1174 "expected worksharing loop directive"); 1175 Data->getChildren()[NextLowerBoundOffset] = NLB; 1176 } 1177 void setNextUpperBound(Expr *NUB) { 1178 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1179 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1180 isOpenMPDistributeDirective(getDirectiveKind())) && 1181 "expected worksharing loop directive"); 1182 Data->getChildren()[NextUpperBoundOffset] = NUB; 1183 } 1184 void setNumIterations(Expr *NI) { 1185 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1186 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1187 isOpenMPDistributeDirective(getDirectiveKind())) && 1188 "expected worksharing loop directive"); 1189 Data->getChildren()[NumIterationsOffset] = NI; 1190 } 1191 void setPrevLowerBoundVariable(Expr *PrevLB) { 1192 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1193 "expected loop bound sharing directive"); 1194 Data->getChildren()[PrevLowerBoundVariableOffset] = PrevLB; 1195 } 1196 void setPrevUpperBoundVariable(Expr *PrevUB) { 1197 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1198 "expected loop bound sharing directive"); 1199 Data->getChildren()[PrevUpperBoundVariableOffset] = PrevUB; 1200 } 1201 void setDistInc(Expr *DistInc) { 1202 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1203 "expected loop bound sharing directive"); 1204 Data->getChildren()[DistIncOffset] = DistInc; 1205 } 1206 void setPrevEnsureUpperBound(Expr *PrevEUB) { 1207 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1208 "expected loop bound sharing directive"); 1209 Data->getChildren()[PrevEnsureUpperBoundOffset] = PrevEUB; 1210 } 1211 void setCombinedLowerBoundVariable(Expr *CombLB) { 1212 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1213 "expected loop bound sharing directive"); 1214 Data->getChildren()[CombinedLowerBoundVariableOffset] = CombLB; 1215 } 1216 void setCombinedUpperBoundVariable(Expr *CombUB) { 1217 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1218 "expected loop bound sharing directive"); 1219 Data->getChildren()[CombinedUpperBoundVariableOffset] = CombUB; 1220 } 1221 void setCombinedEnsureUpperBound(Expr *CombEUB) { 1222 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1223 "expected loop bound sharing directive"); 1224 Data->getChildren()[CombinedEnsureUpperBoundOffset] = CombEUB; 1225 } 1226 void setCombinedInit(Expr *CombInit) { 1227 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1228 "expected loop bound sharing directive"); 1229 Data->getChildren()[CombinedInitOffset] = CombInit; 1230 } 1231 void setCombinedCond(Expr *CombCond) { 1232 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1233 "expected loop bound sharing directive"); 1234 Data->getChildren()[CombinedConditionOffset] = CombCond; 1235 } 1236 void setCombinedNextLowerBound(Expr *CombNLB) { 1237 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1238 "expected loop bound sharing directive"); 1239 Data->getChildren()[CombinedNextLowerBoundOffset] = CombNLB; 1240 } 1241 void setCombinedNextUpperBound(Expr *CombNUB) { 1242 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1243 "expected loop bound sharing directive"); 1244 Data->getChildren()[CombinedNextUpperBoundOffset] = CombNUB; 1245 } 1246 void setCombinedDistCond(Expr *CombDistCond) { 1247 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1248 "expected loop bound distribute sharing directive"); 1249 Data->getChildren()[CombinedDistConditionOffset] = CombDistCond; 1250 } 1251 void setCombinedParForInDistCond(Expr *CombParForInDistCond) { 1252 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1253 "expected loop bound distribute sharing directive"); 1254 Data->getChildren()[CombinedParForInDistConditionOffset] = 1255 CombParForInDistCond; 1256 } 1257 void setCounters(ArrayRef<Expr *> A); 1258 void setPrivateCounters(ArrayRef<Expr *> A); 1259 void setInits(ArrayRef<Expr *> A); 1260 void setUpdates(ArrayRef<Expr *> A); 1261 void setFinals(ArrayRef<Expr *> A); 1262 void setDependentCounters(ArrayRef<Expr *> A); 1263 void setDependentInits(ArrayRef<Expr *> A); 1264 void setFinalsConditions(ArrayRef<Expr *> A); 1265 1266 public: 1267 Expr *getIterationVariable() const { 1268 return cast<Expr>(Data->getChildren()[IterationVariableOffset]); 1269 } 1270 Expr *getLastIteration() const { 1271 return cast<Expr>(Data->getChildren()[LastIterationOffset]); 1272 } 1273 Expr *getCalcLastIteration() const { 1274 return cast<Expr>(Data->getChildren()[CalcLastIterationOffset]); 1275 } 1276 Expr *getPreCond() const { 1277 return cast<Expr>(Data->getChildren()[PreConditionOffset]); 1278 } 1279 Expr *getCond() const { return cast<Expr>(Data->getChildren()[CondOffset]); } 1280 Expr *getInit() const { return cast<Expr>(Data->getChildren()[InitOffset]); } 1281 Expr *getInc() const { return cast<Expr>(Data->getChildren()[IncOffset]); } 1282 const Stmt *getPreInits() const { 1283 return Data->getChildren()[PreInitsOffset]; 1284 } 1285 Stmt *getPreInits() { return Data->getChildren()[PreInitsOffset]; } 1286 Expr *getIsLastIterVariable() const { 1287 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1288 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1289 isOpenMPDistributeDirective(getDirectiveKind())) && 1290 "expected worksharing loop directive"); 1291 return cast<Expr>(Data->getChildren()[IsLastIterVariableOffset]); 1292 } 1293 Expr *getLowerBoundVariable() const { 1294 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1295 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1296 isOpenMPDistributeDirective(getDirectiveKind())) && 1297 "expected worksharing loop directive"); 1298 return cast<Expr>(Data->getChildren()[LowerBoundVariableOffset]); 1299 } 1300 Expr *getUpperBoundVariable() const { 1301 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1302 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1303 isOpenMPDistributeDirective(getDirectiveKind())) && 1304 "expected worksharing loop directive"); 1305 return cast<Expr>(Data->getChildren()[UpperBoundVariableOffset]); 1306 } 1307 Expr *getStrideVariable() const { 1308 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1309 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1310 isOpenMPDistributeDirective(getDirectiveKind())) && 1311 "expected worksharing loop directive"); 1312 return cast<Expr>(Data->getChildren()[StrideVariableOffset]); 1313 } 1314 Expr *getEnsureUpperBound() const { 1315 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1316 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1317 isOpenMPDistributeDirective(getDirectiveKind())) && 1318 "expected worksharing loop directive"); 1319 return cast<Expr>(Data->getChildren()[EnsureUpperBoundOffset]); 1320 } 1321 Expr *getNextLowerBound() const { 1322 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1323 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1324 isOpenMPDistributeDirective(getDirectiveKind())) && 1325 "expected worksharing loop directive"); 1326 return cast<Expr>(Data->getChildren()[NextLowerBoundOffset]); 1327 } 1328 Expr *getNextUpperBound() const { 1329 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1330 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1331 isOpenMPDistributeDirective(getDirectiveKind())) && 1332 "expected worksharing loop directive"); 1333 return cast<Expr>(Data->getChildren()[NextUpperBoundOffset]); 1334 } 1335 Expr *getNumIterations() const { 1336 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1337 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1338 isOpenMPDistributeDirective(getDirectiveKind())) && 1339 "expected worksharing loop directive"); 1340 return cast<Expr>(Data->getChildren()[NumIterationsOffset]); 1341 } 1342 Expr *getPrevLowerBoundVariable() const { 1343 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1344 "expected loop bound sharing directive"); 1345 return cast<Expr>(Data->getChildren()[PrevLowerBoundVariableOffset]); 1346 } 1347 Expr *getPrevUpperBoundVariable() const { 1348 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1349 "expected loop bound sharing directive"); 1350 return cast<Expr>(Data->getChildren()[PrevUpperBoundVariableOffset]); 1351 } 1352 Expr *getDistInc() const { 1353 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1354 "expected loop bound sharing directive"); 1355 return cast<Expr>(Data->getChildren()[DistIncOffset]); 1356 } 1357 Expr *getPrevEnsureUpperBound() const { 1358 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1359 "expected loop bound sharing directive"); 1360 return cast<Expr>(Data->getChildren()[PrevEnsureUpperBoundOffset]); 1361 } 1362 Expr *getCombinedLowerBoundVariable() const { 1363 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1364 "expected loop bound sharing directive"); 1365 return cast<Expr>(Data->getChildren()[CombinedLowerBoundVariableOffset]); 1366 } 1367 Expr *getCombinedUpperBoundVariable() const { 1368 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1369 "expected loop bound sharing directive"); 1370 return cast<Expr>(Data->getChildren()[CombinedUpperBoundVariableOffset]); 1371 } 1372 Expr *getCombinedEnsureUpperBound() const { 1373 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1374 "expected loop bound sharing directive"); 1375 return cast<Expr>(Data->getChildren()[CombinedEnsureUpperBoundOffset]); 1376 } 1377 Expr *getCombinedInit() const { 1378 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1379 "expected loop bound sharing directive"); 1380 return cast<Expr>(Data->getChildren()[CombinedInitOffset]); 1381 } 1382 Expr *getCombinedCond() const { 1383 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1384 "expected loop bound sharing directive"); 1385 return cast<Expr>(Data->getChildren()[CombinedConditionOffset]); 1386 } 1387 Expr *getCombinedNextLowerBound() const { 1388 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1389 "expected loop bound sharing directive"); 1390 return cast<Expr>(Data->getChildren()[CombinedNextLowerBoundOffset]); 1391 } 1392 Expr *getCombinedNextUpperBound() const { 1393 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1394 "expected loop bound sharing directive"); 1395 return cast<Expr>(Data->getChildren()[CombinedNextUpperBoundOffset]); 1396 } 1397 Expr *getCombinedDistCond() const { 1398 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1399 "expected loop bound distribute sharing directive"); 1400 return cast<Expr>(Data->getChildren()[CombinedDistConditionOffset]); 1401 } 1402 Expr *getCombinedParForInDistCond() const { 1403 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1404 "expected loop bound distribute sharing directive"); 1405 return cast<Expr>(Data->getChildren()[CombinedParForInDistConditionOffset]); 1406 } 1407 Stmt *getBody(); 1408 const Stmt *getBody() const { 1409 return const_cast<OMPLoopDirective *>(this)->getBody(); 1410 } 1411 1412 ArrayRef<Expr *> counters() { return getCounters(); } 1413 1414 ArrayRef<Expr *> counters() const { 1415 return const_cast<OMPLoopDirective *>(this)->getCounters(); 1416 } 1417 1418 ArrayRef<Expr *> private_counters() { return getPrivateCounters(); } 1419 1420 ArrayRef<Expr *> private_counters() const { 1421 return const_cast<OMPLoopDirective *>(this)->getPrivateCounters(); 1422 } 1423 1424 ArrayRef<Expr *> inits() { return getInits(); } 1425 1426 ArrayRef<Expr *> inits() const { 1427 return const_cast<OMPLoopDirective *>(this)->getInits(); 1428 } 1429 1430 ArrayRef<Expr *> updates() { return getUpdates(); } 1431 1432 ArrayRef<Expr *> updates() const { 1433 return const_cast<OMPLoopDirective *>(this)->getUpdates(); 1434 } 1435 1436 ArrayRef<Expr *> finals() { return getFinals(); } 1437 1438 ArrayRef<Expr *> finals() const { 1439 return const_cast<OMPLoopDirective *>(this)->getFinals(); 1440 } 1441 1442 ArrayRef<Expr *> dependent_counters() { return getDependentCounters(); } 1443 1444 ArrayRef<Expr *> dependent_counters() const { 1445 return const_cast<OMPLoopDirective *>(this)->getDependentCounters(); 1446 } 1447 1448 ArrayRef<Expr *> dependent_inits() { return getDependentInits(); } 1449 1450 ArrayRef<Expr *> dependent_inits() const { 1451 return const_cast<OMPLoopDirective *>(this)->getDependentInits(); 1452 } 1453 1454 ArrayRef<Expr *> finals_conditions() { return getFinalsConditions(); } 1455 1456 ArrayRef<Expr *> finals_conditions() const { 1457 return const_cast<OMPLoopDirective *>(this)->getFinalsConditions(); 1458 } 1459 1460 static bool classof(const Stmt *T) { 1461 return T->getStmtClass() == OMPSimdDirectiveClass || 1462 T->getStmtClass() == OMPForDirectiveClass || 1463 T->getStmtClass() == OMPForSimdDirectiveClass || 1464 T->getStmtClass() == OMPParallelForDirectiveClass || 1465 T->getStmtClass() == OMPParallelForSimdDirectiveClass || 1466 T->getStmtClass() == OMPTaskLoopDirectiveClass || 1467 T->getStmtClass() == OMPTaskLoopSimdDirectiveClass || 1468 T->getStmtClass() == OMPMasterTaskLoopDirectiveClass || 1469 T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass || 1470 T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass || 1471 T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass || 1472 T->getStmtClass() == OMPDistributeDirectiveClass || 1473 T->getStmtClass() == OMPTargetParallelForDirectiveClass || 1474 T->getStmtClass() == OMPDistributeParallelForDirectiveClass || 1475 T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass || 1476 T->getStmtClass() == OMPDistributeSimdDirectiveClass || 1477 T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass || 1478 T->getStmtClass() == OMPTargetSimdDirectiveClass || 1479 T->getStmtClass() == OMPTeamsDistributeDirectiveClass || 1480 T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass || 1481 T->getStmtClass() == 1482 OMPTeamsDistributeParallelForSimdDirectiveClass || 1483 T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass || 1484 T->getStmtClass() == 1485 OMPTargetTeamsDistributeParallelForDirectiveClass || 1486 T->getStmtClass() == 1487 OMPTargetTeamsDistributeParallelForSimdDirectiveClass || 1488 T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass || 1489 T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass; 1490 } 1491 }; 1492 1493 /// This represents '#pragma omp simd' directive. 1494 /// 1495 /// \code 1496 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d) 1497 /// \endcode 1498 /// In this example directive '#pragma omp simd' has clauses 'private' 1499 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and 1500 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. 1501 /// 1502 class OMPSimdDirective : public OMPLoopDirective { 1503 friend class ASTStmtReader; 1504 friend class OMPExecutableDirective; 1505 /// Build directive with the given start and end location. 1506 /// 1507 /// \param StartLoc Starting location of the directive kind. 1508 /// \param EndLoc Ending location of the directive. 1509 /// \param CollapsedNum Number of collapsed nested loops. 1510 /// 1511 OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1512 unsigned CollapsedNum) 1513 : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, StartLoc, 1514 EndLoc, CollapsedNum) {} 1515 1516 /// Build an empty directive. 1517 /// 1518 /// \param CollapsedNum Number of collapsed nested loops. 1519 /// 1520 explicit OMPSimdDirective(unsigned CollapsedNum) 1521 : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, 1522 SourceLocation(), SourceLocation(), CollapsedNum) {} 1523 1524 public: 1525 /// Creates directive with a list of \a Clauses. 1526 /// 1527 /// \param C AST context. 1528 /// \param StartLoc Starting location of the directive kind. 1529 /// \param EndLoc Ending Location of the directive. 1530 /// \param CollapsedNum Number of collapsed loops. 1531 /// \param Clauses List of clauses. 1532 /// \param AssociatedStmt Statement, associated with the directive. 1533 /// \param Exprs Helper expressions for CodeGen. 1534 /// 1535 static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc, 1536 SourceLocation EndLoc, unsigned CollapsedNum, 1537 ArrayRef<OMPClause *> Clauses, 1538 Stmt *AssociatedStmt, 1539 const HelperExprs &Exprs); 1540 1541 /// Creates an empty directive with the place 1542 /// for \a NumClauses clauses. 1543 /// 1544 /// \param C AST context. 1545 /// \param CollapsedNum Number of collapsed nested loops. 1546 /// \param NumClauses Number of clauses. 1547 /// 1548 static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 1549 unsigned CollapsedNum, EmptyShell); 1550 1551 static bool classof(const Stmt *T) { 1552 return T->getStmtClass() == OMPSimdDirectiveClass; 1553 } 1554 }; 1555 1556 /// This represents '#pragma omp for' directive. 1557 /// 1558 /// \code 1559 /// #pragma omp for private(a,b) reduction(+:c,d) 1560 /// \endcode 1561 /// In this example directive '#pragma omp for' has clauses 'private' with the 1562 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c' 1563 /// and 'd'. 1564 /// 1565 class OMPForDirective : public OMPLoopDirective { 1566 friend class ASTStmtReader; 1567 friend class OMPExecutableDirective; 1568 /// true if current directive has inner cancel directive. 1569 bool HasCancel = false; 1570 1571 /// Build directive with the given start and end location. 1572 /// 1573 /// \param StartLoc Starting location of the directive kind. 1574 /// \param EndLoc Ending location of the directive. 1575 /// \param CollapsedNum Number of collapsed nested loops. 1576 /// 1577 OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1578 unsigned CollapsedNum) 1579 : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, StartLoc, 1580 EndLoc, CollapsedNum) {} 1581 1582 /// Build an empty directive. 1583 /// 1584 /// \param CollapsedNum Number of collapsed nested loops. 1585 /// 1586 explicit OMPForDirective(unsigned CollapsedNum) 1587 : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, 1588 SourceLocation(), SourceLocation(), CollapsedNum) {} 1589 1590 /// Sets special task reduction descriptor. 1591 void setTaskReductionRefExpr(Expr *E) { 1592 Data->getChildren()[numLoopChildren(getLoopsNumber(), 1593 llvm::omp::OMPD_for)] = E; 1594 } 1595 1596 /// Set cancel state. 1597 void setHasCancel(bool Has) { HasCancel = Has; } 1598 1599 public: 1600 /// Creates directive with a list of \a Clauses. 1601 /// 1602 /// \param C AST context. 1603 /// \param StartLoc Starting location of the directive kind. 1604 /// \param EndLoc Ending Location of the directive. 1605 /// \param CollapsedNum Number of collapsed loops. 1606 /// \param Clauses List of clauses. 1607 /// \param AssociatedStmt Statement, associated with the directive. 1608 /// \param Exprs Helper expressions for CodeGen. 1609 /// \param TaskRedRef Task reduction special reference expression to handle 1610 /// taskgroup descriptor. 1611 /// \param HasCancel true if current directive has inner cancel directive. 1612 /// 1613 static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc, 1614 SourceLocation EndLoc, unsigned CollapsedNum, 1615 ArrayRef<OMPClause *> Clauses, 1616 Stmt *AssociatedStmt, const HelperExprs &Exprs, 1617 Expr *TaskRedRef, bool HasCancel); 1618 1619 /// Creates an empty directive with the place 1620 /// for \a NumClauses clauses. 1621 /// 1622 /// \param C AST context. 1623 /// \param CollapsedNum Number of collapsed nested loops. 1624 /// \param NumClauses Number of clauses. 1625 /// 1626 static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 1627 unsigned CollapsedNum, EmptyShell); 1628 1629 /// Returns special task reduction reference expression. 1630 Expr *getTaskReductionRefExpr() { 1631 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 1632 getLoopsNumber(), llvm::omp::OMPD_for)]); 1633 } 1634 const Expr *getTaskReductionRefExpr() const { 1635 return const_cast<OMPForDirective *>(this)->getTaskReductionRefExpr(); 1636 } 1637 1638 /// Return true if current directive has inner cancel directive. 1639 bool hasCancel() const { return HasCancel; } 1640 1641 static bool classof(const Stmt *T) { 1642 return T->getStmtClass() == OMPForDirectiveClass; 1643 } 1644 }; 1645 1646 /// This represents '#pragma omp for simd' directive. 1647 /// 1648 /// \code 1649 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d) 1650 /// \endcode 1651 /// In this example directive '#pragma omp for simd' has clauses 'private' 1652 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and 1653 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. 1654 /// 1655 class OMPForSimdDirective : public OMPLoopDirective { 1656 friend class ASTStmtReader; 1657 friend class OMPExecutableDirective; 1658 /// Build directive with the given start and end location. 1659 /// 1660 /// \param StartLoc Starting location of the directive kind. 1661 /// \param EndLoc Ending location of the directive. 1662 /// \param CollapsedNum Number of collapsed nested loops. 1663 /// 1664 OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1665 unsigned CollapsedNum) 1666 : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd, 1667 StartLoc, EndLoc, CollapsedNum) {} 1668 1669 /// Build an empty directive. 1670 /// 1671 /// \param CollapsedNum Number of collapsed nested loops. 1672 /// 1673 explicit OMPForSimdDirective(unsigned CollapsedNum) 1674 : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd, 1675 SourceLocation(), SourceLocation(), CollapsedNum) {} 1676 1677 public: 1678 /// Creates directive with a list of \a Clauses. 1679 /// 1680 /// \param C AST context. 1681 /// \param StartLoc Starting location of the directive kind. 1682 /// \param EndLoc Ending Location of the directive. 1683 /// \param CollapsedNum Number of collapsed loops. 1684 /// \param Clauses List of clauses. 1685 /// \param AssociatedStmt Statement, associated with the directive. 1686 /// \param Exprs Helper expressions for CodeGen. 1687 /// 1688 static OMPForSimdDirective * 1689 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1690 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 1691 Stmt *AssociatedStmt, const HelperExprs &Exprs); 1692 1693 /// Creates an empty directive with the place 1694 /// for \a NumClauses clauses. 1695 /// 1696 /// \param C AST context. 1697 /// \param CollapsedNum Number of collapsed nested loops. 1698 /// \param NumClauses Number of clauses. 1699 /// 1700 static OMPForSimdDirective *CreateEmpty(const ASTContext &C, 1701 unsigned NumClauses, 1702 unsigned CollapsedNum, EmptyShell); 1703 1704 static bool classof(const Stmt *T) { 1705 return T->getStmtClass() == OMPForSimdDirectiveClass; 1706 } 1707 }; 1708 1709 /// This represents '#pragma omp sections' directive. 1710 /// 1711 /// \code 1712 /// #pragma omp sections private(a,b) reduction(+:c,d) 1713 /// \endcode 1714 /// In this example directive '#pragma omp sections' has clauses 'private' with 1715 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables 1716 /// 'c' and 'd'. 1717 /// 1718 class OMPSectionsDirective : public OMPExecutableDirective { 1719 friend class ASTStmtReader; 1720 friend class OMPExecutableDirective; 1721 1722 /// true if current directive has inner cancel directive. 1723 bool HasCancel = false; 1724 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 /// 1730 OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1731 : OMPExecutableDirective(OMPSectionsDirectiveClass, 1732 llvm::omp::OMPD_sections, StartLoc, EndLoc) {} 1733 1734 /// Build an empty directive. 1735 /// 1736 explicit OMPSectionsDirective() 1737 : OMPExecutableDirective(OMPSectionsDirectiveClass, 1738 llvm::omp::OMPD_sections, SourceLocation(), 1739 SourceLocation()) {} 1740 1741 /// Sets special task reduction descriptor. 1742 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 1743 1744 /// Set cancel state. 1745 void setHasCancel(bool Has) { HasCancel = Has; } 1746 1747 public: 1748 /// Creates directive with a list of \a Clauses. 1749 /// 1750 /// \param C AST context. 1751 /// \param StartLoc Starting location of the directive kind. 1752 /// \param EndLoc Ending Location of the directive. 1753 /// \param Clauses List of clauses. 1754 /// \param AssociatedStmt Statement, associated with the directive. 1755 /// \param TaskRedRef Task reduction special reference expression to handle 1756 /// taskgroup descriptor. 1757 /// \param HasCancel true if current directive has inner directive. 1758 /// 1759 static OMPSectionsDirective * 1760 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1761 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 1762 bool HasCancel); 1763 1764 /// Creates an empty directive with the place for \a NumClauses 1765 /// clauses. 1766 /// 1767 /// \param C AST context. 1768 /// \param NumClauses Number of clauses. 1769 /// 1770 static OMPSectionsDirective *CreateEmpty(const ASTContext &C, 1771 unsigned NumClauses, EmptyShell); 1772 1773 /// Returns special task reduction reference expression. 1774 Expr *getTaskReductionRefExpr() { 1775 return cast_or_null<Expr>(Data->getChildren()[0]); 1776 } 1777 const Expr *getTaskReductionRefExpr() const { 1778 return const_cast<OMPSectionsDirective *>(this)->getTaskReductionRefExpr(); 1779 } 1780 1781 /// Return true if current directive has inner cancel directive. 1782 bool hasCancel() const { return HasCancel; } 1783 1784 static bool classof(const Stmt *T) { 1785 return T->getStmtClass() == OMPSectionsDirectiveClass; 1786 } 1787 }; 1788 1789 /// This represents '#pragma omp section' directive. 1790 /// 1791 /// \code 1792 /// #pragma omp section 1793 /// \endcode 1794 /// 1795 class OMPSectionDirective : public OMPExecutableDirective { 1796 friend class ASTStmtReader; 1797 friend class OMPExecutableDirective; 1798 1799 /// true if current directive has inner cancel directive. 1800 bool HasCancel = false; 1801 1802 /// Build directive with the given start and end location. 1803 /// 1804 /// \param StartLoc Starting location of the directive kind. 1805 /// \param EndLoc Ending location of the directive. 1806 /// 1807 OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1808 : OMPExecutableDirective(OMPSectionDirectiveClass, 1809 llvm::omp::OMPD_section, StartLoc, EndLoc) {} 1810 1811 /// Build an empty directive. 1812 /// 1813 explicit OMPSectionDirective() 1814 : OMPExecutableDirective(OMPSectionDirectiveClass, 1815 llvm::omp::OMPD_section, SourceLocation(), 1816 SourceLocation()) {} 1817 1818 public: 1819 /// Creates directive. 1820 /// 1821 /// \param C AST context. 1822 /// \param StartLoc Starting location of the directive kind. 1823 /// \param EndLoc Ending Location of the directive. 1824 /// \param AssociatedStmt Statement, associated with the directive. 1825 /// \param HasCancel true if current directive has inner directive. 1826 /// 1827 static OMPSectionDirective *Create(const ASTContext &C, 1828 SourceLocation StartLoc, 1829 SourceLocation EndLoc, 1830 Stmt *AssociatedStmt, bool HasCancel); 1831 1832 /// Creates an empty directive. 1833 /// 1834 /// \param C AST context. 1835 /// 1836 static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell); 1837 1838 /// Set cancel state. 1839 void setHasCancel(bool Has) { HasCancel = Has; } 1840 1841 /// Return true if current directive has inner cancel directive. 1842 bool hasCancel() const { return HasCancel; } 1843 1844 static bool classof(const Stmt *T) { 1845 return T->getStmtClass() == OMPSectionDirectiveClass; 1846 } 1847 }; 1848 1849 /// This represents '#pragma omp single' directive. 1850 /// 1851 /// \code 1852 /// #pragma omp single private(a,b) copyprivate(c,d) 1853 /// \endcode 1854 /// In this example directive '#pragma omp single' has clauses 'private' with 1855 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'. 1856 /// 1857 class OMPSingleDirective : public OMPExecutableDirective { 1858 friend class ASTStmtReader; 1859 friend class OMPExecutableDirective; 1860 /// Build directive with the given start and end location. 1861 /// 1862 /// \param StartLoc Starting location of the directive kind. 1863 /// \param EndLoc Ending location of the directive. 1864 /// 1865 OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1866 : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single, 1867 StartLoc, EndLoc) {} 1868 1869 /// Build an empty directive. 1870 /// 1871 explicit OMPSingleDirective() 1872 : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single, 1873 SourceLocation(), SourceLocation()) {} 1874 1875 public: 1876 /// Creates directive with a list of \a Clauses. 1877 /// 1878 /// \param C AST context. 1879 /// \param StartLoc Starting location of the directive kind. 1880 /// \param EndLoc Ending Location of the directive. 1881 /// \param Clauses List of clauses. 1882 /// \param AssociatedStmt Statement, associated with the directive. 1883 /// 1884 static OMPSingleDirective * 1885 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1886 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 1887 1888 /// Creates an empty directive with the place for \a NumClauses 1889 /// clauses. 1890 /// 1891 /// \param C AST context. 1892 /// \param NumClauses Number of clauses. 1893 /// 1894 static OMPSingleDirective *CreateEmpty(const ASTContext &C, 1895 unsigned NumClauses, EmptyShell); 1896 1897 static bool classof(const Stmt *T) { 1898 return T->getStmtClass() == OMPSingleDirectiveClass; 1899 } 1900 }; 1901 1902 /// This represents '#pragma omp master' directive. 1903 /// 1904 /// \code 1905 /// #pragma omp master 1906 /// \endcode 1907 /// 1908 class OMPMasterDirective : public OMPExecutableDirective { 1909 friend class ASTStmtReader; 1910 friend class OMPExecutableDirective; 1911 /// Build directive with the given start and end location. 1912 /// 1913 /// \param StartLoc Starting location of the directive kind. 1914 /// \param EndLoc Ending location of the directive. 1915 /// 1916 OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1917 : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master, 1918 StartLoc, EndLoc) {} 1919 1920 /// Build an empty directive. 1921 /// 1922 explicit OMPMasterDirective() 1923 : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master, 1924 SourceLocation(), SourceLocation()) {} 1925 1926 public: 1927 /// Creates directive. 1928 /// 1929 /// \param C AST context. 1930 /// \param StartLoc Starting location of the directive kind. 1931 /// \param EndLoc Ending Location of the directive. 1932 /// \param AssociatedStmt Statement, associated with the directive. 1933 /// 1934 static OMPMasterDirective *Create(const ASTContext &C, 1935 SourceLocation StartLoc, 1936 SourceLocation EndLoc, 1937 Stmt *AssociatedStmt); 1938 1939 /// Creates an empty directive. 1940 /// 1941 /// \param C AST context. 1942 /// 1943 static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell); 1944 1945 static bool classof(const Stmt *T) { 1946 return T->getStmtClass() == OMPMasterDirectiveClass; 1947 } 1948 }; 1949 1950 /// This represents '#pragma omp critical' directive. 1951 /// 1952 /// \code 1953 /// #pragma omp critical 1954 /// \endcode 1955 /// 1956 class OMPCriticalDirective : public OMPExecutableDirective { 1957 friend class ASTStmtReader; 1958 friend class OMPExecutableDirective; 1959 /// Name of the directive. 1960 DeclarationNameInfo DirName; 1961 /// Build directive with the given start and end location. 1962 /// 1963 /// \param Name Name of the directive. 1964 /// \param StartLoc Starting location of the directive kind. 1965 /// \param EndLoc Ending location of the directive. 1966 /// 1967 OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc, 1968 SourceLocation EndLoc) 1969 : OMPExecutableDirective(OMPCriticalDirectiveClass, 1970 llvm::omp::OMPD_critical, StartLoc, EndLoc), 1971 DirName(Name) {} 1972 1973 /// Build an empty directive. 1974 /// 1975 explicit OMPCriticalDirective() 1976 : OMPExecutableDirective(OMPCriticalDirectiveClass, 1977 llvm::omp::OMPD_critical, SourceLocation(), 1978 SourceLocation()) {} 1979 1980 /// Set name of the directive. 1981 /// 1982 /// \param Name Name of the directive. 1983 /// 1984 void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; } 1985 1986 public: 1987 /// Creates directive. 1988 /// 1989 /// \param C AST context. 1990 /// \param Name Name of the directive. 1991 /// \param StartLoc Starting location of the directive kind. 1992 /// \param EndLoc Ending Location of the directive. 1993 /// \param Clauses List of clauses. 1994 /// \param AssociatedStmt Statement, associated with the directive. 1995 /// 1996 static OMPCriticalDirective * 1997 Create(const ASTContext &C, const DeclarationNameInfo &Name, 1998 SourceLocation StartLoc, SourceLocation EndLoc, 1999 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 2000 2001 /// Creates an empty directive. 2002 /// 2003 /// \param C AST context. 2004 /// \param NumClauses Number of clauses. 2005 /// 2006 static OMPCriticalDirective *CreateEmpty(const ASTContext &C, 2007 unsigned NumClauses, EmptyShell); 2008 2009 /// Return name of the directive. 2010 /// 2011 DeclarationNameInfo getDirectiveName() const { return DirName; } 2012 2013 static bool classof(const Stmt *T) { 2014 return T->getStmtClass() == OMPCriticalDirectiveClass; 2015 } 2016 }; 2017 2018 /// This represents '#pragma omp parallel for' directive. 2019 /// 2020 /// \code 2021 /// #pragma omp parallel for private(a,b) reduction(+:c,d) 2022 /// \endcode 2023 /// In this example directive '#pragma omp parallel for' has clauses 'private' 2024 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and 2025 /// variables 'c' and 'd'. 2026 /// 2027 class OMPParallelForDirective : public OMPLoopDirective { 2028 friend class ASTStmtReader; 2029 friend class OMPExecutableDirective; 2030 2031 /// true if current region has inner cancel directive. 2032 bool HasCancel = false; 2033 2034 /// Build directive with the given start and end location. 2035 /// 2036 /// \param StartLoc Starting location of the directive kind. 2037 /// \param EndLoc Ending location of the directive. 2038 /// \param CollapsedNum Number of collapsed nested loops. 2039 /// 2040 OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2041 unsigned CollapsedNum) 2042 : OMPLoopDirective(OMPParallelForDirectiveClass, 2043 llvm::omp::OMPD_parallel_for, StartLoc, EndLoc, 2044 CollapsedNum) {} 2045 2046 /// Build an empty directive. 2047 /// 2048 /// \param CollapsedNum Number of collapsed nested loops. 2049 /// 2050 explicit OMPParallelForDirective(unsigned CollapsedNum) 2051 : OMPLoopDirective(OMPParallelForDirectiveClass, 2052 llvm::omp::OMPD_parallel_for, SourceLocation(), 2053 SourceLocation(), CollapsedNum) {} 2054 2055 /// Sets special task reduction descriptor. 2056 void setTaskReductionRefExpr(Expr *E) { 2057 Data->getChildren()[numLoopChildren(getLoopsNumber(), 2058 llvm::omp::OMPD_parallel_for)] = E; 2059 } 2060 2061 /// Set cancel state. 2062 void setHasCancel(bool Has) { HasCancel = Has; } 2063 2064 public: 2065 /// Creates directive with a list of \a Clauses. 2066 /// 2067 /// \param C AST context. 2068 /// \param StartLoc Starting location of the directive kind. 2069 /// \param EndLoc Ending Location of the directive. 2070 /// \param CollapsedNum Number of collapsed loops. 2071 /// \param Clauses List of clauses. 2072 /// \param AssociatedStmt Statement, associated with the directive. 2073 /// \param Exprs Helper expressions for CodeGen. 2074 /// \param TaskRedRef Task reduction special reference expression to handle 2075 /// taskgroup descriptor. 2076 /// \param HasCancel true if current directive has inner cancel directive. 2077 /// 2078 static OMPParallelForDirective * 2079 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2080 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 2081 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 2082 bool HasCancel); 2083 2084 /// Creates an empty directive with the place 2085 /// for \a NumClauses clauses. 2086 /// 2087 /// \param C AST context. 2088 /// \param CollapsedNum Number of collapsed nested loops. 2089 /// \param NumClauses Number of clauses. 2090 /// 2091 static OMPParallelForDirective *CreateEmpty(const ASTContext &C, 2092 unsigned NumClauses, 2093 unsigned CollapsedNum, 2094 EmptyShell); 2095 2096 /// Returns special task reduction reference expression. 2097 Expr *getTaskReductionRefExpr() { 2098 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 2099 getLoopsNumber(), llvm::omp::OMPD_parallel_for)]); 2100 } 2101 const Expr *getTaskReductionRefExpr() const { 2102 return const_cast<OMPParallelForDirective *>(this) 2103 ->getTaskReductionRefExpr(); 2104 } 2105 2106 /// Return true if current directive has inner cancel directive. 2107 bool hasCancel() const { return HasCancel; } 2108 2109 static bool classof(const Stmt *T) { 2110 return T->getStmtClass() == OMPParallelForDirectiveClass; 2111 } 2112 }; 2113 2114 /// This represents '#pragma omp parallel for simd' directive. 2115 /// 2116 /// \code 2117 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d) 2118 /// \endcode 2119 /// In this example directive '#pragma omp parallel for simd' has clauses 2120 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j' 2121 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and 2122 /// 'd'. 2123 /// 2124 class OMPParallelForSimdDirective : public OMPLoopDirective { 2125 friend class ASTStmtReader; 2126 friend class OMPExecutableDirective; 2127 /// Build directive with the given start and end location. 2128 /// 2129 /// \param StartLoc Starting location of the directive kind. 2130 /// \param EndLoc Ending location of the directive. 2131 /// \param CollapsedNum Number of collapsed nested loops. 2132 /// 2133 OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2134 unsigned CollapsedNum) 2135 : OMPLoopDirective(OMPParallelForSimdDirectiveClass, 2136 llvm::omp::OMPD_parallel_for_simd, StartLoc, EndLoc, 2137 CollapsedNum) {} 2138 2139 /// Build an empty directive. 2140 /// 2141 /// \param CollapsedNum Number of collapsed nested loops. 2142 /// 2143 explicit OMPParallelForSimdDirective(unsigned CollapsedNum) 2144 : OMPLoopDirective(OMPParallelForSimdDirectiveClass, 2145 llvm::omp::OMPD_parallel_for_simd, SourceLocation(), 2146 SourceLocation(), CollapsedNum) {} 2147 2148 public: 2149 /// Creates directive with a list of \a Clauses. 2150 /// 2151 /// \param C AST context. 2152 /// \param StartLoc Starting location of the directive kind. 2153 /// \param EndLoc Ending Location of the directive. 2154 /// \param CollapsedNum Number of collapsed loops. 2155 /// \param Clauses List of clauses. 2156 /// \param AssociatedStmt Statement, associated with the directive. 2157 /// \param Exprs Helper expressions for CodeGen. 2158 /// 2159 static OMPParallelForSimdDirective * 2160 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2161 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 2162 Stmt *AssociatedStmt, const HelperExprs &Exprs); 2163 2164 /// Creates an empty directive with the place 2165 /// for \a NumClauses clauses. 2166 /// 2167 /// \param C AST context. 2168 /// \param CollapsedNum Number of collapsed nested loops. 2169 /// \param NumClauses Number of clauses. 2170 /// 2171 static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C, 2172 unsigned NumClauses, 2173 unsigned CollapsedNum, 2174 EmptyShell); 2175 2176 static bool classof(const Stmt *T) { 2177 return T->getStmtClass() == OMPParallelForSimdDirectiveClass; 2178 } 2179 }; 2180 2181 /// This represents '#pragma omp parallel master' directive. 2182 /// 2183 /// \code 2184 /// #pragma omp parallel master private(a,b) 2185 /// \endcode 2186 /// In this example directive '#pragma omp parallel master' has clauses 2187 /// 'private' with the variables 'a' and 'b' 2188 /// 2189 class OMPParallelMasterDirective : public OMPExecutableDirective { 2190 friend class ASTStmtReader; 2191 friend class OMPExecutableDirective; 2192 2193 OMPParallelMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2194 : OMPExecutableDirective(OMPParallelMasterDirectiveClass, 2195 llvm::omp::OMPD_parallel_master, StartLoc, 2196 EndLoc) {} 2197 2198 explicit OMPParallelMasterDirective() 2199 : OMPExecutableDirective(OMPParallelMasterDirectiveClass, 2200 llvm::omp::OMPD_parallel_master, 2201 SourceLocation(), SourceLocation()) {} 2202 2203 /// Sets special task reduction descriptor. 2204 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 2205 2206 public: 2207 /// Creates directive with a list of \a Clauses. 2208 /// 2209 /// \param C AST context. 2210 /// \param StartLoc Starting location of the directive kind. 2211 /// \param EndLoc Ending Location of the directive. 2212 /// \param Clauses List of clauses. 2213 /// \param AssociatedStmt Statement, associated with the directive. 2214 /// \param TaskRedRef Task reduction special reference expression to handle 2215 /// taskgroup descriptor. 2216 /// 2217 static OMPParallelMasterDirective * 2218 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2219 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef); 2220 2221 /// Creates an empty directive with the place for \a NumClauses 2222 /// clauses. 2223 /// 2224 /// \param C AST context. 2225 /// \param NumClauses Number of clauses. 2226 /// 2227 static OMPParallelMasterDirective * 2228 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 2229 2230 /// Returns special task reduction reference expression. 2231 Expr *getTaskReductionRefExpr() { 2232 return cast_or_null<Expr>(Data->getChildren()[0]); 2233 } 2234 const Expr *getTaskReductionRefExpr() const { 2235 return const_cast<OMPParallelMasterDirective *>(this) 2236 ->getTaskReductionRefExpr(); 2237 } 2238 2239 static bool classof(const Stmt *T) { 2240 return T->getStmtClass() == OMPParallelMasterDirectiveClass; 2241 } 2242 }; 2243 2244 /// This represents '#pragma omp parallel sections' directive. 2245 /// 2246 /// \code 2247 /// #pragma omp parallel sections private(a,b) reduction(+:c,d) 2248 /// \endcode 2249 /// In this example directive '#pragma omp parallel sections' has clauses 2250 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' 2251 /// and variables 'c' and 'd'. 2252 /// 2253 class OMPParallelSectionsDirective : public OMPExecutableDirective { 2254 friend class ASTStmtReader; 2255 friend class OMPExecutableDirective; 2256 2257 /// true if current directive has inner cancel directive. 2258 bool HasCancel = false; 2259 2260 /// Build directive with the given start and end location. 2261 /// 2262 /// \param StartLoc Starting location of the directive kind. 2263 /// \param EndLoc Ending location of the directive. 2264 /// 2265 OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2266 : OMPExecutableDirective(OMPParallelSectionsDirectiveClass, 2267 llvm::omp::OMPD_parallel_sections, StartLoc, 2268 EndLoc) {} 2269 2270 /// Build an empty directive. 2271 /// 2272 explicit OMPParallelSectionsDirective() 2273 : OMPExecutableDirective(OMPParallelSectionsDirectiveClass, 2274 llvm::omp::OMPD_parallel_sections, 2275 SourceLocation(), SourceLocation()) {} 2276 2277 /// Sets special task reduction descriptor. 2278 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 2279 2280 /// Set cancel state. 2281 void setHasCancel(bool Has) { HasCancel = Has; } 2282 2283 public: 2284 /// Creates directive with a list of \a Clauses. 2285 /// 2286 /// \param C AST context. 2287 /// \param StartLoc Starting location of the directive kind. 2288 /// \param EndLoc Ending Location of the directive. 2289 /// \param Clauses List of clauses. 2290 /// \param AssociatedStmt Statement, associated with the directive. 2291 /// \param TaskRedRef Task reduction special reference expression to handle 2292 /// taskgroup descriptor. 2293 /// \param HasCancel true if current directive has inner cancel directive. 2294 /// 2295 static OMPParallelSectionsDirective * 2296 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2297 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 2298 bool HasCancel); 2299 2300 /// Creates an empty directive with the place for \a NumClauses 2301 /// clauses. 2302 /// 2303 /// \param C AST context. 2304 /// \param NumClauses Number of clauses. 2305 /// 2306 static OMPParallelSectionsDirective * 2307 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 2308 2309 /// Returns special task reduction reference expression. 2310 Expr *getTaskReductionRefExpr() { 2311 return cast_or_null<Expr>(Data->getChildren()[0]); 2312 } 2313 const Expr *getTaskReductionRefExpr() const { 2314 return const_cast<OMPParallelSectionsDirective *>(this) 2315 ->getTaskReductionRefExpr(); 2316 } 2317 2318 /// Return true if current directive has inner cancel directive. 2319 bool hasCancel() const { return HasCancel; } 2320 2321 static bool classof(const Stmt *T) { 2322 return T->getStmtClass() == OMPParallelSectionsDirectiveClass; 2323 } 2324 }; 2325 2326 /// This represents '#pragma omp task' directive. 2327 /// 2328 /// \code 2329 /// #pragma omp task private(a,b) final(d) 2330 /// \endcode 2331 /// In this example directive '#pragma omp task' has clauses 'private' with the 2332 /// variables 'a' and 'b' and 'final' with condition 'd'. 2333 /// 2334 class OMPTaskDirective : public OMPExecutableDirective { 2335 friend class ASTStmtReader; 2336 friend class OMPExecutableDirective; 2337 /// true if this directive has inner cancel directive. 2338 bool HasCancel = false; 2339 2340 /// Build directive with the given start and end location. 2341 /// 2342 /// \param StartLoc Starting location of the directive kind. 2343 /// \param EndLoc Ending location of the directive. 2344 /// 2345 OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2346 : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task, 2347 StartLoc, EndLoc) {} 2348 2349 /// Build an empty directive. 2350 /// 2351 explicit OMPTaskDirective() 2352 : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task, 2353 SourceLocation(), SourceLocation()) {} 2354 2355 /// Set cancel state. 2356 void setHasCancel(bool Has) { HasCancel = Has; } 2357 2358 public: 2359 /// Creates directive with a list of \a Clauses. 2360 /// 2361 /// \param C AST context. 2362 /// \param StartLoc Starting location of the directive kind. 2363 /// \param EndLoc Ending Location of the directive. 2364 /// \param Clauses List of clauses. 2365 /// \param AssociatedStmt Statement, associated with the directive. 2366 /// \param HasCancel true, if current directive has inner cancel directive. 2367 /// 2368 static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc, 2369 SourceLocation EndLoc, 2370 ArrayRef<OMPClause *> Clauses, 2371 Stmt *AssociatedStmt, bool HasCancel); 2372 2373 /// Creates an empty directive with the place for \a NumClauses 2374 /// clauses. 2375 /// 2376 /// \param C AST context. 2377 /// \param NumClauses Number of clauses. 2378 /// 2379 static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 2380 EmptyShell); 2381 2382 /// Return true if current directive has inner cancel directive. 2383 bool hasCancel() const { return HasCancel; } 2384 2385 static bool classof(const Stmt *T) { 2386 return T->getStmtClass() == OMPTaskDirectiveClass; 2387 } 2388 }; 2389 2390 /// This represents '#pragma omp taskyield' directive. 2391 /// 2392 /// \code 2393 /// #pragma omp taskyield 2394 /// \endcode 2395 /// 2396 class OMPTaskyieldDirective : public OMPExecutableDirective { 2397 friend class ASTStmtReader; 2398 friend class OMPExecutableDirective; 2399 /// Build directive with the given start and end location. 2400 /// 2401 /// \param StartLoc Starting location of the directive kind. 2402 /// \param EndLoc Ending location of the directive. 2403 /// 2404 OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2405 : OMPExecutableDirective(OMPTaskyieldDirectiveClass, 2406 llvm::omp::OMPD_taskyield, StartLoc, EndLoc) {} 2407 2408 /// Build an empty directive. 2409 /// 2410 explicit OMPTaskyieldDirective() 2411 : OMPExecutableDirective(OMPTaskyieldDirectiveClass, 2412 llvm::omp::OMPD_taskyield, SourceLocation(), 2413 SourceLocation()) {} 2414 2415 public: 2416 /// Creates directive. 2417 /// 2418 /// \param C AST context. 2419 /// \param StartLoc Starting location of the directive kind. 2420 /// \param EndLoc Ending Location of the directive. 2421 /// 2422 static OMPTaskyieldDirective * 2423 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); 2424 2425 /// Creates an empty directive. 2426 /// 2427 /// \param C AST context. 2428 /// 2429 static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell); 2430 2431 static bool classof(const Stmt *T) { 2432 return T->getStmtClass() == OMPTaskyieldDirectiveClass; 2433 } 2434 }; 2435 2436 /// This represents '#pragma omp barrier' directive. 2437 /// 2438 /// \code 2439 /// #pragma omp barrier 2440 /// \endcode 2441 /// 2442 class OMPBarrierDirective : public OMPExecutableDirective { 2443 friend class ASTStmtReader; 2444 friend class OMPExecutableDirective; 2445 /// Build directive with the given start and end location. 2446 /// 2447 /// \param StartLoc Starting location of the directive kind. 2448 /// \param EndLoc Ending location of the directive. 2449 /// 2450 OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2451 : OMPExecutableDirective(OMPBarrierDirectiveClass, 2452 llvm::omp::OMPD_barrier, StartLoc, EndLoc) {} 2453 2454 /// Build an empty directive. 2455 /// 2456 explicit OMPBarrierDirective() 2457 : OMPExecutableDirective(OMPBarrierDirectiveClass, 2458 llvm::omp::OMPD_barrier, SourceLocation(), 2459 SourceLocation()) {} 2460 2461 public: 2462 /// Creates directive. 2463 /// 2464 /// \param C AST context. 2465 /// \param StartLoc Starting location of the directive kind. 2466 /// \param EndLoc Ending Location of the directive. 2467 /// 2468 static OMPBarrierDirective * 2469 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); 2470 2471 /// Creates an empty directive. 2472 /// 2473 /// \param C AST context. 2474 /// 2475 static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell); 2476 2477 static bool classof(const Stmt *T) { 2478 return T->getStmtClass() == OMPBarrierDirectiveClass; 2479 } 2480 }; 2481 2482 /// This represents '#pragma omp taskwait' directive. 2483 /// 2484 /// \code 2485 /// #pragma omp taskwait 2486 /// \endcode 2487 /// 2488 class OMPTaskwaitDirective : public OMPExecutableDirective { 2489 friend class ASTStmtReader; 2490 friend class OMPExecutableDirective; 2491 /// Build directive with the given start and end location. 2492 /// 2493 /// \param StartLoc Starting location of the directive kind. 2494 /// \param EndLoc Ending location of the directive. 2495 /// 2496 OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2497 : OMPExecutableDirective(OMPTaskwaitDirectiveClass, 2498 llvm::omp::OMPD_taskwait, StartLoc, EndLoc) {} 2499 2500 /// Build an empty directive. 2501 /// 2502 explicit OMPTaskwaitDirective() 2503 : OMPExecutableDirective(OMPTaskwaitDirectiveClass, 2504 llvm::omp::OMPD_taskwait, SourceLocation(), 2505 SourceLocation()) {} 2506 2507 public: 2508 /// Creates directive. 2509 /// 2510 /// \param C AST context. 2511 /// \param StartLoc Starting location of the directive kind. 2512 /// \param EndLoc Ending Location of the directive. 2513 /// 2514 static OMPTaskwaitDirective * 2515 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); 2516 2517 /// Creates an empty directive. 2518 /// 2519 /// \param C AST context. 2520 /// 2521 static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell); 2522 2523 static bool classof(const Stmt *T) { 2524 return T->getStmtClass() == OMPTaskwaitDirectiveClass; 2525 } 2526 }; 2527 2528 /// This represents '#pragma omp taskgroup' directive. 2529 /// 2530 /// \code 2531 /// #pragma omp taskgroup 2532 /// \endcode 2533 /// 2534 class OMPTaskgroupDirective : public OMPExecutableDirective { 2535 friend class ASTStmtReader; 2536 friend class OMPExecutableDirective; 2537 /// Build directive with the given start and end location. 2538 /// 2539 /// \param StartLoc Starting location of the directive kind. 2540 /// \param EndLoc Ending location of the directive. 2541 /// 2542 OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2543 : OMPExecutableDirective(OMPTaskgroupDirectiveClass, 2544 llvm::omp::OMPD_taskgroup, StartLoc, EndLoc) {} 2545 2546 /// Build an empty directive. 2547 /// 2548 explicit OMPTaskgroupDirective() 2549 : OMPExecutableDirective(OMPTaskgroupDirectiveClass, 2550 llvm::omp::OMPD_taskgroup, SourceLocation(), 2551 SourceLocation()) {} 2552 2553 /// Sets the task_reduction return variable. 2554 void setReductionRef(Expr *RR) { Data->getChildren()[0] = RR; } 2555 2556 public: 2557 /// Creates directive. 2558 /// 2559 /// \param C AST context. 2560 /// \param StartLoc Starting location of the directive kind. 2561 /// \param EndLoc Ending Location of the directive. 2562 /// \param Clauses List of clauses. 2563 /// \param AssociatedStmt Statement, associated with the directive. 2564 /// \param ReductionRef Reference to the task_reduction return variable. 2565 /// 2566 static OMPTaskgroupDirective * 2567 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2568 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, 2569 Expr *ReductionRef); 2570 2571 /// Creates an empty directive. 2572 /// 2573 /// \param C AST context. 2574 /// \param NumClauses Number of clauses. 2575 /// 2576 static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, 2577 unsigned NumClauses, EmptyShell); 2578 2579 2580 /// Returns reference to the task_reduction return variable. 2581 const Expr *getReductionRef() const { 2582 return const_cast<OMPTaskgroupDirective *>(this)->getReductionRef(); 2583 } 2584 Expr *getReductionRef() { return cast_or_null<Expr>(Data->getChildren()[0]); } 2585 2586 static bool classof(const Stmt *T) { 2587 return T->getStmtClass() == OMPTaskgroupDirectiveClass; 2588 } 2589 }; 2590 2591 /// This represents '#pragma omp flush' directive. 2592 /// 2593 /// \code 2594 /// #pragma omp flush(a,b) 2595 /// \endcode 2596 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a' 2597 /// and 'b'. 2598 /// 'omp flush' directive does not have clauses but have an optional list of 2599 /// variables to flush. This list of variables is stored within some fake clause 2600 /// FlushClause. 2601 class OMPFlushDirective : public OMPExecutableDirective { 2602 friend class ASTStmtReader; 2603 friend class OMPExecutableDirective; 2604 /// Build directive with the given start and end location. 2605 /// 2606 /// \param StartLoc Starting location of the directive kind. 2607 /// \param EndLoc Ending location of the directive. 2608 /// 2609 OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2610 : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush, 2611 StartLoc, EndLoc) {} 2612 2613 /// Build an empty directive. 2614 /// 2615 explicit OMPFlushDirective() 2616 : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush, 2617 SourceLocation(), SourceLocation()) {} 2618 2619 public: 2620 /// Creates directive with a list of \a Clauses. 2621 /// 2622 /// \param C AST context. 2623 /// \param StartLoc Starting location of the directive kind. 2624 /// \param EndLoc Ending Location of the directive. 2625 /// \param Clauses List of clauses (only single OMPFlushClause clause is 2626 /// allowed). 2627 /// 2628 static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc, 2629 SourceLocation EndLoc, 2630 ArrayRef<OMPClause *> Clauses); 2631 2632 /// Creates an empty directive with the place for \a NumClauses 2633 /// clauses. 2634 /// 2635 /// \param C AST context. 2636 /// \param NumClauses Number of clauses. 2637 /// 2638 static OMPFlushDirective *CreateEmpty(const ASTContext &C, 2639 unsigned NumClauses, EmptyShell); 2640 2641 static bool classof(const Stmt *T) { 2642 return T->getStmtClass() == OMPFlushDirectiveClass; 2643 } 2644 }; 2645 2646 /// This represents '#pragma omp depobj' directive. 2647 /// 2648 /// \code 2649 /// #pragma omp depobj(a) depend(in:x,y) 2650 /// \endcode 2651 /// In this example directive '#pragma omp depobj' initializes a depobj object 2652 /// 'a' with dependence type 'in' and a list with 'x' and 'y' locators. 2653 class OMPDepobjDirective final : public OMPExecutableDirective { 2654 friend class ASTStmtReader; 2655 friend class OMPExecutableDirective; 2656 2657 /// Build directive with the given start and end location. 2658 /// 2659 /// \param StartLoc Starting location of the directive kind. 2660 /// \param EndLoc Ending location of the directive. 2661 /// 2662 OMPDepobjDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2663 : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj, 2664 StartLoc, EndLoc) {} 2665 2666 /// Build an empty directive. 2667 /// 2668 explicit OMPDepobjDirective() 2669 : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj, 2670 SourceLocation(), SourceLocation()) {} 2671 2672 public: 2673 /// Creates directive with a list of \a Clauses. 2674 /// 2675 /// \param C AST context. 2676 /// \param StartLoc Starting location of the directive kind. 2677 /// \param EndLoc Ending Location of the directive. 2678 /// \param Clauses List of clauses. 2679 /// 2680 static OMPDepobjDirective *Create(const ASTContext &C, 2681 SourceLocation StartLoc, 2682 SourceLocation EndLoc, 2683 ArrayRef<OMPClause *> Clauses); 2684 2685 /// Creates an empty directive with the place for \a NumClauses 2686 /// clauses. 2687 /// 2688 /// \param C AST context. 2689 /// \param NumClauses Number of clauses. 2690 /// 2691 static OMPDepobjDirective *CreateEmpty(const ASTContext &C, 2692 unsigned NumClauses, EmptyShell); 2693 2694 static bool classof(const Stmt *T) { 2695 return T->getStmtClass() == OMPDepobjDirectiveClass; 2696 } 2697 }; 2698 2699 /// This represents '#pragma omp ordered' directive. 2700 /// 2701 /// \code 2702 /// #pragma omp ordered 2703 /// \endcode 2704 /// 2705 class OMPOrderedDirective : public OMPExecutableDirective { 2706 friend class ASTStmtReader; 2707 friend class OMPExecutableDirective; 2708 /// Build directive with the given start and end location. 2709 /// 2710 /// \param StartLoc Starting location of the directive kind. 2711 /// \param EndLoc Ending location of the directive. 2712 /// 2713 OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2714 : OMPExecutableDirective(OMPOrderedDirectiveClass, 2715 llvm::omp::OMPD_ordered, StartLoc, EndLoc) {} 2716 2717 /// Build an empty directive. 2718 /// 2719 explicit OMPOrderedDirective() 2720 : OMPExecutableDirective(OMPOrderedDirectiveClass, 2721 llvm::omp::OMPD_ordered, SourceLocation(), 2722 SourceLocation()) {} 2723 2724 public: 2725 /// Creates directive. 2726 /// 2727 /// \param C AST context. 2728 /// \param StartLoc Starting location of the directive kind. 2729 /// \param EndLoc Ending Location of the directive. 2730 /// \param Clauses List of clauses. 2731 /// \param AssociatedStmt Statement, associated with the directive. 2732 /// 2733 static OMPOrderedDirective * 2734 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2735 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 2736 2737 /// Creates an empty directive. 2738 /// 2739 /// \param C AST context. 2740 /// \param NumClauses Number of clauses. 2741 /// \param IsStandalone true, if the the standalone directive is created. 2742 /// 2743 static OMPOrderedDirective *CreateEmpty(const ASTContext &C, 2744 unsigned NumClauses, 2745 bool IsStandalone, EmptyShell); 2746 2747 static bool classof(const Stmt *T) { 2748 return T->getStmtClass() == OMPOrderedDirectiveClass; 2749 } 2750 }; 2751 2752 /// This represents '#pragma omp atomic' directive. 2753 /// 2754 /// \code 2755 /// #pragma omp atomic capture 2756 /// \endcode 2757 /// In this example directive '#pragma omp atomic' has clause 'capture'. 2758 /// 2759 class OMPAtomicDirective : public OMPExecutableDirective { 2760 friend class ASTStmtReader; 2761 friend class OMPExecutableDirective; 2762 /// Used for 'atomic update' or 'atomic capture' constructs. They may 2763 /// have atomic expressions of forms 2764 /// \code 2765 /// x = x binop expr; 2766 /// x = expr binop x; 2767 /// \endcode 2768 /// This field is true for the first form of the expression and false for the 2769 /// second. Required for correct codegen of non-associative operations (like 2770 /// << or >>). 2771 bool IsXLHSInRHSPart = false; 2772 /// Used for 'atomic update' or 'atomic capture' constructs. They may 2773 /// have atomic expressions of forms 2774 /// \code 2775 /// v = x; <update x>; 2776 /// <update x>; v = x; 2777 /// \endcode 2778 /// This field is true for the first(postfix) form of the expression and false 2779 /// otherwise. 2780 bool IsPostfixUpdate = false; 2781 2782 /// Build directive with the given start and end location. 2783 /// 2784 /// \param StartLoc Starting location of the directive kind. 2785 /// \param EndLoc Ending location of the directive. 2786 /// 2787 OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2788 : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic, 2789 StartLoc, EndLoc) {} 2790 2791 /// Build an empty directive. 2792 /// 2793 explicit OMPAtomicDirective() 2794 : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic, 2795 SourceLocation(), SourceLocation()) {} 2796 2797 /// Set 'x' part of the associated expression/statement. 2798 void setX(Expr *X) { Data->getChildren()[0] = X; } 2799 /// Set helper expression of the form 2800 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 2801 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 2802 void setUpdateExpr(Expr *UE) { Data->getChildren()[1] = UE; } 2803 /// Set 'v' part of the associated expression/statement. 2804 void setV(Expr *V) { Data->getChildren()[2] = V; } 2805 /// Set 'expr' part of the associated expression/statement. 2806 void setExpr(Expr *E) { Data->getChildren()[3] = E; } 2807 2808 public: 2809 /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr' 2810 /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for 2811 /// detailed description of 'x', 'v' and 'expr'). 2812 /// 2813 /// \param C AST context. 2814 /// \param StartLoc Starting location of the directive kind. 2815 /// \param EndLoc Ending Location of the directive. 2816 /// \param Clauses List of clauses. 2817 /// \param AssociatedStmt Statement, associated with the directive. 2818 /// \param X 'x' part of the associated expression/statement. 2819 /// \param V 'v' part of the associated expression/statement. 2820 /// \param E 'expr' part of the associated expression/statement. 2821 /// \param UE Helper expression of the form 2822 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 2823 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 2824 /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the 2825 /// second. 2826 /// \param IsPostfixUpdate true if original value of 'x' must be stored in 2827 /// 'v', not an updated one. 2828 static OMPAtomicDirective * 2829 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2830 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V, 2831 Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate); 2832 2833 /// Creates an empty directive with the place for \a NumClauses 2834 /// clauses. 2835 /// 2836 /// \param C AST context. 2837 /// \param NumClauses Number of clauses. 2838 /// 2839 static OMPAtomicDirective *CreateEmpty(const ASTContext &C, 2840 unsigned NumClauses, EmptyShell); 2841 2842 /// Get 'x' part of the associated expression/statement. 2843 Expr *getX() { return cast_or_null<Expr>(Data->getChildren()[0]); } 2844 const Expr *getX() const { 2845 return cast_or_null<Expr>(Data->getChildren()[0]); 2846 } 2847 /// Get helper expression of the form 2848 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 2849 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 2850 Expr *getUpdateExpr() { return cast_or_null<Expr>(Data->getChildren()[1]); } 2851 const Expr *getUpdateExpr() const { 2852 return cast_or_null<Expr>(Data->getChildren()[1]); 2853 } 2854 /// Return true if helper update expression has form 2855 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form 2856 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 2857 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 2858 /// Return true if 'v' expression must be updated to original value of 2859 /// 'x', false if 'v' must be updated to the new value of 'x'. 2860 bool isPostfixUpdate() const { return IsPostfixUpdate; } 2861 /// Get 'v' part of the associated expression/statement. 2862 Expr *getV() { return cast_or_null<Expr>(Data->getChildren()[2]); } 2863 const Expr *getV() const { 2864 return cast_or_null<Expr>(Data->getChildren()[2]); 2865 } 2866 /// Get 'expr' part of the associated expression/statement. 2867 Expr *getExpr() { return cast_or_null<Expr>(Data->getChildren()[3]); } 2868 const Expr *getExpr() const { 2869 return cast_or_null<Expr>(Data->getChildren()[3]); 2870 } 2871 2872 static bool classof(const Stmt *T) { 2873 return T->getStmtClass() == OMPAtomicDirectiveClass; 2874 } 2875 }; 2876 2877 /// This represents '#pragma omp target' directive. 2878 /// 2879 /// \code 2880 /// #pragma omp target if(a) 2881 /// \endcode 2882 /// In this example directive '#pragma omp target' has clause 'if' with 2883 /// condition 'a'. 2884 /// 2885 class OMPTargetDirective : public OMPExecutableDirective { 2886 friend class ASTStmtReader; 2887 friend class OMPExecutableDirective; 2888 /// Build directive with the given start and end location. 2889 /// 2890 /// \param StartLoc Starting location of the directive kind. 2891 /// \param EndLoc Ending location of the directive. 2892 /// 2893 OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2894 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target, 2895 StartLoc, EndLoc) {} 2896 2897 /// Build an empty directive. 2898 /// 2899 explicit OMPTargetDirective() 2900 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target, 2901 SourceLocation(), SourceLocation()) {} 2902 2903 public: 2904 /// Creates directive with a list of \a Clauses. 2905 /// 2906 /// \param C AST context. 2907 /// \param StartLoc Starting location of the directive kind. 2908 /// \param EndLoc Ending Location of the directive. 2909 /// \param Clauses List of clauses. 2910 /// \param AssociatedStmt Statement, associated with the directive. 2911 /// 2912 static OMPTargetDirective * 2913 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2914 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 2915 2916 /// Creates an empty directive with the place for \a NumClauses 2917 /// clauses. 2918 /// 2919 /// \param C AST context. 2920 /// \param NumClauses Number of clauses. 2921 /// 2922 static OMPTargetDirective *CreateEmpty(const ASTContext &C, 2923 unsigned NumClauses, EmptyShell); 2924 2925 static bool classof(const Stmt *T) { 2926 return T->getStmtClass() == OMPTargetDirectiveClass; 2927 } 2928 }; 2929 2930 /// This represents '#pragma omp target data' directive. 2931 /// 2932 /// \code 2933 /// #pragma omp target data device(0) if(a) map(b[:]) 2934 /// \endcode 2935 /// In this example directive '#pragma omp target data' has clauses 'device' 2936 /// with the value '0', 'if' with condition 'a' and 'map' with array 2937 /// section 'b[:]'. 2938 /// 2939 class OMPTargetDataDirective : public OMPExecutableDirective { 2940 friend class ASTStmtReader; 2941 friend class OMPExecutableDirective; 2942 /// Build directive with the given start and end location. 2943 /// 2944 /// \param StartLoc Starting location of the directive kind. 2945 /// \param EndLoc Ending Location of the directive. 2946 /// 2947 OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2948 : OMPExecutableDirective(OMPTargetDataDirectiveClass, 2949 llvm::omp::OMPD_target_data, StartLoc, EndLoc) {} 2950 2951 /// Build an empty directive. 2952 /// 2953 explicit OMPTargetDataDirective() 2954 : OMPExecutableDirective(OMPTargetDataDirectiveClass, 2955 llvm::omp::OMPD_target_data, SourceLocation(), 2956 SourceLocation()) {} 2957 2958 public: 2959 /// Creates directive with a list of \a Clauses. 2960 /// 2961 /// \param C AST context. 2962 /// \param StartLoc Starting location of the directive kind. 2963 /// \param EndLoc Ending Location of the directive. 2964 /// \param Clauses List of clauses. 2965 /// \param AssociatedStmt Statement, associated with the directive. 2966 /// 2967 static OMPTargetDataDirective * 2968 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2969 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 2970 2971 /// Creates an empty directive with the place for \a N clauses. 2972 /// 2973 /// \param C AST context. 2974 /// \param N The number of clauses. 2975 /// 2976 static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N, 2977 EmptyShell); 2978 2979 static bool classof(const Stmt *T) { 2980 return T->getStmtClass() == OMPTargetDataDirectiveClass; 2981 } 2982 }; 2983 2984 /// This represents '#pragma omp target enter data' directive. 2985 /// 2986 /// \code 2987 /// #pragma omp target enter data device(0) if(a) map(b[:]) 2988 /// \endcode 2989 /// In this example directive '#pragma omp target enter data' has clauses 2990 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array 2991 /// section 'b[:]'. 2992 /// 2993 class OMPTargetEnterDataDirective : public OMPExecutableDirective { 2994 friend class ASTStmtReader; 2995 friend class OMPExecutableDirective; 2996 /// Build directive with the given start and end location. 2997 /// 2998 /// \param StartLoc Starting location of the directive kind. 2999 /// \param EndLoc Ending Location of the directive. 3000 /// 3001 OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3002 : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass, 3003 llvm::omp::OMPD_target_enter_data, StartLoc, 3004 EndLoc) {} 3005 3006 /// Build an empty directive. 3007 /// 3008 explicit OMPTargetEnterDataDirective() 3009 : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass, 3010 llvm::omp::OMPD_target_enter_data, 3011 SourceLocation(), SourceLocation()) {} 3012 3013 public: 3014 /// Creates directive with a list of \a Clauses. 3015 /// 3016 /// \param C AST context. 3017 /// \param StartLoc Starting location of the directive kind. 3018 /// \param EndLoc Ending Location of the directive. 3019 /// \param Clauses List of clauses. 3020 /// \param AssociatedStmt Statement, associated with the directive. 3021 /// 3022 static OMPTargetEnterDataDirective * 3023 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3024 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 3025 3026 /// Creates an empty directive with the place for \a N clauses. 3027 /// 3028 /// \param C AST context. 3029 /// \param N The number of clauses. 3030 /// 3031 static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C, 3032 unsigned N, EmptyShell); 3033 3034 static bool classof(const Stmt *T) { 3035 return T->getStmtClass() == OMPTargetEnterDataDirectiveClass; 3036 } 3037 }; 3038 3039 /// This represents '#pragma omp target exit data' directive. 3040 /// 3041 /// \code 3042 /// #pragma omp target exit data device(0) if(a) map(b[:]) 3043 /// \endcode 3044 /// In this example directive '#pragma omp target exit data' has clauses 3045 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array 3046 /// section 'b[:]'. 3047 /// 3048 class OMPTargetExitDataDirective : public OMPExecutableDirective { 3049 friend class ASTStmtReader; 3050 friend class OMPExecutableDirective; 3051 /// Build directive with the given start and end location. 3052 /// 3053 /// \param StartLoc Starting location of the directive kind. 3054 /// \param EndLoc Ending Location of the directive. 3055 /// 3056 OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3057 : OMPExecutableDirective(OMPTargetExitDataDirectiveClass, 3058 llvm::omp::OMPD_target_exit_data, StartLoc, 3059 EndLoc) {} 3060 3061 /// Build an empty directive. 3062 /// 3063 explicit OMPTargetExitDataDirective() 3064 : OMPExecutableDirective(OMPTargetExitDataDirectiveClass, 3065 llvm::omp::OMPD_target_exit_data, 3066 SourceLocation(), SourceLocation()) {} 3067 3068 public: 3069 /// Creates directive with a list of \a Clauses. 3070 /// 3071 /// \param C AST context. 3072 /// \param StartLoc Starting location of the directive kind. 3073 /// \param EndLoc Ending Location of the directive. 3074 /// \param Clauses List of clauses. 3075 /// \param AssociatedStmt Statement, associated with the directive. 3076 /// 3077 static OMPTargetExitDataDirective * 3078 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3079 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 3080 3081 /// Creates an empty directive with the place for \a N clauses. 3082 /// 3083 /// \param C AST context. 3084 /// \param N The number of clauses. 3085 /// 3086 static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C, 3087 unsigned N, EmptyShell); 3088 3089 static bool classof(const Stmt *T) { 3090 return T->getStmtClass() == OMPTargetExitDataDirectiveClass; 3091 } 3092 }; 3093 3094 /// This represents '#pragma omp target parallel' directive. 3095 /// 3096 /// \code 3097 /// #pragma omp target parallel if(a) 3098 /// \endcode 3099 /// In this example directive '#pragma omp target parallel' has clause 'if' with 3100 /// condition 'a'. 3101 /// 3102 class OMPTargetParallelDirective : public OMPExecutableDirective { 3103 friend class ASTStmtReader; 3104 friend class OMPExecutableDirective; 3105 /// true if the construct has inner cancel directive. 3106 bool HasCancel = false; 3107 3108 /// Build directive with the given start and end location. 3109 /// 3110 /// \param StartLoc Starting location of the directive kind. 3111 /// \param EndLoc Ending location of the directive. 3112 /// 3113 OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3114 : OMPExecutableDirective(OMPTargetParallelDirectiveClass, 3115 llvm::omp::OMPD_target_parallel, StartLoc, 3116 EndLoc) {} 3117 3118 /// Build an empty directive. 3119 /// 3120 explicit OMPTargetParallelDirective() 3121 : OMPExecutableDirective(OMPTargetParallelDirectiveClass, 3122 llvm::omp::OMPD_target_parallel, 3123 SourceLocation(), SourceLocation()) {} 3124 3125 /// Sets special task reduction descriptor. 3126 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 3127 /// Set cancel state. 3128 void setHasCancel(bool Has) { HasCancel = Has; } 3129 3130 public: 3131 /// Creates directive with a list of \a Clauses. 3132 /// 3133 /// \param C AST context. 3134 /// \param StartLoc Starting location of the directive kind. 3135 /// \param EndLoc Ending Location of the directive. 3136 /// \param Clauses List of clauses. 3137 /// \param AssociatedStmt Statement, associated with the directive. 3138 /// \param TaskRedRef Task reduction special reference expression to handle 3139 /// taskgroup descriptor. 3140 /// \param HasCancel true if this directive has inner cancel directive. 3141 /// 3142 static OMPTargetParallelDirective * 3143 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3144 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 3145 bool HasCancel); 3146 3147 /// Creates an empty directive with the place for \a NumClauses 3148 /// clauses. 3149 /// 3150 /// \param C AST context. 3151 /// \param NumClauses Number of clauses. 3152 /// 3153 static OMPTargetParallelDirective * 3154 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 3155 3156 /// Returns special task reduction reference expression. 3157 Expr *getTaskReductionRefExpr() { 3158 return cast_or_null<Expr>(Data->getChildren()[0]); 3159 } 3160 const Expr *getTaskReductionRefExpr() const { 3161 return const_cast<OMPTargetParallelDirective *>(this) 3162 ->getTaskReductionRefExpr(); 3163 } 3164 3165 /// Return true if current directive has inner cancel directive. 3166 bool hasCancel() const { return HasCancel; } 3167 3168 static bool classof(const Stmt *T) { 3169 return T->getStmtClass() == OMPTargetParallelDirectiveClass; 3170 } 3171 }; 3172 3173 /// This represents '#pragma omp target parallel for' directive. 3174 /// 3175 /// \code 3176 /// #pragma omp target parallel for private(a,b) reduction(+:c,d) 3177 /// \endcode 3178 /// In this example directive '#pragma omp target parallel for' has clauses 3179 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' 3180 /// and variables 'c' and 'd'. 3181 /// 3182 class OMPTargetParallelForDirective : public OMPLoopDirective { 3183 friend class ASTStmtReader; 3184 friend class OMPExecutableDirective; 3185 3186 /// true if current region has inner cancel directive. 3187 bool HasCancel = false; 3188 3189 /// Build directive with the given start and end location. 3190 /// 3191 /// \param StartLoc Starting location of the directive kind. 3192 /// \param EndLoc Ending location of the directive. 3193 /// \param CollapsedNum Number of collapsed nested loops. 3194 /// 3195 OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3196 unsigned CollapsedNum) 3197 : OMPLoopDirective(OMPTargetParallelForDirectiveClass, 3198 llvm::omp::OMPD_target_parallel_for, StartLoc, EndLoc, 3199 CollapsedNum) {} 3200 3201 /// Build an empty directive. 3202 /// 3203 /// \param CollapsedNum Number of collapsed nested loops. 3204 /// 3205 explicit OMPTargetParallelForDirective(unsigned CollapsedNum) 3206 : OMPLoopDirective(OMPTargetParallelForDirectiveClass, 3207 llvm::omp::OMPD_target_parallel_for, SourceLocation(), 3208 SourceLocation(), CollapsedNum) {} 3209 3210 /// Sets special task reduction descriptor. 3211 void setTaskReductionRefExpr(Expr *E) { 3212 Data->getChildren()[numLoopChildren( 3213 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)] = E; 3214 } 3215 3216 /// Set cancel state. 3217 void setHasCancel(bool Has) { HasCancel = Has; } 3218 3219 public: 3220 /// Creates directive with a list of \a Clauses. 3221 /// 3222 /// \param C AST context. 3223 /// \param StartLoc Starting location of the directive kind. 3224 /// \param EndLoc Ending Location of the directive. 3225 /// \param CollapsedNum Number of collapsed loops. 3226 /// \param Clauses List of clauses. 3227 /// \param AssociatedStmt Statement, associated with the directive. 3228 /// \param Exprs Helper expressions for CodeGen. 3229 /// \param TaskRedRef Task reduction special reference expression to handle 3230 /// taskgroup descriptor. 3231 /// \param HasCancel true if current directive has inner cancel directive. 3232 /// 3233 static OMPTargetParallelForDirective * 3234 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3235 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3236 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 3237 bool HasCancel); 3238 3239 /// Creates an empty directive with the place 3240 /// for \a NumClauses clauses. 3241 /// 3242 /// \param C AST context. 3243 /// \param CollapsedNum Number of collapsed nested loops. 3244 /// \param NumClauses Number of clauses. 3245 /// 3246 static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C, 3247 unsigned NumClauses, 3248 unsigned CollapsedNum, 3249 EmptyShell); 3250 3251 /// Returns special task reduction reference expression. 3252 Expr *getTaskReductionRefExpr() { 3253 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 3254 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)]); 3255 } 3256 const Expr *getTaskReductionRefExpr() const { 3257 return const_cast<OMPTargetParallelForDirective *>(this) 3258 ->getTaskReductionRefExpr(); 3259 } 3260 3261 /// Return true if current directive has inner cancel directive. 3262 bool hasCancel() const { return HasCancel; } 3263 3264 static bool classof(const Stmt *T) { 3265 return T->getStmtClass() == OMPTargetParallelForDirectiveClass; 3266 } 3267 }; 3268 3269 /// This represents '#pragma omp teams' directive. 3270 /// 3271 /// \code 3272 /// #pragma omp teams if(a) 3273 /// \endcode 3274 /// In this example directive '#pragma omp teams' has clause 'if' with 3275 /// condition 'a'. 3276 /// 3277 class OMPTeamsDirective : public OMPExecutableDirective { 3278 friend class ASTStmtReader; 3279 friend class OMPExecutableDirective; 3280 /// Build directive with the given start and end location. 3281 /// 3282 /// \param StartLoc Starting location of the directive kind. 3283 /// \param EndLoc Ending location of the directive. 3284 /// 3285 OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3286 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams, 3287 StartLoc, EndLoc) {} 3288 3289 /// Build an empty directive. 3290 /// 3291 explicit OMPTeamsDirective() 3292 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams, 3293 SourceLocation(), SourceLocation()) {} 3294 3295 public: 3296 /// Creates directive with a list of \a Clauses. 3297 /// 3298 /// \param C AST context. 3299 /// \param StartLoc Starting location of the directive kind. 3300 /// \param EndLoc Ending Location of the directive. 3301 /// \param Clauses List of clauses. 3302 /// \param AssociatedStmt Statement, associated with the directive. 3303 /// 3304 static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc, 3305 SourceLocation EndLoc, 3306 ArrayRef<OMPClause *> Clauses, 3307 Stmt *AssociatedStmt); 3308 3309 /// Creates an empty directive with the place for \a NumClauses 3310 /// clauses. 3311 /// 3312 /// \param C AST context. 3313 /// \param NumClauses Number of clauses. 3314 /// 3315 static OMPTeamsDirective *CreateEmpty(const ASTContext &C, 3316 unsigned NumClauses, EmptyShell); 3317 3318 static bool classof(const Stmt *T) { 3319 return T->getStmtClass() == OMPTeamsDirectiveClass; 3320 } 3321 }; 3322 3323 /// This represents '#pragma omp cancellation point' directive. 3324 /// 3325 /// \code 3326 /// #pragma omp cancellation point for 3327 /// \endcode 3328 /// 3329 /// In this example a cancellation point is created for innermost 'for' region. 3330 class OMPCancellationPointDirective : public OMPExecutableDirective { 3331 friend class ASTStmtReader; 3332 friend class OMPExecutableDirective; 3333 OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown; 3334 /// Build directive with the given start and end location. 3335 /// 3336 /// \param StartLoc Starting location of the directive kind. 3337 /// \param EndLoc Ending location of the directive. 3338 /// statements and child expressions. 3339 /// 3340 OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3341 : OMPExecutableDirective(OMPCancellationPointDirectiveClass, 3342 llvm::omp::OMPD_cancellation_point, StartLoc, 3343 EndLoc) {} 3344 3345 /// Build an empty directive. 3346 explicit OMPCancellationPointDirective() 3347 : OMPExecutableDirective(OMPCancellationPointDirectiveClass, 3348 llvm::omp::OMPD_cancellation_point, 3349 SourceLocation(), SourceLocation()) {} 3350 3351 /// Set cancel region for current cancellation point. 3352 /// \param CR Cancellation region. 3353 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } 3354 3355 public: 3356 /// Creates directive. 3357 /// 3358 /// \param C AST context. 3359 /// \param StartLoc Starting location of the directive kind. 3360 /// \param EndLoc Ending Location of the directive. 3361 /// 3362 static OMPCancellationPointDirective * 3363 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3364 OpenMPDirectiveKind CancelRegion); 3365 3366 /// Creates an empty directive. 3367 /// 3368 /// \param C AST context. 3369 /// 3370 static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C, 3371 EmptyShell); 3372 3373 /// Get cancellation region for the current cancellation point. 3374 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } 3375 3376 static bool classof(const Stmt *T) { 3377 return T->getStmtClass() == OMPCancellationPointDirectiveClass; 3378 } 3379 }; 3380 3381 /// This represents '#pragma omp cancel' directive. 3382 /// 3383 /// \code 3384 /// #pragma omp cancel for 3385 /// \endcode 3386 /// 3387 /// In this example a cancel is created for innermost 'for' region. 3388 class OMPCancelDirective : public OMPExecutableDirective { 3389 friend class ASTStmtReader; 3390 friend class OMPExecutableDirective; 3391 OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown; 3392 /// Build directive with the given start and end location. 3393 /// 3394 /// \param StartLoc Starting location of the directive kind. 3395 /// \param EndLoc Ending location of the directive. 3396 /// 3397 OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3398 : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel, 3399 StartLoc, EndLoc) {} 3400 3401 /// Build an empty directive. 3402 /// 3403 explicit OMPCancelDirective() 3404 : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel, 3405 SourceLocation(), SourceLocation()) {} 3406 3407 /// Set cancel region for current cancellation point. 3408 /// \param CR Cancellation region. 3409 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } 3410 3411 public: 3412 /// Creates directive. 3413 /// 3414 /// \param C AST context. 3415 /// \param StartLoc Starting location of the directive kind. 3416 /// \param EndLoc Ending Location of the directive. 3417 /// \param Clauses List of clauses. 3418 /// 3419 static OMPCancelDirective * 3420 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3421 ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion); 3422 3423 /// Creates an empty directive. 3424 /// 3425 /// \param C AST context. 3426 /// \param NumClauses Number of clauses. 3427 /// 3428 static OMPCancelDirective *CreateEmpty(const ASTContext &C, 3429 unsigned NumClauses, EmptyShell); 3430 3431 /// Get cancellation region for the current cancellation point. 3432 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } 3433 3434 static bool classof(const Stmt *T) { 3435 return T->getStmtClass() == OMPCancelDirectiveClass; 3436 } 3437 }; 3438 3439 /// This represents '#pragma omp taskloop' directive. 3440 /// 3441 /// \code 3442 /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num) 3443 /// \endcode 3444 /// In this example directive '#pragma omp taskloop' has clauses 'private' 3445 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and 3446 /// 'num_tasks' with expression 'num'. 3447 /// 3448 class OMPTaskLoopDirective : public OMPLoopDirective { 3449 friend class ASTStmtReader; 3450 friend class OMPExecutableDirective; 3451 /// true if the construct has inner cancel directive. 3452 bool HasCancel = false; 3453 3454 /// Build directive with the given start and end location. 3455 /// 3456 /// \param StartLoc Starting location of the directive kind. 3457 /// \param EndLoc Ending location of the directive. 3458 /// \param CollapsedNum Number of collapsed nested loops. 3459 /// 3460 OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3461 unsigned CollapsedNum) 3462 : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop, 3463 StartLoc, EndLoc, CollapsedNum) {} 3464 3465 /// Build an empty directive. 3466 /// 3467 /// \param CollapsedNum Number of collapsed nested loops. 3468 /// 3469 explicit OMPTaskLoopDirective(unsigned CollapsedNum) 3470 : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop, 3471 SourceLocation(), SourceLocation(), CollapsedNum) {} 3472 3473 /// Set cancel state. 3474 void setHasCancel(bool Has) { HasCancel = Has; } 3475 3476 public: 3477 /// Creates directive with a list of \a Clauses. 3478 /// 3479 /// \param C AST context. 3480 /// \param StartLoc Starting location of the directive kind. 3481 /// \param EndLoc Ending Location of the directive. 3482 /// \param CollapsedNum Number of collapsed loops. 3483 /// \param Clauses List of clauses. 3484 /// \param AssociatedStmt Statement, associated with the directive. 3485 /// \param Exprs Helper expressions for CodeGen. 3486 /// \param HasCancel true if this directive has inner cancel directive. 3487 /// 3488 static OMPTaskLoopDirective * 3489 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3490 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3491 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 3492 3493 /// Creates an empty directive with the place 3494 /// for \a NumClauses clauses. 3495 /// 3496 /// \param C AST context. 3497 /// \param CollapsedNum Number of collapsed nested loops. 3498 /// \param NumClauses Number of clauses. 3499 /// 3500 static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C, 3501 unsigned NumClauses, 3502 unsigned CollapsedNum, EmptyShell); 3503 3504 /// Return true if current directive has inner cancel directive. 3505 bool hasCancel() const { return HasCancel; } 3506 3507 static bool classof(const Stmt *T) { 3508 return T->getStmtClass() == OMPTaskLoopDirectiveClass; 3509 } 3510 }; 3511 3512 /// This represents '#pragma omp taskloop simd' directive. 3513 /// 3514 /// \code 3515 /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num) 3516 /// \endcode 3517 /// In this example directive '#pragma omp taskloop simd' has clauses 'private' 3518 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and 3519 /// 'num_tasks' with expression 'num'. 3520 /// 3521 class OMPTaskLoopSimdDirective : public OMPLoopDirective { 3522 friend class ASTStmtReader; 3523 friend class OMPExecutableDirective; 3524 /// Build directive with the given start and end location. 3525 /// 3526 /// \param StartLoc Starting location of the directive kind. 3527 /// \param EndLoc Ending location of the directive. 3528 /// \param CollapsedNum Number of collapsed nested loops. 3529 /// 3530 OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3531 unsigned CollapsedNum) 3532 : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass, 3533 llvm::omp::OMPD_taskloop_simd, StartLoc, EndLoc, 3534 CollapsedNum) {} 3535 3536 /// Build an empty directive. 3537 /// 3538 /// \param CollapsedNum Number of collapsed nested loops. 3539 /// 3540 explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum) 3541 : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass, 3542 llvm::omp::OMPD_taskloop_simd, SourceLocation(), 3543 SourceLocation(), CollapsedNum) {} 3544 3545 public: 3546 /// Creates directive with a list of \a Clauses. 3547 /// 3548 /// \param C AST context. 3549 /// \param StartLoc Starting location of the directive kind. 3550 /// \param EndLoc Ending Location of the directive. 3551 /// \param CollapsedNum Number of collapsed loops. 3552 /// \param Clauses List of clauses. 3553 /// \param AssociatedStmt Statement, associated with the directive. 3554 /// \param Exprs Helper expressions for CodeGen. 3555 /// 3556 static OMPTaskLoopSimdDirective * 3557 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3558 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3559 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3560 3561 /// Creates an empty directive with the place 3562 /// for \a NumClauses clauses. 3563 /// 3564 /// \param C AST context. 3565 /// \param CollapsedNum Number of collapsed nested loops. 3566 /// \param NumClauses Number of clauses. 3567 /// 3568 static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, 3569 unsigned NumClauses, 3570 unsigned CollapsedNum, 3571 EmptyShell); 3572 3573 static bool classof(const Stmt *T) { 3574 return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass; 3575 } 3576 }; 3577 3578 /// This represents '#pragma omp master taskloop' directive. 3579 /// 3580 /// \code 3581 /// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num) 3582 /// \endcode 3583 /// In this example directive '#pragma omp master taskloop' has clauses 3584 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 3585 /// and 'num_tasks' with expression 'num'. 3586 /// 3587 class OMPMasterTaskLoopDirective : public OMPLoopDirective { 3588 friend class ASTStmtReader; 3589 friend class OMPExecutableDirective; 3590 /// true if the construct has inner cancel directive. 3591 bool HasCancel = false; 3592 3593 /// Build directive with the given start and end location. 3594 /// 3595 /// \param StartLoc Starting location of the directive kind. 3596 /// \param EndLoc Ending location of the directive. 3597 /// \param CollapsedNum Number of collapsed nested loops. 3598 /// 3599 OMPMasterTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3600 unsigned CollapsedNum) 3601 : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass, 3602 llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc, 3603 CollapsedNum) {} 3604 3605 /// Build an empty directive. 3606 /// 3607 /// \param CollapsedNum Number of collapsed nested loops. 3608 /// 3609 explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum) 3610 : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass, 3611 llvm::omp::OMPD_master_taskloop, SourceLocation(), 3612 SourceLocation(), CollapsedNum) {} 3613 3614 /// Set cancel state. 3615 void setHasCancel(bool Has) { HasCancel = Has; } 3616 3617 public: 3618 /// Creates directive with a list of \a Clauses. 3619 /// 3620 /// \param C AST context. 3621 /// \param StartLoc Starting location of the directive kind. 3622 /// \param EndLoc Ending Location of the directive. 3623 /// \param CollapsedNum Number of collapsed loops. 3624 /// \param Clauses List of clauses. 3625 /// \param AssociatedStmt Statement, associated with the directive. 3626 /// \param Exprs Helper expressions for CodeGen. 3627 /// \param HasCancel true if this directive has inner cancel directive. 3628 /// 3629 static OMPMasterTaskLoopDirective * 3630 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3631 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3632 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 3633 3634 /// Creates an empty directive with the place 3635 /// for \a NumClauses clauses. 3636 /// 3637 /// \param C AST context. 3638 /// \param CollapsedNum Number of collapsed nested loops. 3639 /// \param NumClauses Number of clauses. 3640 /// 3641 static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C, 3642 unsigned NumClauses, 3643 unsigned CollapsedNum, 3644 EmptyShell); 3645 3646 /// Return true if current directive has inner cancel directive. 3647 bool hasCancel() const { return HasCancel; } 3648 3649 static bool classof(const Stmt *T) { 3650 return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass; 3651 } 3652 }; 3653 3654 /// This represents '#pragma omp master taskloop simd' directive. 3655 /// 3656 /// \code 3657 /// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num) 3658 /// \endcode 3659 /// In this example directive '#pragma omp master taskloop simd' has clauses 3660 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 3661 /// and 'num_tasks' with expression 'num'. 3662 /// 3663 class OMPMasterTaskLoopSimdDirective : public OMPLoopDirective { 3664 friend class ASTStmtReader; 3665 friend class OMPExecutableDirective; 3666 /// Build directive with the given start and end location. 3667 /// 3668 /// \param StartLoc Starting location of the directive kind. 3669 /// \param EndLoc Ending location of the directive. 3670 /// \param CollapsedNum Number of collapsed nested loops. 3671 /// 3672 OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3673 unsigned CollapsedNum) 3674 : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass, 3675 llvm::omp::OMPD_master_taskloop_simd, StartLoc, EndLoc, 3676 CollapsedNum) {} 3677 3678 /// Build an empty directive. 3679 /// 3680 /// \param CollapsedNum Number of collapsed nested loops. 3681 /// 3682 explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum) 3683 : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass, 3684 llvm::omp::OMPD_master_taskloop_simd, SourceLocation(), 3685 SourceLocation(), CollapsedNum) {} 3686 3687 public: 3688 /// Creates directive with a list of \p 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 /// 3698 static OMPMasterTaskLoopSimdDirective * 3699 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3700 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3701 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3702 3703 /// Creates an empty directive with the place for \p NumClauses clauses. 3704 /// 3705 /// \param C AST context. 3706 /// \param CollapsedNum Number of collapsed nested loops. 3707 /// \param NumClauses Number of clauses. 3708 /// 3709 static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, 3710 unsigned NumClauses, 3711 unsigned CollapsedNum, 3712 EmptyShell); 3713 3714 static bool classof(const Stmt *T) { 3715 return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass; 3716 } 3717 }; 3718 3719 /// This represents '#pragma omp parallel master taskloop' directive. 3720 /// 3721 /// \code 3722 /// #pragma omp parallel master taskloop private(a,b) grainsize(val) 3723 /// num_tasks(num) 3724 /// \endcode 3725 /// In this example directive '#pragma omp parallel master taskloop' has clauses 3726 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 3727 /// and 'num_tasks' with expression 'num'. 3728 /// 3729 class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective { 3730 friend class ASTStmtReader; 3731 friend class OMPExecutableDirective; 3732 /// true if the construct has inner cancel directive. 3733 bool HasCancel = false; 3734 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 OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc, 3742 SourceLocation EndLoc, 3743 unsigned CollapsedNum) 3744 : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass, 3745 llvm::omp::OMPD_parallel_master_taskloop, StartLoc, 3746 EndLoc, CollapsedNum) {} 3747 3748 /// Build an empty directive. 3749 /// 3750 /// \param CollapsedNum Number of collapsed nested loops. 3751 /// 3752 explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum) 3753 : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass, 3754 llvm::omp::OMPD_parallel_master_taskloop, 3755 SourceLocation(), SourceLocation(), CollapsedNum) {} 3756 3757 /// Set cancel state. 3758 void setHasCancel(bool Has) { HasCancel = Has; } 3759 3760 public: 3761 /// Creates directive with a list of \a Clauses. 3762 /// 3763 /// \param C AST context. 3764 /// \param StartLoc Starting location of the directive kind. 3765 /// \param EndLoc Ending Location of the directive. 3766 /// \param CollapsedNum Number of collapsed loops. 3767 /// \param Clauses List of clauses. 3768 /// \param AssociatedStmt Statement, associated with the directive. 3769 /// \param Exprs Helper expressions for CodeGen. 3770 /// \param HasCancel true if this directive has inner cancel directive. 3771 /// 3772 static OMPParallelMasterTaskLoopDirective * 3773 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3774 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3775 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 3776 3777 /// Creates an empty directive with the place 3778 /// for \a NumClauses clauses. 3779 /// 3780 /// \param C AST context. 3781 /// \param CollapsedNum Number of collapsed nested loops. 3782 /// \param NumClauses Number of clauses. 3783 /// 3784 static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C, 3785 unsigned NumClauses, 3786 unsigned CollapsedNum, 3787 EmptyShell); 3788 3789 /// Return true if current directive has inner cancel directive. 3790 bool hasCancel() const { return HasCancel; } 3791 3792 static bool classof(const Stmt *T) { 3793 return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass; 3794 } 3795 }; 3796 3797 /// This represents '#pragma omp parallel master taskloop simd' directive. 3798 /// 3799 /// \code 3800 /// #pragma omp parallel master taskloop simd private(a,b) grainsize(val) 3801 /// num_tasks(num) 3802 /// \endcode 3803 /// In this example directive '#pragma omp parallel master taskloop simd' has 3804 /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with 3805 /// expression 'val' and 'num_tasks' with expression 'num'. 3806 /// 3807 class OMPParallelMasterTaskLoopSimdDirective : public OMPLoopDirective { 3808 friend class ASTStmtReader; 3809 friend class OMPExecutableDirective; 3810 /// Build directive with the given start and end location. 3811 /// 3812 /// \param StartLoc Starting location of the directive kind. 3813 /// \param EndLoc Ending location of the directive. 3814 /// \param CollapsedNum Number of collapsed nested loops. 3815 /// 3816 OMPParallelMasterTaskLoopSimdDirective(SourceLocation StartLoc, 3817 SourceLocation EndLoc, 3818 unsigned CollapsedNum) 3819 : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass, 3820 llvm::omp::OMPD_parallel_master_taskloop_simd, 3821 StartLoc, EndLoc, CollapsedNum) {} 3822 3823 /// Build an empty directive. 3824 /// 3825 /// \param CollapsedNum Number of collapsed nested loops. 3826 /// 3827 explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum) 3828 : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass, 3829 llvm::omp::OMPD_parallel_master_taskloop_simd, 3830 SourceLocation(), SourceLocation(), CollapsedNum) {} 3831 3832 public: 3833 /// Creates directive with a list of \p Clauses. 3834 /// 3835 /// \param C AST context. 3836 /// \param StartLoc Starting location of the directive kind. 3837 /// \param EndLoc Ending Location of the directive. 3838 /// \param CollapsedNum Number of collapsed loops. 3839 /// \param Clauses List of clauses. 3840 /// \param AssociatedStmt Statement, associated with the directive. 3841 /// \param Exprs Helper expressions for CodeGen. 3842 /// 3843 static OMPParallelMasterTaskLoopSimdDirective * 3844 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3845 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3846 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3847 3848 /// Creates an empty directive with the place 3849 /// for \a NumClauses clauses. 3850 /// 3851 /// \param C AST context. 3852 /// \param CollapsedNum Number of collapsed nested loops. 3853 /// \param NumClauses Number of clauses. 3854 /// 3855 static OMPParallelMasterTaskLoopSimdDirective * 3856 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 3857 EmptyShell); 3858 3859 static bool classof(const Stmt *T) { 3860 return T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass; 3861 } 3862 }; 3863 3864 /// This represents '#pragma omp distribute' directive. 3865 /// 3866 /// \code 3867 /// #pragma omp distribute private(a,b) 3868 /// \endcode 3869 /// In this example directive '#pragma omp distribute' has clauses 'private' 3870 /// with the variables 'a' and 'b' 3871 /// 3872 class OMPDistributeDirective : public OMPLoopDirective { 3873 friend class ASTStmtReader; 3874 friend class OMPExecutableDirective; 3875 3876 /// Build directive with the given start and end location. 3877 /// 3878 /// \param StartLoc Starting location of the directive kind. 3879 /// \param EndLoc Ending location of the directive. 3880 /// \param CollapsedNum Number of collapsed nested loops. 3881 /// 3882 OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3883 unsigned CollapsedNum) 3884 : OMPLoopDirective(OMPDistributeDirectiveClass, 3885 llvm::omp::OMPD_distribute, StartLoc, EndLoc, 3886 CollapsedNum) {} 3887 3888 /// Build an empty directive. 3889 /// 3890 /// \param CollapsedNum Number of collapsed nested loops. 3891 /// 3892 explicit OMPDistributeDirective(unsigned CollapsedNum) 3893 : OMPLoopDirective(OMPDistributeDirectiveClass, 3894 llvm::omp::OMPD_distribute, SourceLocation(), 3895 SourceLocation(), CollapsedNum) {} 3896 3897 public: 3898 /// Creates directive with a list of \a Clauses. 3899 /// 3900 /// \param C AST context. 3901 /// \param StartLoc Starting location of the directive kind. 3902 /// \param EndLoc Ending Location of the directive. 3903 /// \param CollapsedNum Number of collapsed loops. 3904 /// \param Clauses List of clauses. 3905 /// \param AssociatedStmt Statement, associated with the directive. 3906 /// \param Exprs Helper expressions for CodeGen. 3907 /// 3908 static OMPDistributeDirective * 3909 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3910 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3911 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3912 3913 /// Creates an empty directive with the place 3914 /// for \a NumClauses clauses. 3915 /// 3916 /// \param C AST context. 3917 /// \param CollapsedNum Number of collapsed nested loops. 3918 /// \param NumClauses Number of clauses. 3919 /// 3920 static OMPDistributeDirective *CreateEmpty(const ASTContext &C, 3921 unsigned NumClauses, 3922 unsigned CollapsedNum, EmptyShell); 3923 3924 static bool classof(const Stmt *T) { 3925 return T->getStmtClass() == OMPDistributeDirectiveClass; 3926 } 3927 }; 3928 3929 /// This represents '#pragma omp target update' directive. 3930 /// 3931 /// \code 3932 /// #pragma omp target update to(a) from(b) device(1) 3933 /// \endcode 3934 /// In this example directive '#pragma omp target update' has clause 'to' with 3935 /// argument 'a', clause 'from' with argument 'b' and clause 'device' with 3936 /// argument '1'. 3937 /// 3938 class OMPTargetUpdateDirective : public OMPExecutableDirective { 3939 friend class ASTStmtReader; 3940 friend class OMPExecutableDirective; 3941 /// Build directive with the given start and end location. 3942 /// 3943 /// \param StartLoc Starting location of the directive kind. 3944 /// \param EndLoc Ending Location of the directive. 3945 /// 3946 OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3947 : OMPExecutableDirective(OMPTargetUpdateDirectiveClass, 3948 llvm::omp::OMPD_target_update, StartLoc, 3949 EndLoc) {} 3950 3951 /// Build an empty directive. 3952 /// 3953 explicit OMPTargetUpdateDirective() 3954 : OMPExecutableDirective(OMPTargetUpdateDirectiveClass, 3955 llvm::omp::OMPD_target_update, SourceLocation(), 3956 SourceLocation()) {} 3957 3958 public: 3959 /// Creates directive with a list of \a Clauses. 3960 /// 3961 /// \param C AST context. 3962 /// \param StartLoc Starting location of the directive kind. 3963 /// \param EndLoc Ending Location of the directive. 3964 /// \param Clauses List of clauses. 3965 /// \param AssociatedStmt Statement, associated with the directive. 3966 /// 3967 static OMPTargetUpdateDirective * 3968 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3969 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 3970 3971 /// Creates an empty directive with the place for \a NumClauses 3972 /// clauses. 3973 /// 3974 /// \param C AST context. 3975 /// \param NumClauses The number of clauses. 3976 /// 3977 static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C, 3978 unsigned NumClauses, EmptyShell); 3979 3980 static bool classof(const Stmt *T) { 3981 return T->getStmtClass() == OMPTargetUpdateDirectiveClass; 3982 } 3983 }; 3984 3985 /// This represents '#pragma omp distribute parallel for' composite 3986 /// directive. 3987 /// 3988 /// \code 3989 /// #pragma omp distribute parallel for private(a,b) 3990 /// \endcode 3991 /// In this example directive '#pragma omp distribute parallel for' has clause 3992 /// 'private' with the variables 'a' and 'b' 3993 /// 3994 class OMPDistributeParallelForDirective : public OMPLoopDirective { 3995 friend class ASTStmtReader; 3996 friend class OMPExecutableDirective; 3997 /// true if the construct has inner cancel directive. 3998 bool HasCancel = false; 3999 4000 /// Build directive with the given start and end location. 4001 /// 4002 /// \param StartLoc Starting location of the directive kind. 4003 /// \param EndLoc Ending location of the directive. 4004 /// \param CollapsedNum Number of collapsed nested loops. 4005 /// 4006 OMPDistributeParallelForDirective(SourceLocation StartLoc, 4007 SourceLocation EndLoc, 4008 unsigned CollapsedNum) 4009 : OMPLoopDirective(OMPDistributeParallelForDirectiveClass, 4010 llvm::omp::OMPD_distribute_parallel_for, StartLoc, 4011 EndLoc, CollapsedNum) {} 4012 4013 /// Build an empty directive. 4014 /// 4015 /// \param CollapsedNum Number of collapsed nested loops. 4016 /// 4017 explicit OMPDistributeParallelForDirective(unsigned CollapsedNum) 4018 : OMPLoopDirective(OMPDistributeParallelForDirectiveClass, 4019 llvm::omp::OMPD_distribute_parallel_for, 4020 SourceLocation(), SourceLocation(), CollapsedNum) {} 4021 4022 /// Sets special task reduction descriptor. 4023 void setTaskReductionRefExpr(Expr *E) { 4024 Data->getChildren()[numLoopChildren( 4025 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)] = E; 4026 } 4027 4028 /// Set cancel state. 4029 void setHasCancel(bool Has) { HasCancel = Has; } 4030 4031 public: 4032 /// Creates directive with a list of \a Clauses. 4033 /// 4034 /// \param C AST context. 4035 /// \param StartLoc Starting location of the directive kind. 4036 /// \param EndLoc Ending Location of the directive. 4037 /// \param CollapsedNum Number of collapsed loops. 4038 /// \param Clauses List of clauses. 4039 /// \param AssociatedStmt Statement, associated with the directive. 4040 /// \param Exprs Helper expressions for CodeGen. 4041 /// \param TaskRedRef Task reduction special reference expression to handle 4042 /// taskgroup descriptor. 4043 /// \param HasCancel true if this directive has inner cancel directive. 4044 /// 4045 static OMPDistributeParallelForDirective * 4046 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4047 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4048 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 4049 bool HasCancel); 4050 4051 /// Creates an empty directive with the place 4052 /// for \a NumClauses clauses. 4053 /// 4054 /// \param C AST context. 4055 /// \param CollapsedNum Number of collapsed nested loops. 4056 /// \param NumClauses Number of clauses. 4057 /// 4058 static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C, 4059 unsigned NumClauses, 4060 unsigned CollapsedNum, 4061 EmptyShell); 4062 4063 /// Returns special task reduction reference expression. 4064 Expr *getTaskReductionRefExpr() { 4065 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 4066 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)]); 4067 } 4068 const Expr *getTaskReductionRefExpr() const { 4069 return const_cast<OMPDistributeParallelForDirective *>(this) 4070 ->getTaskReductionRefExpr(); 4071 } 4072 4073 /// Return true if current directive has inner cancel directive. 4074 bool hasCancel() const { return HasCancel; } 4075 4076 static bool classof(const Stmt *T) { 4077 return T->getStmtClass() == OMPDistributeParallelForDirectiveClass; 4078 } 4079 }; 4080 4081 /// This represents '#pragma omp distribute parallel for simd' composite 4082 /// directive. 4083 /// 4084 /// \code 4085 /// #pragma omp distribute parallel for simd private(x) 4086 /// \endcode 4087 /// In this example directive '#pragma omp distribute parallel for simd' has 4088 /// clause 'private' with the variables 'x' 4089 /// 4090 class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective { 4091 friend class ASTStmtReader; 4092 friend class OMPExecutableDirective; 4093 4094 /// Build directive with the given start and end location. 4095 /// 4096 /// \param StartLoc Starting location of the directive kind. 4097 /// \param EndLoc Ending location of the directive. 4098 /// \param CollapsedNum Number of collapsed nested loops. 4099 /// 4100 OMPDistributeParallelForSimdDirective(SourceLocation StartLoc, 4101 SourceLocation EndLoc, 4102 unsigned CollapsedNum) 4103 : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass, 4104 llvm::omp::OMPD_distribute_parallel_for_simd, StartLoc, 4105 EndLoc, CollapsedNum) {} 4106 4107 /// Build an empty directive. 4108 /// 4109 /// \param CollapsedNum Number of collapsed nested loops. 4110 /// 4111 explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum) 4112 : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass, 4113 llvm::omp::OMPD_distribute_parallel_for_simd, 4114 SourceLocation(), SourceLocation(), CollapsedNum) {} 4115 4116 public: 4117 /// Creates directive with a list of \a Clauses. 4118 /// 4119 /// \param C AST context. 4120 /// \param StartLoc Starting location of the directive kind. 4121 /// \param EndLoc Ending Location of the directive. 4122 /// \param CollapsedNum Number of collapsed loops. 4123 /// \param Clauses List of clauses. 4124 /// \param AssociatedStmt Statement, associated with the directive. 4125 /// \param Exprs Helper expressions for CodeGen. 4126 /// 4127 static OMPDistributeParallelForSimdDirective *Create( 4128 const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4129 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4130 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4131 4132 /// Creates an empty directive with the place for \a NumClauses clauses. 4133 /// 4134 /// \param C AST context. 4135 /// \param CollapsedNum Number of collapsed nested loops. 4136 /// \param NumClauses Number of clauses. 4137 /// 4138 static OMPDistributeParallelForSimdDirective *CreateEmpty( 4139 const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4140 EmptyShell); 4141 4142 static bool classof(const Stmt *T) { 4143 return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass; 4144 } 4145 }; 4146 4147 /// This represents '#pragma omp distribute simd' composite directive. 4148 /// 4149 /// \code 4150 /// #pragma omp distribute simd private(x) 4151 /// \endcode 4152 /// In this example directive '#pragma omp distribute simd' has clause 4153 /// 'private' with the variables 'x' 4154 /// 4155 class OMPDistributeSimdDirective final : public OMPLoopDirective { 4156 friend class ASTStmtReader; 4157 friend class OMPExecutableDirective; 4158 4159 /// Build directive with the given start and end location. 4160 /// 4161 /// \param StartLoc Starting location of the directive kind. 4162 /// \param EndLoc Ending location of the directive. 4163 /// \param CollapsedNum Number of collapsed nested loops. 4164 /// 4165 OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4166 unsigned CollapsedNum) 4167 : OMPLoopDirective(OMPDistributeSimdDirectiveClass, 4168 llvm::omp::OMPD_distribute_simd, StartLoc, EndLoc, 4169 CollapsedNum) {} 4170 4171 /// Build an empty directive. 4172 /// 4173 /// \param CollapsedNum Number of collapsed nested loops. 4174 /// 4175 explicit OMPDistributeSimdDirective(unsigned CollapsedNum) 4176 : OMPLoopDirective(OMPDistributeSimdDirectiveClass, 4177 llvm::omp::OMPD_distribute_simd, SourceLocation(), 4178 SourceLocation(), CollapsedNum) {} 4179 4180 public: 4181 /// Creates directive with a list of \a Clauses. 4182 /// 4183 /// \param C AST context. 4184 /// \param StartLoc Starting location of the directive kind. 4185 /// \param EndLoc Ending Location of the directive. 4186 /// \param CollapsedNum Number of collapsed loops. 4187 /// \param Clauses List of clauses. 4188 /// \param AssociatedStmt Statement, associated with the directive. 4189 /// \param Exprs Helper expressions for CodeGen. 4190 /// 4191 static OMPDistributeSimdDirective * 4192 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4193 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4194 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4195 4196 /// Creates an empty directive with the place for \a NumClauses clauses. 4197 /// 4198 /// \param C AST context. 4199 /// \param CollapsedNum Number of collapsed nested loops. 4200 /// \param NumClauses Number of clauses. 4201 /// 4202 static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C, 4203 unsigned NumClauses, 4204 unsigned CollapsedNum, 4205 EmptyShell); 4206 4207 static bool classof(const Stmt *T) { 4208 return T->getStmtClass() == OMPDistributeSimdDirectiveClass; 4209 } 4210 }; 4211 4212 /// This represents '#pragma omp target parallel for simd' directive. 4213 /// 4214 /// \code 4215 /// #pragma omp target parallel for simd private(a) map(b) safelen(c) 4216 /// \endcode 4217 /// In this example directive '#pragma omp target parallel for simd' has clauses 4218 /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen' 4219 /// with the variable 'c'. 4220 /// 4221 class OMPTargetParallelForSimdDirective final : public OMPLoopDirective { 4222 friend class ASTStmtReader; 4223 friend class OMPExecutableDirective; 4224 4225 /// Build directive with the given start and end location. 4226 /// 4227 /// \param StartLoc Starting location of the directive kind. 4228 /// \param EndLoc Ending location of the directive. 4229 /// \param CollapsedNum Number of collapsed nested loops. 4230 /// 4231 OMPTargetParallelForSimdDirective(SourceLocation StartLoc, 4232 SourceLocation EndLoc, 4233 unsigned CollapsedNum) 4234 : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass, 4235 llvm::omp::OMPD_target_parallel_for_simd, StartLoc, 4236 EndLoc, CollapsedNum) {} 4237 4238 /// Build an empty directive. 4239 /// 4240 /// \param CollapsedNum Number of collapsed nested loops. 4241 /// 4242 explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum) 4243 : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass, 4244 llvm::omp::OMPD_target_parallel_for_simd, 4245 SourceLocation(), SourceLocation(), CollapsedNum) {} 4246 4247 public: 4248 /// Creates directive with a list of \a Clauses. 4249 /// 4250 /// \param C AST context. 4251 /// \param StartLoc Starting location of the directive kind. 4252 /// \param EndLoc Ending Location of the directive. 4253 /// \param CollapsedNum Number of collapsed loops. 4254 /// \param Clauses List of clauses. 4255 /// \param AssociatedStmt Statement, associated with the directive. 4256 /// \param Exprs Helper expressions for CodeGen. 4257 /// 4258 static OMPTargetParallelForSimdDirective * 4259 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4260 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4261 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4262 4263 /// Creates an empty directive with the place for \a NumClauses clauses. 4264 /// 4265 /// \param C AST context. 4266 /// \param CollapsedNum Number of collapsed nested loops. 4267 /// \param NumClauses Number of clauses. 4268 /// 4269 static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C, 4270 unsigned NumClauses, 4271 unsigned CollapsedNum, 4272 EmptyShell); 4273 4274 static bool classof(const Stmt *T) { 4275 return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass; 4276 } 4277 }; 4278 4279 /// This represents '#pragma omp target simd' directive. 4280 /// 4281 /// \code 4282 /// #pragma omp target simd private(a) map(b) safelen(c) 4283 /// \endcode 4284 /// In this example directive '#pragma omp target simd' has clauses 'private' 4285 /// with the variable 'a', 'map' with the variable 'b' and 'safelen' with 4286 /// the variable 'c'. 4287 /// 4288 class OMPTargetSimdDirective final : public OMPLoopDirective { 4289 friend class ASTStmtReader; 4290 friend class OMPExecutableDirective; 4291 4292 /// Build directive with the given start and end location. 4293 /// 4294 /// \param StartLoc Starting location of the directive kind. 4295 /// \param EndLoc Ending location of the directive. 4296 /// \param CollapsedNum Number of collapsed nested loops. 4297 /// 4298 OMPTargetSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4299 unsigned CollapsedNum) 4300 : OMPLoopDirective(OMPTargetSimdDirectiveClass, 4301 llvm::omp::OMPD_target_simd, StartLoc, EndLoc, 4302 CollapsedNum) {} 4303 4304 /// Build an empty directive. 4305 /// 4306 /// \param CollapsedNum Number of collapsed nested loops. 4307 /// 4308 explicit OMPTargetSimdDirective(unsigned CollapsedNum) 4309 : OMPLoopDirective(OMPTargetSimdDirectiveClass, 4310 llvm::omp::OMPD_target_simd, SourceLocation(), 4311 SourceLocation(), CollapsedNum) {} 4312 4313 public: 4314 /// Creates directive with a list of \a Clauses. 4315 /// 4316 /// \param C AST context. 4317 /// \param StartLoc Starting location of the directive kind. 4318 /// \param EndLoc Ending Location of the directive. 4319 /// \param CollapsedNum Number of collapsed loops. 4320 /// \param Clauses List of clauses. 4321 /// \param AssociatedStmt Statement, associated with the directive. 4322 /// \param Exprs Helper expressions for CodeGen. 4323 /// 4324 static OMPTargetSimdDirective * 4325 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4326 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4327 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4328 4329 /// Creates an empty directive with the place for \a NumClauses clauses. 4330 /// 4331 /// \param C AST context. 4332 /// \param CollapsedNum Number of collapsed nested loops. 4333 /// \param NumClauses Number of clauses. 4334 /// 4335 static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C, 4336 unsigned NumClauses, 4337 unsigned CollapsedNum, 4338 EmptyShell); 4339 4340 static bool classof(const Stmt *T) { 4341 return T->getStmtClass() == OMPTargetSimdDirectiveClass; 4342 } 4343 }; 4344 4345 /// This represents '#pragma omp teams distribute' directive. 4346 /// 4347 /// \code 4348 /// #pragma omp teams distribute private(a,b) 4349 /// \endcode 4350 /// In this example directive '#pragma omp teams distribute' has clauses 4351 /// 'private' with the variables 'a' and 'b' 4352 /// 4353 class OMPTeamsDistributeDirective final : public OMPLoopDirective { 4354 friend class ASTStmtReader; 4355 friend class OMPExecutableDirective; 4356 4357 /// Build directive with the given start and end location. 4358 /// 4359 /// \param StartLoc Starting location of the directive kind. 4360 /// \param EndLoc Ending location of the directive. 4361 /// \param CollapsedNum Number of collapsed nested loops. 4362 /// 4363 OMPTeamsDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4364 unsigned CollapsedNum) 4365 : OMPLoopDirective(OMPTeamsDistributeDirectiveClass, 4366 llvm::omp::OMPD_teams_distribute, StartLoc, EndLoc, 4367 CollapsedNum) {} 4368 4369 /// Build an empty directive. 4370 /// 4371 /// \param CollapsedNum Number of collapsed nested loops. 4372 /// 4373 explicit OMPTeamsDistributeDirective(unsigned CollapsedNum) 4374 : OMPLoopDirective(OMPTeamsDistributeDirectiveClass, 4375 llvm::omp::OMPD_teams_distribute, SourceLocation(), 4376 SourceLocation(), CollapsedNum) {} 4377 4378 public: 4379 /// Creates directive with a list of \a Clauses. 4380 /// 4381 /// \param C AST context. 4382 /// \param StartLoc Starting location of the directive kind. 4383 /// \param EndLoc Ending Location of the directive. 4384 /// \param CollapsedNum Number of collapsed loops. 4385 /// \param Clauses List of clauses. 4386 /// \param AssociatedStmt Statement, associated with the directive. 4387 /// \param Exprs Helper expressions for CodeGen. 4388 /// 4389 static OMPTeamsDistributeDirective * 4390 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4391 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4392 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4393 4394 /// Creates an empty directive with the place for \a NumClauses clauses. 4395 /// 4396 /// \param C AST context. 4397 /// \param CollapsedNum Number of collapsed nested loops. 4398 /// \param NumClauses Number of clauses. 4399 /// 4400 static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C, 4401 unsigned NumClauses, 4402 unsigned CollapsedNum, 4403 EmptyShell); 4404 4405 static bool classof(const Stmt *T) { 4406 return T->getStmtClass() == OMPTeamsDistributeDirectiveClass; 4407 } 4408 }; 4409 4410 /// This represents '#pragma omp teams distribute simd' 4411 /// combined directive. 4412 /// 4413 /// \code 4414 /// #pragma omp teams distribute simd private(a,b) 4415 /// \endcode 4416 /// In this example directive '#pragma omp teams distribute simd' 4417 /// has clause 'private' with the variables 'a' and 'b' 4418 /// 4419 class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective { 4420 friend class ASTStmtReader; 4421 friend class OMPExecutableDirective; 4422 4423 /// Build directive with the given start and end location. 4424 /// 4425 /// \param StartLoc Starting location of the directive kind. 4426 /// \param EndLoc Ending location of the directive. 4427 /// \param CollapsedNum Number of collapsed nested loops. 4428 /// 4429 OMPTeamsDistributeSimdDirective(SourceLocation StartLoc, 4430 SourceLocation EndLoc, unsigned CollapsedNum) 4431 : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass, 4432 llvm::omp::OMPD_teams_distribute_simd, StartLoc, 4433 EndLoc, CollapsedNum) {} 4434 4435 /// Build an empty directive. 4436 /// 4437 /// \param CollapsedNum Number of collapsed nested loops. 4438 /// 4439 explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum) 4440 : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass, 4441 llvm::omp::OMPD_teams_distribute_simd, 4442 SourceLocation(), SourceLocation(), CollapsedNum) {} 4443 4444 public: 4445 /// Creates directive with a list of \a Clauses. 4446 /// 4447 /// \param C AST context. 4448 /// \param StartLoc Starting location of the directive kind. 4449 /// \param EndLoc Ending Location of the directive. 4450 /// \param CollapsedNum Number of collapsed loops. 4451 /// \param Clauses List of clauses. 4452 /// \param AssociatedStmt Statement, associated with the directive. 4453 /// \param Exprs Helper expressions for CodeGen. 4454 /// 4455 static OMPTeamsDistributeSimdDirective * 4456 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4457 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4458 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4459 4460 /// Creates an empty directive with the place 4461 /// for \a NumClauses clauses. 4462 /// 4463 /// \param C AST context. 4464 /// \param CollapsedNum Number of collapsed nested loops. 4465 /// \param NumClauses Number of clauses. 4466 /// 4467 static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C, 4468 unsigned NumClauses, 4469 unsigned CollapsedNum, 4470 EmptyShell); 4471 4472 static bool classof(const Stmt *T) { 4473 return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass; 4474 } 4475 }; 4476 4477 /// This represents '#pragma omp teams distribute parallel for simd' composite 4478 /// directive. 4479 /// 4480 /// \code 4481 /// #pragma omp teams distribute parallel for simd private(x) 4482 /// \endcode 4483 /// In this example directive '#pragma omp teams distribute parallel for simd' 4484 /// has clause 'private' with the variables 'x' 4485 /// 4486 class OMPTeamsDistributeParallelForSimdDirective final 4487 : public OMPLoopDirective { 4488 friend class ASTStmtReader; 4489 friend class OMPExecutableDirective; 4490 4491 /// Build directive with the given start and end location. 4492 /// 4493 /// \param StartLoc Starting location of the directive kind. 4494 /// \param EndLoc Ending location of the directive. 4495 /// \param CollapsedNum Number of collapsed nested loops. 4496 /// 4497 OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc, 4498 SourceLocation EndLoc, 4499 unsigned CollapsedNum) 4500 : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass, 4501 llvm::omp::OMPD_teams_distribute_parallel_for_simd, 4502 StartLoc, EndLoc, CollapsedNum) {} 4503 4504 /// Build an empty directive. 4505 /// 4506 /// \param CollapsedNum Number of collapsed nested loops. 4507 /// 4508 explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum) 4509 : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass, 4510 llvm::omp::OMPD_teams_distribute_parallel_for_simd, 4511 SourceLocation(), SourceLocation(), CollapsedNum) {} 4512 4513 public: 4514 /// Creates directive with a list of \a Clauses. 4515 /// 4516 /// \param C AST context. 4517 /// \param StartLoc Starting location of the directive kind. 4518 /// \param EndLoc Ending Location of the directive. 4519 /// \param CollapsedNum Number of collapsed loops. 4520 /// \param Clauses List of clauses. 4521 /// \param AssociatedStmt Statement, associated with the directive. 4522 /// \param Exprs Helper expressions for CodeGen. 4523 /// 4524 static OMPTeamsDistributeParallelForSimdDirective * 4525 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4526 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4527 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4528 4529 /// Creates an empty directive with the place for \a NumClauses clauses. 4530 /// 4531 /// \param C AST context. 4532 /// \param CollapsedNum Number of collapsed nested loops. 4533 /// \param NumClauses Number of clauses. 4534 /// 4535 static OMPTeamsDistributeParallelForSimdDirective * 4536 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4537 EmptyShell); 4538 4539 static bool classof(const Stmt *T) { 4540 return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass; 4541 } 4542 }; 4543 4544 /// This represents '#pragma omp teams distribute parallel for' composite 4545 /// directive. 4546 /// 4547 /// \code 4548 /// #pragma omp teams distribute parallel for private(x) 4549 /// \endcode 4550 /// In this example directive '#pragma omp teams distribute parallel for' 4551 /// has clause 'private' with the variables 'x' 4552 /// 4553 class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective { 4554 friend class ASTStmtReader; 4555 friend class OMPExecutableDirective; 4556 /// true if the construct has inner cancel directive. 4557 bool HasCancel = false; 4558 4559 /// Build directive with the given start and end location. 4560 /// 4561 /// \param StartLoc Starting location of the directive kind. 4562 /// \param EndLoc Ending location of the directive. 4563 /// \param CollapsedNum Number of collapsed nested loops. 4564 /// 4565 OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc, 4566 SourceLocation EndLoc, 4567 unsigned CollapsedNum) 4568 : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass, 4569 llvm::omp::OMPD_teams_distribute_parallel_for, 4570 StartLoc, EndLoc, CollapsedNum) {} 4571 4572 /// Build an empty directive. 4573 /// 4574 /// \param CollapsedNum Number of collapsed nested loops. 4575 /// 4576 explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum) 4577 : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass, 4578 llvm::omp::OMPD_teams_distribute_parallel_for, 4579 SourceLocation(), SourceLocation(), CollapsedNum) {} 4580 4581 /// Sets special task reduction descriptor. 4582 void setTaskReductionRefExpr(Expr *E) { 4583 Data->getChildren()[numLoopChildren( 4584 getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)] = E; 4585 } 4586 4587 /// Set cancel state. 4588 void setHasCancel(bool Has) { HasCancel = Has; } 4589 4590 public: 4591 /// Creates directive with a list of \a Clauses. 4592 /// 4593 /// \param C AST context. 4594 /// \param StartLoc Starting location of the directive kind. 4595 /// \param EndLoc Ending Location of the directive. 4596 /// \param CollapsedNum Number of collapsed loops. 4597 /// \param Clauses List of clauses. 4598 /// \param AssociatedStmt Statement, associated with the directive. 4599 /// \param Exprs Helper expressions for CodeGen. 4600 /// \param TaskRedRef Task reduction special reference expression to handle 4601 /// taskgroup descriptor. 4602 /// \param HasCancel true if this directive has inner cancel directive. 4603 /// 4604 static OMPTeamsDistributeParallelForDirective * 4605 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4606 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4607 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 4608 bool HasCancel); 4609 4610 /// Creates an empty directive with the place for \a NumClauses clauses. 4611 /// 4612 /// \param C AST context. 4613 /// \param CollapsedNum Number of collapsed nested loops. 4614 /// \param NumClauses Number of clauses. 4615 /// 4616 static OMPTeamsDistributeParallelForDirective * 4617 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4618 EmptyShell); 4619 4620 /// Returns special task reduction reference expression. 4621 Expr *getTaskReductionRefExpr() { 4622 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 4623 getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)]); 4624 } 4625 const Expr *getTaskReductionRefExpr() const { 4626 return const_cast<OMPTeamsDistributeParallelForDirective *>(this) 4627 ->getTaskReductionRefExpr(); 4628 } 4629 4630 /// Return true if current directive has inner cancel directive. 4631 bool hasCancel() const { return HasCancel; } 4632 4633 static bool classof(const Stmt *T) { 4634 return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass; 4635 } 4636 }; 4637 4638 /// This represents '#pragma omp target teams' directive. 4639 /// 4640 /// \code 4641 /// #pragma omp target teams if(a>0) 4642 /// \endcode 4643 /// In this example directive '#pragma omp target teams' has clause 'if' with 4644 /// condition 'a>0'. 4645 /// 4646 class OMPTargetTeamsDirective final : public OMPExecutableDirective { 4647 friend class ASTStmtReader; 4648 friend class OMPExecutableDirective; 4649 /// Build directive with the given start and end location. 4650 /// 4651 /// \param StartLoc Starting location of the directive kind. 4652 /// \param EndLoc Ending location of the directive. 4653 /// 4654 OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 4655 : OMPExecutableDirective(OMPTargetTeamsDirectiveClass, 4656 llvm::omp::OMPD_target_teams, StartLoc, EndLoc) { 4657 } 4658 4659 /// Build an empty directive. 4660 /// 4661 explicit OMPTargetTeamsDirective() 4662 : OMPExecutableDirective(OMPTargetTeamsDirectiveClass, 4663 llvm::omp::OMPD_target_teams, SourceLocation(), 4664 SourceLocation()) {} 4665 4666 public: 4667 /// Creates directive with a list of \a Clauses. 4668 /// 4669 /// \param C AST context. 4670 /// \param StartLoc Starting location of the directive kind. 4671 /// \param EndLoc Ending Location of the directive. 4672 /// \param Clauses List of clauses. 4673 /// \param AssociatedStmt Statement, associated with the directive. 4674 /// 4675 static OMPTargetTeamsDirective *Create(const ASTContext &C, 4676 SourceLocation StartLoc, 4677 SourceLocation EndLoc, 4678 ArrayRef<OMPClause *> Clauses, 4679 Stmt *AssociatedStmt); 4680 4681 /// Creates an empty directive with the place for \a NumClauses clauses. 4682 /// 4683 /// \param C AST context. 4684 /// \param NumClauses Number of clauses. 4685 /// 4686 static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C, 4687 unsigned NumClauses, EmptyShell); 4688 4689 static bool classof(const Stmt *T) { 4690 return T->getStmtClass() == OMPTargetTeamsDirectiveClass; 4691 } 4692 }; 4693 4694 /// This represents '#pragma omp target teams distribute' combined directive. 4695 /// 4696 /// \code 4697 /// #pragma omp target teams distribute private(x) 4698 /// \endcode 4699 /// In this example directive '#pragma omp target teams distribute' has clause 4700 /// 'private' with the variables 'x' 4701 /// 4702 class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective { 4703 friend class ASTStmtReader; 4704 friend class OMPExecutableDirective; 4705 4706 /// Build directive with the given start and end location. 4707 /// 4708 /// \param StartLoc Starting location of the directive kind. 4709 /// \param EndLoc Ending location of the directive. 4710 /// \param CollapsedNum Number of collapsed nested loops. 4711 /// 4712 OMPTargetTeamsDistributeDirective(SourceLocation StartLoc, 4713 SourceLocation EndLoc, 4714 unsigned CollapsedNum) 4715 : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass, 4716 llvm::omp::OMPD_target_teams_distribute, StartLoc, 4717 EndLoc, CollapsedNum) {} 4718 4719 /// Build an empty directive. 4720 /// 4721 /// \param CollapsedNum Number of collapsed nested loops. 4722 /// 4723 explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum) 4724 : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass, 4725 llvm::omp::OMPD_target_teams_distribute, 4726 SourceLocation(), SourceLocation(), CollapsedNum) {} 4727 4728 public: 4729 /// Creates directive with a list of \a Clauses. 4730 /// 4731 /// \param C AST context. 4732 /// \param StartLoc Starting location of the directive kind. 4733 /// \param EndLoc Ending Location of the directive. 4734 /// \param CollapsedNum Number of collapsed loops. 4735 /// \param Clauses List of clauses. 4736 /// \param AssociatedStmt Statement, associated with the directive. 4737 /// \param Exprs Helper expressions for CodeGen. 4738 /// 4739 static OMPTargetTeamsDistributeDirective * 4740 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4741 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4742 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4743 4744 /// Creates an empty directive with the place for \a NumClauses clauses. 4745 /// 4746 /// \param C AST context. 4747 /// \param CollapsedNum Number of collapsed nested loops. 4748 /// \param NumClauses Number of clauses. 4749 /// 4750 static OMPTargetTeamsDistributeDirective * 4751 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4752 EmptyShell); 4753 4754 static bool classof(const Stmt *T) { 4755 return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass; 4756 } 4757 }; 4758 4759 /// This represents '#pragma omp target teams distribute parallel for' combined 4760 /// directive. 4761 /// 4762 /// \code 4763 /// #pragma omp target teams distribute parallel for private(x) 4764 /// \endcode 4765 /// In this example directive '#pragma omp target teams distribute parallel 4766 /// for' has clause 'private' with the variables 'x' 4767 /// 4768 class OMPTargetTeamsDistributeParallelForDirective final 4769 : public OMPLoopDirective { 4770 friend class ASTStmtReader; 4771 friend class OMPExecutableDirective; 4772 /// true if the construct has inner cancel directive. 4773 bool HasCancel = false; 4774 4775 /// Build directive with the given start and end location. 4776 /// 4777 /// \param StartLoc Starting location of the directive kind. 4778 /// \param EndLoc Ending location of the directive. 4779 /// \param CollapsedNum Number of collapsed nested loops. 4780 /// 4781 OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc, 4782 SourceLocation EndLoc, 4783 unsigned CollapsedNum) 4784 : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass, 4785 llvm::omp::OMPD_target_teams_distribute_parallel_for, 4786 StartLoc, EndLoc, CollapsedNum) {} 4787 4788 /// Build an empty directive. 4789 /// 4790 /// \param CollapsedNum Number of collapsed nested loops. 4791 /// 4792 explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum) 4793 : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass, 4794 llvm::omp::OMPD_target_teams_distribute_parallel_for, 4795 SourceLocation(), SourceLocation(), CollapsedNum) {} 4796 4797 /// Sets special task reduction descriptor. 4798 void setTaskReductionRefExpr(Expr *E) { 4799 Data->getChildren()[numLoopChildren( 4800 getLoopsNumber(), 4801 llvm::omp::OMPD_target_teams_distribute_parallel_for)] = E; 4802 } 4803 4804 /// Set cancel state. 4805 void setHasCancel(bool Has) { HasCancel = Has; } 4806 4807 public: 4808 /// Creates directive with a list of \a Clauses. 4809 /// 4810 /// \param C AST context. 4811 /// \param StartLoc Starting location of the directive kind. 4812 /// \param EndLoc Ending Location of the directive. 4813 /// \param CollapsedNum Number of collapsed loops. 4814 /// \param Clauses List of clauses. 4815 /// \param AssociatedStmt Statement, associated with the directive. 4816 /// \param Exprs Helper expressions for CodeGen. 4817 /// \param TaskRedRef Task reduction special reference expression to handle 4818 /// taskgroup descriptor. 4819 /// \param HasCancel true if this directive has inner cancel directive. 4820 /// 4821 static OMPTargetTeamsDistributeParallelForDirective * 4822 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4823 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4824 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 4825 bool HasCancel); 4826 4827 /// Creates an empty directive with the place for \a NumClauses clauses. 4828 /// 4829 /// \param C AST context. 4830 /// \param CollapsedNum Number of collapsed nested loops. 4831 /// \param NumClauses Number of clauses. 4832 /// 4833 static OMPTargetTeamsDistributeParallelForDirective * 4834 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4835 EmptyShell); 4836 4837 /// Returns special task reduction reference expression. 4838 Expr *getTaskReductionRefExpr() { 4839 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 4840 getLoopsNumber(), 4841 llvm::omp::OMPD_target_teams_distribute_parallel_for)]); 4842 } 4843 const Expr *getTaskReductionRefExpr() const { 4844 return const_cast<OMPTargetTeamsDistributeParallelForDirective *>(this) 4845 ->getTaskReductionRefExpr(); 4846 } 4847 4848 /// Return true if current directive has inner cancel directive. 4849 bool hasCancel() const { return HasCancel; } 4850 4851 static bool classof(const Stmt *T) { 4852 return T->getStmtClass() == 4853 OMPTargetTeamsDistributeParallelForDirectiveClass; 4854 } 4855 }; 4856 4857 /// This represents '#pragma omp target teams distribute parallel for simd' 4858 /// combined directive. 4859 /// 4860 /// \code 4861 /// #pragma omp target teams distribute parallel for simd private(x) 4862 /// \endcode 4863 /// In this example directive '#pragma omp target teams distribute parallel 4864 /// for simd' has clause 'private' with the variables 'x' 4865 /// 4866 class OMPTargetTeamsDistributeParallelForSimdDirective final 4867 : public OMPLoopDirective { 4868 friend class ASTStmtReader; 4869 friend class OMPExecutableDirective; 4870 4871 /// Build directive with the given start and end location. 4872 /// 4873 /// \param StartLoc Starting location of the directive kind. 4874 /// \param EndLoc Ending location of the directive. 4875 /// \param CollapsedNum Number of collapsed nested loops. 4876 /// 4877 OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc, 4878 SourceLocation EndLoc, 4879 unsigned CollapsedNum) 4880 : OMPLoopDirective( 4881 OMPTargetTeamsDistributeParallelForSimdDirectiveClass, 4882 llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, StartLoc, 4883 EndLoc, CollapsedNum) {} 4884 4885 /// Build an empty directive. 4886 /// 4887 /// \param CollapsedNum Number of collapsed nested loops. 4888 /// 4889 explicit OMPTargetTeamsDistributeParallelForSimdDirective( 4890 unsigned CollapsedNum) 4891 : OMPLoopDirective( 4892 OMPTargetTeamsDistributeParallelForSimdDirectiveClass, 4893 llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, 4894 SourceLocation(), SourceLocation(), CollapsedNum) {} 4895 4896 public: 4897 /// Creates directive with a list of \a Clauses. 4898 /// 4899 /// \param C AST context. 4900 /// \param StartLoc Starting location of the directive kind. 4901 /// \param EndLoc Ending Location of the directive. 4902 /// \param CollapsedNum Number of collapsed loops. 4903 /// \param Clauses List of clauses. 4904 /// \param AssociatedStmt Statement, associated with the directive. 4905 /// \param Exprs Helper expressions for CodeGen. 4906 /// 4907 static OMPTargetTeamsDistributeParallelForSimdDirective * 4908 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4909 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4910 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4911 4912 /// Creates an empty directive with the place for \a NumClauses clauses. 4913 /// 4914 /// \param C AST context. 4915 /// \param CollapsedNum Number of collapsed nested loops. 4916 /// \param NumClauses Number of clauses. 4917 /// 4918 static OMPTargetTeamsDistributeParallelForSimdDirective * 4919 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4920 EmptyShell); 4921 4922 static bool classof(const Stmt *T) { 4923 return T->getStmtClass() == 4924 OMPTargetTeamsDistributeParallelForSimdDirectiveClass; 4925 } 4926 }; 4927 4928 /// This represents '#pragma omp target teams distribute simd' combined 4929 /// directive. 4930 /// 4931 /// \code 4932 /// #pragma omp target teams distribute simd private(x) 4933 /// \endcode 4934 /// In this example directive '#pragma omp target teams distribute simd' 4935 /// has clause 'private' with the variables 'x' 4936 /// 4937 class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective { 4938 friend class ASTStmtReader; 4939 friend class OMPExecutableDirective; 4940 4941 /// Build directive with the given start and end location. 4942 /// 4943 /// \param StartLoc Starting location of the directive kind. 4944 /// \param EndLoc Ending location of the directive. 4945 /// \param CollapsedNum Number of collapsed nested loops. 4946 /// 4947 OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc, 4948 SourceLocation EndLoc, 4949 unsigned CollapsedNum) 4950 : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass, 4951 llvm::omp::OMPD_target_teams_distribute_simd, StartLoc, 4952 EndLoc, CollapsedNum) {} 4953 4954 /// Build an empty directive. 4955 /// 4956 /// \param CollapsedNum Number of collapsed nested loops. 4957 /// 4958 explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum) 4959 : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass, 4960 llvm::omp::OMPD_target_teams_distribute_simd, 4961 SourceLocation(), SourceLocation(), CollapsedNum) {} 4962 4963 public: 4964 /// Creates directive with a list of \a Clauses. 4965 /// 4966 /// \param C AST context. 4967 /// \param StartLoc Starting location of the directive kind. 4968 /// \param EndLoc Ending Location of the directive. 4969 /// \param CollapsedNum Number of collapsed loops. 4970 /// \param Clauses List of clauses. 4971 /// \param AssociatedStmt Statement, associated with the directive. 4972 /// \param Exprs Helper expressions for CodeGen. 4973 /// 4974 static OMPTargetTeamsDistributeSimdDirective * 4975 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4976 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4977 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4978 4979 /// Creates an empty directive with the place for \a NumClauses clauses. 4980 /// 4981 /// \param C AST context. 4982 /// \param CollapsedNum Number of collapsed nested loops. 4983 /// \param NumClauses Number of clauses. 4984 /// 4985 static OMPTargetTeamsDistributeSimdDirective * 4986 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4987 EmptyShell); 4988 4989 static bool classof(const Stmt *T) { 4990 return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass; 4991 } 4992 }; 4993 4994 /// This represents the '#pragma omp tile' loop transformation directive. 4995 class OMPTileDirective final : public OMPLoopBasedDirective { 4996 friend class ASTStmtReader; 4997 friend class OMPExecutableDirective; 4998 4999 /// Default list of offsets. 5000 enum { 5001 PreInitsOffset = 0, 5002 TransformedStmtOffset, 5003 }; 5004 5005 explicit OMPTileDirective(SourceLocation StartLoc, SourceLocation EndLoc, 5006 unsigned NumLoops) 5007 : OMPLoopBasedDirective(OMPTileDirectiveClass, llvm::omp::OMPD_tile, 5008 StartLoc, EndLoc, NumLoops) {} 5009 5010 void setPreInits(Stmt *PreInits) { 5011 Data->getChildren()[PreInitsOffset] = PreInits; 5012 } 5013 5014 void setTransformedStmt(Stmt *S) { 5015 Data->getChildren()[TransformedStmtOffset] = S; 5016 } 5017 5018 public: 5019 /// Create a new AST node representation for '#pragma omp tile'. 5020 /// 5021 /// \param C Context of the AST. 5022 /// \param StartLoc Location of the introducer (e.g. the 'omp' token). 5023 /// \param EndLoc Location of the directive's end (e.g. the tok::eod). 5024 /// \param Clauses The directive's clauses. 5025 /// \param NumLoops Number of associated loops (number of items in the 5026 /// 'sizes' clause). 5027 /// \param AssociatedStmt The outermost associated loop. 5028 /// \param TransformedStmt The loop nest after tiling, or nullptr in 5029 /// dependent contexts. 5030 /// \param PreInits Helper preinits statements for the loop nest. 5031 static OMPTileDirective *Create(const ASTContext &C, SourceLocation StartLoc, 5032 SourceLocation EndLoc, 5033 ArrayRef<OMPClause *> Clauses, 5034 unsigned NumLoops, Stmt *AssociatedStmt, 5035 Stmt *TransformedStmt, Stmt *PreInits); 5036 5037 /// Build an empty '#pragma omp tile' AST node for deserialization. 5038 /// 5039 /// \param C Context of the AST. 5040 /// \param NumClauses Number of clauses to allocate. 5041 /// \param NumLoops Number of associated loops to allocate. 5042 static OMPTileDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 5043 unsigned NumLoops); 5044 5045 unsigned getNumAssociatedLoops() const { return getLoopsNumber(); } 5046 5047 /// Gets/sets the associated loops after tiling. 5048 /// 5049 /// This is in de-sugared format stored as a CompoundStmt. 5050 /// 5051 /// \code 5052 /// for (...) 5053 /// ... 5054 /// \endcode 5055 /// 5056 /// Note that if the generated loops a become associated loops of another 5057 /// directive, they may need to be hoisted before them. 5058 Stmt *getTransformedStmt() const { 5059 return Data->getChildren()[TransformedStmtOffset]; 5060 } 5061 5062 /// Return preinits statement. 5063 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } 5064 5065 static bool classof(const Stmt *T) { 5066 return T->getStmtClass() == OMPTileDirectiveClass; 5067 } 5068 }; 5069 5070 /// This represents the '#pragma omp unroll' loop transformation directive. 5071 /// 5072 /// \code 5073 /// #pragma omp unroll 5074 /// for (int i = 0; i < 64; ++i) 5075 /// \endcode 5076 class OMPUnrollDirective final : public OMPLoopBasedDirective { 5077 friend class ASTStmtReader; 5078 friend class OMPExecutableDirective; 5079 5080 /// Default list of offsets. 5081 enum { 5082 PreInitsOffset = 0, 5083 TransformedStmtOffset, 5084 }; 5085 5086 explicit OMPUnrollDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5087 : OMPLoopBasedDirective(OMPUnrollDirectiveClass, llvm::omp::OMPD_unroll, 5088 StartLoc, EndLoc, 1) {} 5089 5090 /// Set the pre-init statements. 5091 void setPreInits(Stmt *PreInits) { 5092 Data->getChildren()[PreInitsOffset] = PreInits; 5093 } 5094 5095 /// Set the de-sugared statement. 5096 void setTransformedStmt(Stmt *S) { 5097 Data->getChildren()[TransformedStmtOffset] = S; 5098 } 5099 5100 public: 5101 /// Create a new AST node representation for '#pragma omp unroll'. 5102 /// 5103 /// \param C Context of the AST. 5104 /// \param StartLoc Location of the introducer (e.g. the 'omp' token). 5105 /// \param EndLoc Location of the directive's end (e.g. the tok::eod). 5106 /// \param Clauses The directive's clauses. 5107 /// \param AssociatedStmt The outermost associated loop. 5108 /// \param TransformedStmt The loop nest after tiling, or nullptr in 5109 /// dependent contexts. 5110 /// \param PreInits Helper preinits statements for the loop nest. 5111 static OMPUnrollDirective * 5112 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5113 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, 5114 Stmt *TransformedStmt, Stmt *PreInits); 5115 5116 /// Build an empty '#pragma omp unroll' AST node for deserialization. 5117 /// 5118 /// \param C Context of the AST. 5119 /// \param NumClauses Number of clauses to allocate. 5120 static OMPUnrollDirective *CreateEmpty(const ASTContext &C, 5121 unsigned NumClauses); 5122 5123 /// Get the de-sugared associated loops after unrolling. 5124 /// 5125 /// This is only used if the unrolled loop becomes an associated loop of 5126 /// another directive, otherwise the loop is emitted directly using loop 5127 /// transformation metadata. When the unrolled loop cannot be used by another 5128 /// directive (e.g. because of the full clause), the transformed stmt can also 5129 /// be nullptr. 5130 Stmt *getTransformedStmt() const { 5131 return Data->getChildren()[TransformedStmtOffset]; 5132 } 5133 5134 /// Return the pre-init statements. 5135 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } 5136 5137 static bool classof(const Stmt *T) { 5138 return T->getStmtClass() == OMPUnrollDirectiveClass; 5139 } 5140 }; 5141 5142 /// This represents '#pragma omp scan' directive. 5143 /// 5144 /// \code 5145 /// #pragma omp scan inclusive(a) 5146 /// \endcode 5147 /// In this example directive '#pragma omp scan' has clause 'inclusive' with 5148 /// list item 'a'. 5149 class OMPScanDirective final : public OMPExecutableDirective { 5150 friend class ASTStmtReader; 5151 friend class OMPExecutableDirective; 5152 /// Build directive with the given start and end location. 5153 /// 5154 /// \param StartLoc Starting location of the directive kind. 5155 /// \param EndLoc Ending location of the directive. 5156 /// 5157 OMPScanDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5158 : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan, 5159 StartLoc, EndLoc) {} 5160 5161 /// Build an empty directive. 5162 /// 5163 explicit OMPScanDirective() 5164 : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan, 5165 SourceLocation(), SourceLocation()) {} 5166 5167 public: 5168 /// Creates directive with a list of \a Clauses. 5169 /// 5170 /// \param C AST context. 5171 /// \param StartLoc Starting location of the directive kind. 5172 /// \param EndLoc Ending Location of the directive. 5173 /// \param Clauses List of clauses (only single OMPFlushClause clause is 5174 /// allowed). 5175 /// 5176 static OMPScanDirective *Create(const ASTContext &C, SourceLocation StartLoc, 5177 SourceLocation EndLoc, 5178 ArrayRef<OMPClause *> Clauses); 5179 5180 /// Creates an empty directive with the place for \a NumClauses 5181 /// clauses. 5182 /// 5183 /// \param C AST context. 5184 /// \param NumClauses Number of clauses. 5185 /// 5186 static OMPScanDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 5187 EmptyShell); 5188 5189 static bool classof(const Stmt *T) { 5190 return T->getStmtClass() == OMPScanDirectiveClass; 5191 } 5192 }; 5193 5194 /// This represents '#pragma omp interop' directive. 5195 /// 5196 /// \code 5197 /// #pragma omp interop init(target:obj) device(x) depend(inout:y) nowait 5198 /// \endcode 5199 /// In this example directive '#pragma omp interop' has 5200 /// clauses 'init', 'device', 'depend' and 'nowait'. 5201 /// 5202 class OMPInteropDirective final : public OMPExecutableDirective { 5203 friend class ASTStmtReader; 5204 friend class OMPExecutableDirective; 5205 5206 /// Build directive with the given start and end location. 5207 /// 5208 /// \param StartLoc Starting location of the directive. 5209 /// \param EndLoc Ending location of the directive. 5210 /// 5211 OMPInteropDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5212 : OMPExecutableDirective(OMPInteropDirectiveClass, 5213 llvm::omp::OMPD_interop, StartLoc, EndLoc) {} 5214 5215 /// Build an empty directive. 5216 /// 5217 explicit OMPInteropDirective() 5218 : OMPExecutableDirective(OMPInteropDirectiveClass, 5219 llvm::omp::OMPD_interop, SourceLocation(), 5220 SourceLocation()) {} 5221 5222 public: 5223 /// Creates directive. 5224 /// 5225 /// \param C AST context. 5226 /// \param StartLoc Starting location of the directive. 5227 /// \param EndLoc Ending Location of the directive. 5228 /// \param Clauses The directive's clauses. 5229 /// 5230 static OMPInteropDirective *Create(const ASTContext &C, 5231 SourceLocation StartLoc, 5232 SourceLocation EndLoc, 5233 ArrayRef<OMPClause *> Clauses); 5234 5235 /// Creates an empty directive. 5236 /// 5237 /// \param C AST context. 5238 /// 5239 static OMPInteropDirective *CreateEmpty(const ASTContext &C, 5240 unsigned NumClauses, EmptyShell); 5241 5242 static bool classof(const Stmt *T) { 5243 return T->getStmtClass() == OMPInteropDirectiveClass; 5244 } 5245 }; 5246 5247 /// This represents '#pragma omp dispatch' directive. 5248 /// 5249 /// \code 5250 /// #pragma omp dispatch device(dnum) 5251 /// \endcode 5252 /// This example shows a directive '#pragma omp dispatch' with a 5253 /// device clause with variable 'dnum'. 5254 /// 5255 class OMPDispatchDirective final : public OMPExecutableDirective { 5256 friend class ASTStmtReader; 5257 friend class OMPExecutableDirective; 5258 5259 /// The location of the target-call. 5260 SourceLocation TargetCallLoc; 5261 5262 /// Set the location of the target-call. 5263 void setTargetCallLoc(SourceLocation Loc) { TargetCallLoc = Loc; } 5264 5265 /// Build directive with the given start and end location. 5266 /// 5267 /// \param StartLoc Starting location of the directive kind. 5268 /// \param EndLoc Ending location of the directive. 5269 /// 5270 OMPDispatchDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5271 : OMPExecutableDirective(OMPDispatchDirectiveClass, 5272 llvm::omp::OMPD_dispatch, StartLoc, EndLoc) {} 5273 5274 /// Build an empty directive. 5275 /// 5276 explicit OMPDispatchDirective() 5277 : OMPExecutableDirective(OMPDispatchDirectiveClass, 5278 llvm::omp::OMPD_dispatch, SourceLocation(), 5279 SourceLocation()) {} 5280 5281 public: 5282 /// Creates directive with a list of \a Clauses. 5283 /// 5284 /// \param C AST context. 5285 /// \param StartLoc Starting location of the directive kind. 5286 /// \param EndLoc Ending Location of the directive. 5287 /// \param Clauses List of clauses. 5288 /// \param AssociatedStmt Statement, associated with the directive. 5289 /// \param TargetCallLoc Location of the target-call. 5290 /// 5291 static OMPDispatchDirective * 5292 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5293 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, 5294 SourceLocation TargetCallLoc); 5295 5296 /// Creates an empty directive with the place for \a NumClauses 5297 /// clauses. 5298 /// 5299 /// \param C AST context. 5300 /// \param NumClauses Number of clauses. 5301 /// 5302 static OMPDispatchDirective *CreateEmpty(const ASTContext &C, 5303 unsigned NumClauses, EmptyShell); 5304 5305 /// Return location of target-call. 5306 SourceLocation getTargetCallLoc() const { return TargetCallLoc; } 5307 5308 static bool classof(const Stmt *T) { 5309 return T->getStmtClass() == OMPDispatchDirectiveClass; 5310 } 5311 }; 5312 5313 /// This represents '#pragma omp masked' directive. 5314 /// \code 5315 /// #pragma omp masked filter(tid) 5316 /// \endcode 5317 /// This example shows a directive '#pragma omp masked' with a filter clause 5318 /// with variable 'tid'. 5319 /// 5320 class OMPMaskedDirective final : public OMPExecutableDirective { 5321 friend class ASTStmtReader; 5322 friend class OMPExecutableDirective; 5323 5324 /// Build directive with the given start and end location. 5325 /// 5326 /// \param StartLoc Starting location of the directive kind. 5327 /// \param EndLoc Ending location of the directive. 5328 /// 5329 OMPMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5330 : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked, 5331 StartLoc, EndLoc) {} 5332 5333 /// Build an empty directive. 5334 /// 5335 explicit OMPMaskedDirective() 5336 : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked, 5337 SourceLocation(), SourceLocation()) {} 5338 5339 public: 5340 /// Creates directive. 5341 /// 5342 /// \param C AST context. 5343 /// \param StartLoc Starting location of the directive kind. 5344 /// \param EndLoc Ending Location of the directive. 5345 /// \param AssociatedStmt Statement, associated with the directive. 5346 /// 5347 static OMPMaskedDirective * 5348 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5349 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 5350 5351 /// Creates an empty directive. 5352 /// 5353 /// \param C AST context. 5354 /// 5355 static OMPMaskedDirective *CreateEmpty(const ASTContext &C, 5356 unsigned NumClauses, EmptyShell); 5357 5358 static bool classof(const Stmt *T) { 5359 return T->getStmtClass() == OMPMaskedDirectiveClass; 5360 } 5361 }; 5362 5363 } // end namespace clang 5364 5365 #endif 5366