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/Expr.h" 18 #include "clang/AST/OpenMPClause.h" 19 #include "clang/AST/Stmt.h" 20 #include "clang/AST/StmtCXX.h" 21 #include "clang/Basic/OpenMPKinds.h" 22 #include "clang/Basic/SourceLocation.h" 23 24 namespace clang { 25 26 //===----------------------------------------------------------------------===// 27 // AST classes for directives. 28 //===----------------------------------------------------------------------===// 29 30 /// This is a basic class for representing single OpenMP executable 31 /// directive. 32 /// 33 class OMPExecutableDirective : public Stmt { 34 friend class ASTStmtReader; 35 /// Kind of the directive. 36 OpenMPDirectiveKind Kind; 37 /// Starting location of the directive (directive keyword). 38 SourceLocation StartLoc; 39 /// Ending location of the directive. 40 SourceLocation EndLoc; 41 /// Numbers of clauses. 42 const unsigned NumClauses; 43 /// Number of child expressions/stmts. 44 const unsigned NumChildren; 45 /// Offset from this to the start of clauses. 46 /// There are NumClauses pointers to clauses, they are followed by 47 /// NumChildren pointers to child stmts/exprs (if the directive type 48 /// requires an associated stmt, then it has to be the first of them). 49 const unsigned ClausesOffset; 50 51 /// Get the clauses storage. 52 MutableArrayRef<OMPClause *> getClauses() { 53 OMPClause **ClauseStorage = reinterpret_cast<OMPClause **>( 54 reinterpret_cast<char *>(this) + ClausesOffset); 55 return MutableArrayRef<OMPClause *>(ClauseStorage, NumClauses); 56 } 57 58 protected: 59 /// Build instance of directive of class \a K. 60 /// 61 /// \param SC Statement class. 62 /// \param K Kind of OpenMP directive. 63 /// \param StartLoc Starting location of the directive (directive keyword). 64 /// \param EndLoc Ending location of the directive. 65 /// 66 template <typename T> 67 OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K, 68 SourceLocation StartLoc, SourceLocation EndLoc, 69 unsigned NumClauses, unsigned NumChildren) 70 : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)), 71 EndLoc(std::move(EndLoc)), NumClauses(NumClauses), 72 NumChildren(NumChildren), 73 ClausesOffset(llvm::alignTo(sizeof(T), alignof(OMPClause *))) {} 74 75 /// Sets the list of variables for this clause. 76 /// 77 /// \param Clauses The list of clauses for the directive. 78 /// 79 void setClauses(ArrayRef<OMPClause *> Clauses); 80 81 /// Set the associated statement for the directive. 82 /// 83 /// /param S Associated statement. 84 /// 85 void setAssociatedStmt(Stmt *S) { 86 assert(hasAssociatedStmt() && "no associated statement."); 87 *child_begin() = S; 88 } 89 90 public: 91 /// Iterates over expressions/statements used in the construct. 92 class used_clauses_child_iterator 93 : public llvm::iterator_adaptor_base< 94 used_clauses_child_iterator, ArrayRef<OMPClause *>::iterator, 95 std::forward_iterator_tag, Stmt *, ptrdiff_t, Stmt *, Stmt *> { 96 ArrayRef<OMPClause *>::iterator End; 97 OMPClause::child_iterator ChildI, ChildEnd; 98 99 void MoveToNext() { 100 if (ChildI != ChildEnd) 101 return; 102 while (this->I != End) { 103 ++this->I; 104 if (this->I != End) { 105 ChildI = (*this->I)->used_children().begin(); 106 ChildEnd = (*this->I)->used_children().end(); 107 if (ChildI != ChildEnd) 108 return; 109 } 110 } 111 } 112 113 public: 114 explicit used_clauses_child_iterator(ArrayRef<OMPClause *> Clauses) 115 : used_clauses_child_iterator::iterator_adaptor_base(Clauses.begin()), 116 End(Clauses.end()) { 117 if (this->I != End) { 118 ChildI = (*this->I)->used_children().begin(); 119 ChildEnd = (*this->I)->used_children().end(); 120 MoveToNext(); 121 } 122 } 123 Stmt *operator*() const { return *ChildI; } 124 Stmt *operator->() const { return **this; } 125 126 used_clauses_child_iterator &operator++() { 127 ++ChildI; 128 if (ChildI != ChildEnd) 129 return *this; 130 if (this->I != End) { 131 ++this->I; 132 if (this->I != End) { 133 ChildI = (*this->I)->used_children().begin(); 134 ChildEnd = (*this->I)->used_children().end(); 135 } 136 } 137 MoveToNext(); 138 return *this; 139 } 140 }; 141 142 static llvm::iterator_range<used_clauses_child_iterator> 143 used_clauses_children(ArrayRef<OMPClause *> Clauses) { 144 return {used_clauses_child_iterator(Clauses), 145 used_clauses_child_iterator(llvm::makeArrayRef(Clauses.end(), 0))}; 146 } 147 148 /// Iterates over a filtered subrange of clauses applied to a 149 /// directive. 150 /// 151 /// This iterator visits only clauses of type SpecificClause. 152 template <typename SpecificClause> 153 class specific_clause_iterator 154 : public llvm::iterator_adaptor_base< 155 specific_clause_iterator<SpecificClause>, 156 ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag, 157 const SpecificClause *, ptrdiff_t, const SpecificClause *, 158 const SpecificClause *> { 159 ArrayRef<OMPClause *>::const_iterator End; 160 161 void SkipToNextClause() { 162 while (this->I != End && !isa<SpecificClause>(*this->I)) 163 ++this->I; 164 } 165 166 public: 167 explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses) 168 : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()), 169 End(Clauses.end()) { 170 SkipToNextClause(); 171 } 172 173 const SpecificClause *operator*() const { 174 return cast<SpecificClause>(*this->I); 175 } 176 const SpecificClause *operator->() const { return **this; } 177 178 specific_clause_iterator &operator++() { 179 ++this->I; 180 SkipToNextClause(); 181 return *this; 182 } 183 }; 184 185 template <typename SpecificClause> 186 static llvm::iterator_range<specific_clause_iterator<SpecificClause>> 187 getClausesOfKind(ArrayRef<OMPClause *> Clauses) { 188 return {specific_clause_iterator<SpecificClause>(Clauses), 189 specific_clause_iterator<SpecificClause>( 190 llvm::makeArrayRef(Clauses.end(), 0))}; 191 } 192 193 template <typename SpecificClause> 194 llvm::iterator_range<specific_clause_iterator<SpecificClause>> 195 getClausesOfKind() const { 196 return getClausesOfKind<SpecificClause>(clauses()); 197 } 198 199 /// Gets a single clause of the specified kind associated with the 200 /// current directive iff there is only one clause of this kind (and assertion 201 /// is fired if there is more than one clause is associated with the 202 /// directive). Returns nullptr if no clause of this kind is associated with 203 /// the directive. 204 template <typename SpecificClause> 205 const SpecificClause *getSingleClause() const { 206 auto Clauses = getClausesOfKind<SpecificClause>(); 207 208 if (Clauses.begin() != Clauses.end()) { 209 assert(std::next(Clauses.begin()) == Clauses.end() && 210 "There are at least 2 clauses of the specified kind"); 211 return *Clauses.begin(); 212 } 213 return nullptr; 214 } 215 216 /// Returns true if the current directive has one or more clauses of a 217 /// specific kind. 218 template <typename SpecificClause> 219 bool hasClausesOfKind() const { 220 auto Clauses = getClausesOfKind<SpecificClause>(); 221 return Clauses.begin() != Clauses.end(); 222 } 223 224 /// Returns starting location of directive kind. 225 SourceLocation getBeginLoc() const { return StartLoc; } 226 /// Returns ending location of directive. 227 SourceLocation getEndLoc() const { return EndLoc; } 228 229 /// Set starting location of directive kind. 230 /// 231 /// \param Loc New starting location of directive. 232 /// 233 void setLocStart(SourceLocation Loc) { StartLoc = Loc; } 234 /// Set ending location of directive. 235 /// 236 /// \param Loc New ending location of directive. 237 /// 238 void setLocEnd(SourceLocation Loc) { EndLoc = Loc; } 239 240 /// Get number of clauses. 241 unsigned getNumClauses() const { return NumClauses; } 242 243 /// Returns specified clause. 244 /// 245 /// \param i Number of clause. 246 /// 247 OMPClause *getClause(unsigned i) const { return clauses()[i]; } 248 249 /// Returns true if directive has associated statement. 250 bool hasAssociatedStmt() const { return NumChildren > 0; } 251 252 /// Returns statement associated with the directive. 253 const Stmt *getAssociatedStmt() const { 254 assert(hasAssociatedStmt() && "no associated statement."); 255 return *child_begin(); 256 } 257 Stmt *getAssociatedStmt() { 258 assert(hasAssociatedStmt() && "no associated statement."); 259 return *child_begin(); 260 } 261 262 /// Returns the captured statement associated with the 263 /// component region within the (combined) directive. 264 // 265 // \param RegionKind Component region kind. 266 const CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const { 267 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 268 getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind()); 269 assert(std::any_of( 270 CaptureRegions.begin(), CaptureRegions.end(), 271 [=](const OpenMPDirectiveKind K) { return K == RegionKind; }) && 272 "RegionKind not found in OpenMP CaptureRegions."); 273 auto *CS = cast<CapturedStmt>(getAssociatedStmt()); 274 for (auto ThisCaptureRegion : CaptureRegions) { 275 if (ThisCaptureRegion == RegionKind) 276 return CS; 277 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 278 } 279 llvm_unreachable("Incorrect RegionKind specified for directive."); 280 } 281 282 /// Get innermost captured statement for the construct. 283 CapturedStmt *getInnermostCapturedStmt() { 284 assert(hasAssociatedStmt() && getAssociatedStmt() && 285 "Must have associated statement."); 286 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 287 getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind()); 288 assert(!CaptureRegions.empty() && 289 "At least one captured statement must be provided."); 290 auto *CS = cast<CapturedStmt>(getAssociatedStmt()); 291 for (unsigned Level = CaptureRegions.size(); Level > 1; --Level) 292 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 293 return CS; 294 } 295 296 const CapturedStmt *getInnermostCapturedStmt() const { 297 return const_cast<OMPExecutableDirective *>(this) 298 ->getInnermostCapturedStmt(); 299 } 300 301 OpenMPDirectiveKind getDirectiveKind() const { return Kind; } 302 303 static bool classof(const Stmt *S) { 304 return S->getStmtClass() >= firstOMPExecutableDirectiveConstant && 305 S->getStmtClass() <= lastOMPExecutableDirectiveConstant; 306 } 307 308 child_range children() { 309 if (!hasAssociatedStmt()) 310 return child_range(child_iterator(), child_iterator()); 311 Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end()); 312 /// Do not mark all the special expression/statements as children, except 313 /// for the associated statement. 314 return child_range(ChildStorage, ChildStorage + 1); 315 } 316 317 const_child_range children() const { 318 if (!hasAssociatedStmt()) 319 return const_child_range(const_child_iterator(), const_child_iterator()); 320 Stmt **ChildStorage = reinterpret_cast<Stmt **>( 321 const_cast<OMPExecutableDirective *>(this)->getClauses().end()); 322 return const_child_range(ChildStorage, ChildStorage + 1); 323 } 324 325 ArrayRef<OMPClause *> clauses() { return getClauses(); } 326 327 ArrayRef<OMPClause *> clauses() const { 328 return const_cast<OMPExecutableDirective *>(this)->getClauses(); 329 } 330 331 /// Returns whether or not this is a Standalone directive. 332 /// 333 /// Stand-alone directives are executable directives 334 /// that have no associated user code. 335 bool isStandaloneDirective() const; 336 337 /// Returns the AST node representing OpenMP structured-block of this 338 /// OpenMP executable directive, 339 /// Prerequisite: Executable Directive must not be Standalone directive. 340 const Stmt *getStructuredBlock() const; 341 342 Stmt *getStructuredBlock() { 343 return const_cast<Stmt *>( 344 const_cast<const OMPExecutableDirective *>(this)->getStructuredBlock()); 345 } 346 }; 347 348 /// This represents '#pragma omp parallel' directive. 349 /// 350 /// \code 351 /// #pragma omp parallel private(a,b) reduction(+: c,d) 352 /// \endcode 353 /// In this example directive '#pragma omp parallel' has clauses 'private' 354 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and 355 /// variables 'c' and 'd'. 356 /// 357 class OMPParallelDirective : public OMPExecutableDirective { 358 friend class ASTStmtReader; 359 /// Special reference expression for handling task reduction. Used to store 360 /// the taskgroup descriptor returned by the runtime functions. 361 Expr *TaskRedRef = nullptr; 362 /// true if the construct has inner cancel directive. 363 bool HasCancel; 364 365 /// Build directive with the given start and end location. 366 /// 367 /// \param StartLoc Starting location of the directive (directive keyword). 368 /// \param EndLoc Ending Location of the directive. 369 /// 370 OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc, 371 unsigned NumClauses) 372 : OMPExecutableDirective(this, OMPParallelDirectiveClass, 373 llvm::omp::OMPD_parallel, StartLoc, EndLoc, 374 NumClauses, 1), 375 HasCancel(false) {} 376 377 /// Build an empty directive. 378 /// 379 /// \param NumClauses Number of clauses. 380 /// 381 explicit OMPParallelDirective(unsigned NumClauses) 382 : OMPExecutableDirective(this, OMPParallelDirectiveClass, 383 llvm::omp::OMPD_parallel, SourceLocation(), 384 SourceLocation(), NumClauses, 1), 385 HasCancel(false) {} 386 387 /// Sets special task reduction descriptor. 388 void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } 389 390 /// Set cancel state. 391 void setHasCancel(bool Has) { HasCancel = Has; } 392 393 public: 394 /// Creates directive with a list of \a Clauses. 395 /// 396 /// \param C AST context. 397 /// \param StartLoc Starting location of the directive kind. 398 /// \param EndLoc Ending Location of the directive. 399 /// \param Clauses List of clauses. 400 /// \param AssociatedStmt Statement associated with the directive. 401 /// \param TaskRedRef Task reduction special reference expression to handle 402 /// taskgroup descriptor. 403 /// \param HasCancel true if this directive has inner cancel directive. 404 /// 405 static OMPParallelDirective * 406 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 407 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 408 bool HasCancel); 409 410 /// Creates an empty directive with the place for \a N clauses. 411 /// 412 /// \param C AST context. 413 /// \param NumClauses Number of clauses. 414 /// 415 static OMPParallelDirective *CreateEmpty(const ASTContext &C, 416 unsigned NumClauses, EmptyShell); 417 418 /// Returns special task reduction reference expression. 419 Expr *getTaskReductionRefExpr() { return TaskRedRef; } 420 const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } 421 422 /// Return true if current directive has inner cancel directive. 423 bool hasCancel() const { return HasCancel; } 424 425 static bool classof(const Stmt *T) { 426 return T->getStmtClass() == OMPParallelDirectiveClass; 427 } 428 }; 429 430 /// This is a common base class for loop directives ('omp simd', 'omp 431 /// for', 'omp for simd' etc.). It is responsible for the loop code generation. 432 /// 433 class OMPLoopDirective : public OMPExecutableDirective { 434 friend class ASTStmtReader; 435 /// Number of collapsed loops as specified by 'collapse' clause. 436 unsigned CollapsedNum; 437 438 /// Offsets to the stored exprs. 439 /// This enumeration contains offsets to all the pointers to children 440 /// expressions stored in OMPLoopDirective. 441 /// The first 9 children are necessary for all the loop directives, 442 /// the next 8 are specific to the worksharing ones, and the next 11 are 443 /// used for combined constructs containing two pragmas associated to loops. 444 /// After the fixed children, three arrays of length CollapsedNum are 445 /// allocated: loop counters, their updates and final values. 446 /// PrevLowerBound and PrevUpperBound are used to communicate blocking 447 /// information in composite constructs which require loop blocking 448 /// DistInc is used to generate the increment expression for the distribute 449 /// loop when combined with a further nested loop 450 /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the 451 /// for loop when combined with a previous distribute loop in the same pragma 452 /// (e.g. 'distribute parallel for') 453 /// 454 enum { 455 AssociatedStmtOffset = 0, 456 IterationVariableOffset = 1, 457 LastIterationOffset = 2, 458 CalcLastIterationOffset = 3, 459 PreConditionOffset = 4, 460 CondOffset = 5, 461 InitOffset = 6, 462 IncOffset = 7, 463 PreInitsOffset = 8, 464 // The '...End' enumerators do not correspond to child expressions - they 465 // specify the offset to the end (and start of the following counters/ 466 // updates/finals/dependent_counters/dependent_inits/finals_conditions 467 // arrays). 468 DefaultEnd = 9, 469 // The following 8 exprs are used by worksharing and distribute loops only. 470 IsLastIterVariableOffset = 9, 471 LowerBoundVariableOffset = 10, 472 UpperBoundVariableOffset = 11, 473 StrideVariableOffset = 12, 474 EnsureUpperBoundOffset = 13, 475 NextLowerBoundOffset = 14, 476 NextUpperBoundOffset = 15, 477 NumIterationsOffset = 16, 478 // Offset to the end for worksharing loop directives. 479 WorksharingEnd = 17, 480 PrevLowerBoundVariableOffset = 17, 481 PrevUpperBoundVariableOffset = 18, 482 DistIncOffset = 19, 483 PrevEnsureUpperBoundOffset = 20, 484 CombinedLowerBoundVariableOffset = 21, 485 CombinedUpperBoundVariableOffset = 22, 486 CombinedEnsureUpperBoundOffset = 23, 487 CombinedInitOffset = 24, 488 CombinedConditionOffset = 25, 489 CombinedNextLowerBoundOffset = 26, 490 CombinedNextUpperBoundOffset = 27, 491 CombinedDistConditionOffset = 28, 492 CombinedParForInDistConditionOffset = 29, 493 // Offset to the end (and start of the following 494 // counters/updates/finals/dependent_counters/dependent_inits/finals_conditions 495 // arrays) for combined distribute loop directives. 496 CombinedDistributeEnd = 30, 497 }; 498 499 /// Get the counters storage. 500 MutableArrayRef<Expr *> getCounters() { 501 Expr **Storage = reinterpret_cast<Expr **>( 502 &(*(std::next(child_begin(), getArraysOffset(getDirectiveKind()))))); 503 return MutableArrayRef<Expr *>(Storage, CollapsedNum); 504 } 505 506 /// Get the private counters storage. 507 MutableArrayRef<Expr *> getPrivateCounters() { 508 Expr **Storage = reinterpret_cast<Expr **>(&*std::next( 509 child_begin(), getArraysOffset(getDirectiveKind()) + CollapsedNum)); 510 return MutableArrayRef<Expr *>(Storage, CollapsedNum); 511 } 512 513 /// Get the updates storage. 514 MutableArrayRef<Expr *> getInits() { 515 Expr **Storage = reinterpret_cast<Expr **>( 516 &*std::next(child_begin(), 517 getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum)); 518 return MutableArrayRef<Expr *>(Storage, CollapsedNum); 519 } 520 521 /// Get the updates storage. 522 MutableArrayRef<Expr *> getUpdates() { 523 Expr **Storage = reinterpret_cast<Expr **>( 524 &*std::next(child_begin(), 525 getArraysOffset(getDirectiveKind()) + 3 * CollapsedNum)); 526 return MutableArrayRef<Expr *>(Storage, CollapsedNum); 527 } 528 529 /// Get the final counter updates storage. 530 MutableArrayRef<Expr *> getFinals() { 531 Expr **Storage = reinterpret_cast<Expr **>( 532 &*std::next(child_begin(), 533 getArraysOffset(getDirectiveKind()) + 4 * CollapsedNum)); 534 return MutableArrayRef<Expr *>(Storage, CollapsedNum); 535 } 536 537 /// Get the dependent counters storage. 538 MutableArrayRef<Expr *> getDependentCounters() { 539 Expr **Storage = reinterpret_cast<Expr **>( 540 &*std::next(child_begin(), 541 getArraysOffset(getDirectiveKind()) + 5 * CollapsedNum)); 542 return MutableArrayRef<Expr *>(Storage, CollapsedNum); 543 } 544 545 /// Get the dependent inits storage. 546 MutableArrayRef<Expr *> getDependentInits() { 547 Expr **Storage = reinterpret_cast<Expr **>( 548 &*std::next(child_begin(), 549 getArraysOffset(getDirectiveKind()) + 6 * CollapsedNum)); 550 return MutableArrayRef<Expr *>(Storage, CollapsedNum); 551 } 552 553 /// Get the finals conditions storage. 554 MutableArrayRef<Expr *> getFinalsConditions() { 555 Expr **Storage = reinterpret_cast<Expr **>( 556 &*std::next(child_begin(), 557 getArraysOffset(getDirectiveKind()) + 7 * CollapsedNum)); 558 return MutableArrayRef<Expr *>(Storage, CollapsedNum); 559 } 560 561 protected: 562 /// Build instance of loop directive of class \a Kind. 563 /// 564 /// \param SC Statement class. 565 /// \param Kind Kind of OpenMP directive. 566 /// \param StartLoc Starting location of the directive (directive keyword). 567 /// \param EndLoc Ending location of the directive. 568 /// \param CollapsedNum Number of collapsed loops from 'collapse' clause. 569 /// \param NumClauses Number of clauses. 570 /// \param NumSpecialChildren Number of additional directive-specific stmts. 571 /// 572 template <typename T> 573 OMPLoopDirective(const T *That, StmtClass SC, OpenMPDirectiveKind Kind, 574 SourceLocation StartLoc, SourceLocation EndLoc, 575 unsigned CollapsedNum, unsigned NumClauses, 576 unsigned NumSpecialChildren = 0) 577 : OMPExecutableDirective(That, SC, Kind, StartLoc, EndLoc, NumClauses, 578 numLoopChildren(CollapsedNum, Kind) + 579 NumSpecialChildren), 580 CollapsedNum(CollapsedNum) {} 581 582 /// Offset to the start of children expression arrays. 583 static unsigned getArraysOffset(OpenMPDirectiveKind Kind) { 584 if (isOpenMPLoopBoundSharingDirective(Kind)) 585 return CombinedDistributeEnd; 586 if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) || 587 isOpenMPDistributeDirective(Kind)) 588 return WorksharingEnd; 589 return DefaultEnd; 590 } 591 592 /// Children number. 593 static unsigned numLoopChildren(unsigned CollapsedNum, 594 OpenMPDirectiveKind Kind) { 595 return getArraysOffset(Kind) + 596 8 * CollapsedNum; // Counters, PrivateCounters, Inits, 597 // Updates, Finals, DependentCounters, 598 // DependentInits, FinalsConditions. 599 } 600 601 void setIterationVariable(Expr *IV) { 602 *std::next(child_begin(), IterationVariableOffset) = IV; 603 } 604 void setLastIteration(Expr *LI) { 605 *std::next(child_begin(), LastIterationOffset) = LI; 606 } 607 void setCalcLastIteration(Expr *CLI) { 608 *std::next(child_begin(), CalcLastIterationOffset) = CLI; 609 } 610 void setPreCond(Expr *PC) { 611 *std::next(child_begin(), PreConditionOffset) = PC; 612 } 613 void setCond(Expr *Cond) { 614 *std::next(child_begin(), CondOffset) = Cond; 615 } 616 void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; } 617 void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; } 618 void setPreInits(Stmt *PreInits) { 619 *std::next(child_begin(), PreInitsOffset) = PreInits; 620 } 621 void setIsLastIterVariable(Expr *IL) { 622 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 623 isOpenMPTaskLoopDirective(getDirectiveKind()) || 624 isOpenMPDistributeDirective(getDirectiveKind())) && 625 "expected worksharing loop directive"); 626 *std::next(child_begin(), IsLastIterVariableOffset) = IL; 627 } 628 void setLowerBoundVariable(Expr *LB) { 629 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 630 isOpenMPTaskLoopDirective(getDirectiveKind()) || 631 isOpenMPDistributeDirective(getDirectiveKind())) && 632 "expected worksharing loop directive"); 633 *std::next(child_begin(), LowerBoundVariableOffset) = LB; 634 } 635 void setUpperBoundVariable(Expr *UB) { 636 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 637 isOpenMPTaskLoopDirective(getDirectiveKind()) || 638 isOpenMPDistributeDirective(getDirectiveKind())) && 639 "expected worksharing loop directive"); 640 *std::next(child_begin(), UpperBoundVariableOffset) = UB; 641 } 642 void setStrideVariable(Expr *ST) { 643 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 644 isOpenMPTaskLoopDirective(getDirectiveKind()) || 645 isOpenMPDistributeDirective(getDirectiveKind())) && 646 "expected worksharing loop directive"); 647 *std::next(child_begin(), StrideVariableOffset) = ST; 648 } 649 void setEnsureUpperBound(Expr *EUB) { 650 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 651 isOpenMPTaskLoopDirective(getDirectiveKind()) || 652 isOpenMPDistributeDirective(getDirectiveKind())) && 653 "expected worksharing loop directive"); 654 *std::next(child_begin(), EnsureUpperBoundOffset) = EUB; 655 } 656 void setNextLowerBound(Expr *NLB) { 657 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 658 isOpenMPTaskLoopDirective(getDirectiveKind()) || 659 isOpenMPDistributeDirective(getDirectiveKind())) && 660 "expected worksharing loop directive"); 661 *std::next(child_begin(), NextLowerBoundOffset) = NLB; 662 } 663 void setNextUpperBound(Expr *NUB) { 664 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 665 isOpenMPTaskLoopDirective(getDirectiveKind()) || 666 isOpenMPDistributeDirective(getDirectiveKind())) && 667 "expected worksharing loop directive"); 668 *std::next(child_begin(), NextUpperBoundOffset) = NUB; 669 } 670 void setNumIterations(Expr *NI) { 671 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 672 isOpenMPTaskLoopDirective(getDirectiveKind()) || 673 isOpenMPDistributeDirective(getDirectiveKind())) && 674 "expected worksharing loop directive"); 675 *std::next(child_begin(), NumIterationsOffset) = NI; 676 } 677 void setPrevLowerBoundVariable(Expr *PrevLB) { 678 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 679 "expected loop bound sharing directive"); 680 *std::next(child_begin(), PrevLowerBoundVariableOffset) = PrevLB; 681 } 682 void setPrevUpperBoundVariable(Expr *PrevUB) { 683 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 684 "expected loop bound sharing directive"); 685 *std::next(child_begin(), PrevUpperBoundVariableOffset) = PrevUB; 686 } 687 void setDistInc(Expr *DistInc) { 688 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 689 "expected loop bound sharing directive"); 690 *std::next(child_begin(), DistIncOffset) = DistInc; 691 } 692 void setPrevEnsureUpperBound(Expr *PrevEUB) { 693 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 694 "expected loop bound sharing directive"); 695 *std::next(child_begin(), PrevEnsureUpperBoundOffset) = PrevEUB; 696 } 697 void setCombinedLowerBoundVariable(Expr *CombLB) { 698 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 699 "expected loop bound sharing directive"); 700 *std::next(child_begin(), CombinedLowerBoundVariableOffset) = CombLB; 701 } 702 void setCombinedUpperBoundVariable(Expr *CombUB) { 703 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 704 "expected loop bound sharing directive"); 705 *std::next(child_begin(), CombinedUpperBoundVariableOffset) = CombUB; 706 } 707 void setCombinedEnsureUpperBound(Expr *CombEUB) { 708 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 709 "expected loop bound sharing directive"); 710 *std::next(child_begin(), CombinedEnsureUpperBoundOffset) = CombEUB; 711 } 712 void setCombinedInit(Expr *CombInit) { 713 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 714 "expected loop bound sharing directive"); 715 *std::next(child_begin(), CombinedInitOffset) = CombInit; 716 } 717 void setCombinedCond(Expr *CombCond) { 718 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 719 "expected loop bound sharing directive"); 720 *std::next(child_begin(), CombinedConditionOffset) = CombCond; 721 } 722 void setCombinedNextLowerBound(Expr *CombNLB) { 723 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 724 "expected loop bound sharing directive"); 725 *std::next(child_begin(), CombinedNextLowerBoundOffset) = CombNLB; 726 } 727 void setCombinedNextUpperBound(Expr *CombNUB) { 728 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 729 "expected loop bound sharing directive"); 730 *std::next(child_begin(), CombinedNextUpperBoundOffset) = CombNUB; 731 } 732 void setCombinedDistCond(Expr *CombDistCond) { 733 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 734 "expected loop bound distribute sharing directive"); 735 *std::next(child_begin(), CombinedDistConditionOffset) = CombDistCond; 736 } 737 void setCombinedParForInDistCond(Expr *CombParForInDistCond) { 738 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 739 "expected loop bound distribute sharing directive"); 740 *std::next(child_begin(), 741 CombinedParForInDistConditionOffset) = CombParForInDistCond; 742 } 743 void setCounters(ArrayRef<Expr *> A); 744 void setPrivateCounters(ArrayRef<Expr *> A); 745 void setInits(ArrayRef<Expr *> A); 746 void setUpdates(ArrayRef<Expr *> A); 747 void setFinals(ArrayRef<Expr *> A); 748 void setDependentCounters(ArrayRef<Expr *> A); 749 void setDependentInits(ArrayRef<Expr *> A); 750 void setFinalsConditions(ArrayRef<Expr *> A); 751 752 public: 753 /// The expressions built to support OpenMP loops in combined/composite 754 /// pragmas (e.g. pragma omp distribute parallel for) 755 struct DistCombinedHelperExprs { 756 /// DistributeLowerBound - used when composing 'omp distribute' with 757 /// 'omp for' in a same construct. 758 Expr *LB; 759 /// DistributeUpperBound - used when composing 'omp distribute' with 760 /// 'omp for' in a same construct. 761 Expr *UB; 762 /// DistributeEnsureUpperBound - used when composing 'omp distribute' 763 /// with 'omp for' in a same construct, EUB depends on DistUB 764 Expr *EUB; 765 /// Distribute loop iteration variable init used when composing 'omp 766 /// distribute' 767 /// with 'omp for' in a same construct 768 Expr *Init; 769 /// Distribute Loop condition used when composing 'omp distribute' 770 /// with 'omp for' in a same construct 771 Expr *Cond; 772 /// Update of LowerBound for statically scheduled omp loops for 773 /// outer loop in combined constructs (e.g. 'distribute parallel for') 774 Expr *NLB; 775 /// Update of UpperBound for statically scheduled omp loops for 776 /// outer loop in combined constructs (e.g. 'distribute parallel for') 777 Expr *NUB; 778 /// Distribute Loop condition used when composing 'omp distribute' 779 /// with 'omp for' in a same construct when schedule is chunked. 780 Expr *DistCond; 781 /// 'omp parallel for' loop condition used when composed with 782 /// 'omp distribute' in the same construct and when schedule is 783 /// chunked and the chunk size is 1. 784 Expr *ParForInDistCond; 785 }; 786 787 /// The expressions built for the OpenMP loop CodeGen for the 788 /// whole collapsed loop nest. 789 struct HelperExprs { 790 /// Loop iteration variable. 791 Expr *IterationVarRef; 792 /// Loop last iteration number. 793 Expr *LastIteration; 794 /// Loop number of iterations. 795 Expr *NumIterations; 796 /// Calculation of last iteration. 797 Expr *CalcLastIteration; 798 /// Loop pre-condition. 799 Expr *PreCond; 800 /// Loop condition. 801 Expr *Cond; 802 /// Loop iteration variable init. 803 Expr *Init; 804 /// Loop increment. 805 Expr *Inc; 806 /// IsLastIteration - local flag variable passed to runtime. 807 Expr *IL; 808 /// LowerBound - local variable passed to runtime. 809 Expr *LB; 810 /// UpperBound - local variable passed to runtime. 811 Expr *UB; 812 /// Stride - local variable passed to runtime. 813 Expr *ST; 814 /// EnsureUpperBound -- expression UB = min(UB, NumIterations). 815 Expr *EUB; 816 /// Update of LowerBound for statically scheduled 'omp for' loops. 817 Expr *NLB; 818 /// Update of UpperBound for statically scheduled 'omp for' loops. 819 Expr *NUB; 820 /// PreviousLowerBound - local variable passed to runtime in the 821 /// enclosing schedule or null if that does not apply. 822 Expr *PrevLB; 823 /// PreviousUpperBound - local variable passed to runtime in the 824 /// enclosing schedule or null if that does not apply. 825 Expr *PrevUB; 826 /// DistInc - increment expression for distribute loop when found 827 /// combined with a further loop level (e.g. in 'distribute parallel for') 828 /// expression IV = IV + ST 829 Expr *DistInc; 830 /// PrevEUB - expression similar to EUB but to be used when loop 831 /// scheduling uses PrevLB and PrevUB (e.g. in 'distribute parallel for' 832 /// when ensuring that the UB is either the calculated UB by the runtime or 833 /// the end of the assigned distribute chunk) 834 /// expression UB = min (UB, PrevUB) 835 Expr *PrevEUB; 836 /// Counters Loop counters. 837 SmallVector<Expr *, 4> Counters; 838 /// PrivateCounters Loop counters. 839 SmallVector<Expr *, 4> PrivateCounters; 840 /// Expressions for loop counters inits for CodeGen. 841 SmallVector<Expr *, 4> Inits; 842 /// Expressions for loop counters update for CodeGen. 843 SmallVector<Expr *, 4> Updates; 844 /// Final loop counter values for GodeGen. 845 SmallVector<Expr *, 4> Finals; 846 /// List of counters required for the generation of the non-rectangular 847 /// loops. 848 SmallVector<Expr *, 4> DependentCounters; 849 /// List of initializers required for the generation of the non-rectangular 850 /// loops. 851 SmallVector<Expr *, 4> DependentInits; 852 /// List of final conditions required for the generation of the 853 /// non-rectangular loops. 854 SmallVector<Expr *, 4> FinalsConditions; 855 /// Init statement for all captured expressions. 856 Stmt *PreInits; 857 858 /// Expressions used when combining OpenMP loop pragmas 859 DistCombinedHelperExprs DistCombinedFields; 860 861 /// Check if all the expressions are built (does not check the 862 /// worksharing ones). 863 bool builtAll() { 864 return IterationVarRef != nullptr && LastIteration != nullptr && 865 NumIterations != nullptr && PreCond != nullptr && 866 Cond != nullptr && Init != nullptr && Inc != nullptr; 867 } 868 869 /// Initialize all the fields to null. 870 /// \param Size Number of elements in the 871 /// counters/finals/updates/dependent_counters/dependent_inits/finals_conditions 872 /// arrays. 873 void clear(unsigned Size) { 874 IterationVarRef = nullptr; 875 LastIteration = nullptr; 876 CalcLastIteration = nullptr; 877 PreCond = nullptr; 878 Cond = nullptr; 879 Init = nullptr; 880 Inc = nullptr; 881 IL = nullptr; 882 LB = nullptr; 883 UB = nullptr; 884 ST = nullptr; 885 EUB = nullptr; 886 NLB = nullptr; 887 NUB = nullptr; 888 NumIterations = nullptr; 889 PrevLB = nullptr; 890 PrevUB = nullptr; 891 DistInc = nullptr; 892 PrevEUB = nullptr; 893 Counters.resize(Size); 894 PrivateCounters.resize(Size); 895 Inits.resize(Size); 896 Updates.resize(Size); 897 Finals.resize(Size); 898 DependentCounters.resize(Size); 899 DependentInits.resize(Size); 900 FinalsConditions.resize(Size); 901 for (unsigned i = 0; i < Size; ++i) { 902 Counters[i] = nullptr; 903 PrivateCounters[i] = nullptr; 904 Inits[i] = nullptr; 905 Updates[i] = nullptr; 906 Finals[i] = nullptr; 907 DependentCounters[i] = nullptr; 908 DependentInits[i] = nullptr; 909 FinalsConditions[i] = nullptr; 910 } 911 PreInits = nullptr; 912 DistCombinedFields.LB = nullptr; 913 DistCombinedFields.UB = nullptr; 914 DistCombinedFields.EUB = nullptr; 915 DistCombinedFields.Init = nullptr; 916 DistCombinedFields.Cond = nullptr; 917 DistCombinedFields.NLB = nullptr; 918 DistCombinedFields.NUB = nullptr; 919 DistCombinedFields.DistCond = nullptr; 920 DistCombinedFields.ParForInDistCond = nullptr; 921 } 922 }; 923 924 /// Get number of collapsed loops. 925 unsigned getCollapsedNumber() const { return CollapsedNum; } 926 927 Expr *getIterationVariable() const { 928 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 929 *std::next(child_begin(), IterationVariableOffset))); 930 } 931 Expr *getLastIteration() const { 932 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 933 *std::next(child_begin(), LastIterationOffset))); 934 } 935 Expr *getCalcLastIteration() const { 936 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 937 *std::next(child_begin(), CalcLastIterationOffset))); 938 } 939 Expr *getPreCond() const { 940 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 941 *std::next(child_begin(), PreConditionOffset))); 942 } 943 Expr *getCond() const { 944 return const_cast<Expr *>( 945 reinterpret_cast<const Expr *>(*std::next(child_begin(), CondOffset))); 946 } 947 Expr *getInit() const { 948 return const_cast<Expr *>( 949 reinterpret_cast<const Expr *>(*std::next(child_begin(), InitOffset))); 950 } 951 Expr *getInc() const { 952 return const_cast<Expr *>( 953 reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset))); 954 } 955 const Stmt *getPreInits() const { 956 return *std::next(child_begin(), PreInitsOffset); 957 } 958 Stmt *getPreInits() { return *std::next(child_begin(), PreInitsOffset); } 959 Expr *getIsLastIterVariable() const { 960 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 961 isOpenMPTaskLoopDirective(getDirectiveKind()) || 962 isOpenMPDistributeDirective(getDirectiveKind())) && 963 "expected worksharing loop directive"); 964 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 965 *std::next(child_begin(), IsLastIterVariableOffset))); 966 } 967 Expr *getLowerBoundVariable() const { 968 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 969 isOpenMPTaskLoopDirective(getDirectiveKind()) || 970 isOpenMPDistributeDirective(getDirectiveKind())) && 971 "expected worksharing loop directive"); 972 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 973 *std::next(child_begin(), LowerBoundVariableOffset))); 974 } 975 Expr *getUpperBoundVariable() const { 976 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 977 isOpenMPTaskLoopDirective(getDirectiveKind()) || 978 isOpenMPDistributeDirective(getDirectiveKind())) && 979 "expected worksharing loop directive"); 980 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 981 *std::next(child_begin(), UpperBoundVariableOffset))); 982 } 983 Expr *getStrideVariable() const { 984 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 985 isOpenMPTaskLoopDirective(getDirectiveKind()) || 986 isOpenMPDistributeDirective(getDirectiveKind())) && 987 "expected worksharing loop directive"); 988 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 989 *std::next(child_begin(), StrideVariableOffset))); 990 } 991 Expr *getEnsureUpperBound() const { 992 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 993 isOpenMPTaskLoopDirective(getDirectiveKind()) || 994 isOpenMPDistributeDirective(getDirectiveKind())) && 995 "expected worksharing loop directive"); 996 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 997 *std::next(child_begin(), EnsureUpperBoundOffset))); 998 } 999 Expr *getNextLowerBound() const { 1000 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1001 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1002 isOpenMPDistributeDirective(getDirectiveKind())) && 1003 "expected worksharing loop directive"); 1004 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 1005 *std::next(child_begin(), NextLowerBoundOffset))); 1006 } 1007 Expr *getNextUpperBound() const { 1008 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1009 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1010 isOpenMPDistributeDirective(getDirectiveKind())) && 1011 "expected worksharing loop directive"); 1012 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 1013 *std::next(child_begin(), NextUpperBoundOffset))); 1014 } 1015 Expr *getNumIterations() const { 1016 assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 1017 isOpenMPTaskLoopDirective(getDirectiveKind()) || 1018 isOpenMPDistributeDirective(getDirectiveKind())) && 1019 "expected worksharing loop directive"); 1020 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 1021 *std::next(child_begin(), NumIterationsOffset))); 1022 } 1023 Expr *getPrevLowerBoundVariable() const { 1024 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1025 "expected loop bound sharing directive"); 1026 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 1027 *std::next(child_begin(), PrevLowerBoundVariableOffset))); 1028 } 1029 Expr *getPrevUpperBoundVariable() const { 1030 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1031 "expected loop bound sharing directive"); 1032 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 1033 *std::next(child_begin(), PrevUpperBoundVariableOffset))); 1034 } 1035 Expr *getDistInc() const { 1036 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1037 "expected loop bound sharing directive"); 1038 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 1039 *std::next(child_begin(), DistIncOffset))); 1040 } 1041 Expr *getPrevEnsureUpperBound() const { 1042 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1043 "expected loop bound sharing directive"); 1044 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 1045 *std::next(child_begin(), PrevEnsureUpperBoundOffset))); 1046 } 1047 Expr *getCombinedLowerBoundVariable() const { 1048 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1049 "expected loop bound sharing directive"); 1050 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 1051 *std::next(child_begin(), CombinedLowerBoundVariableOffset))); 1052 } 1053 Expr *getCombinedUpperBoundVariable() const { 1054 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1055 "expected loop bound sharing directive"); 1056 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 1057 *std::next(child_begin(), CombinedUpperBoundVariableOffset))); 1058 } 1059 Expr *getCombinedEnsureUpperBound() const { 1060 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1061 "expected loop bound sharing directive"); 1062 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 1063 *std::next(child_begin(), CombinedEnsureUpperBoundOffset))); 1064 } 1065 Expr *getCombinedInit() const { 1066 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1067 "expected loop bound sharing directive"); 1068 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 1069 *std::next(child_begin(), CombinedInitOffset))); 1070 } 1071 Expr *getCombinedCond() const { 1072 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1073 "expected loop bound sharing directive"); 1074 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 1075 *std::next(child_begin(), CombinedConditionOffset))); 1076 } 1077 Expr *getCombinedNextLowerBound() const { 1078 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1079 "expected loop bound sharing directive"); 1080 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 1081 *std::next(child_begin(), CombinedNextLowerBoundOffset))); 1082 } 1083 Expr *getCombinedNextUpperBound() const { 1084 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1085 "expected loop bound sharing directive"); 1086 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 1087 *std::next(child_begin(), CombinedNextUpperBoundOffset))); 1088 } 1089 Expr *getCombinedDistCond() const { 1090 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1091 "expected loop bound distribute sharing directive"); 1092 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 1093 *std::next(child_begin(), CombinedDistConditionOffset))); 1094 } 1095 Expr *getCombinedParForInDistCond() const { 1096 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 1097 "expected loop bound distribute sharing directive"); 1098 return const_cast<Expr *>(reinterpret_cast<const Expr *>( 1099 *std::next(child_begin(), CombinedParForInDistConditionOffset))); 1100 } 1101 /// Try to find the next loop sub-statement in the specified statement \p 1102 /// CurStmt. 1103 /// \param TryImperfectlyNestedLoops true, if we need to try to look for the 1104 /// imperfectly nested loop. 1105 static Stmt *tryToFindNextInnerLoop(Stmt *CurStmt, 1106 bool TryImperfectlyNestedLoops); 1107 static const Stmt *tryToFindNextInnerLoop(const Stmt *CurStmt, 1108 bool TryImperfectlyNestedLoops) { 1109 return tryToFindNextInnerLoop(const_cast<Stmt *>(CurStmt), 1110 TryImperfectlyNestedLoops); 1111 } 1112 Stmt *getBody(); 1113 const Stmt *getBody() const { 1114 return const_cast<OMPLoopDirective *>(this)->getBody(); 1115 } 1116 1117 ArrayRef<Expr *> counters() { return getCounters(); } 1118 1119 ArrayRef<Expr *> counters() const { 1120 return const_cast<OMPLoopDirective *>(this)->getCounters(); 1121 } 1122 1123 ArrayRef<Expr *> private_counters() { return getPrivateCounters(); } 1124 1125 ArrayRef<Expr *> private_counters() const { 1126 return const_cast<OMPLoopDirective *>(this)->getPrivateCounters(); 1127 } 1128 1129 ArrayRef<Expr *> inits() { return getInits(); } 1130 1131 ArrayRef<Expr *> inits() const { 1132 return const_cast<OMPLoopDirective *>(this)->getInits(); 1133 } 1134 1135 ArrayRef<Expr *> updates() { return getUpdates(); } 1136 1137 ArrayRef<Expr *> updates() const { 1138 return const_cast<OMPLoopDirective *>(this)->getUpdates(); 1139 } 1140 1141 ArrayRef<Expr *> finals() { return getFinals(); } 1142 1143 ArrayRef<Expr *> finals() const { 1144 return const_cast<OMPLoopDirective *>(this)->getFinals(); 1145 } 1146 1147 ArrayRef<Expr *> dependent_counters() { return getDependentCounters(); } 1148 1149 ArrayRef<Expr *> dependent_counters() const { 1150 return const_cast<OMPLoopDirective *>(this)->getDependentCounters(); 1151 } 1152 1153 ArrayRef<Expr *> dependent_inits() { return getDependentInits(); } 1154 1155 ArrayRef<Expr *> dependent_inits() const { 1156 return const_cast<OMPLoopDirective *>(this)->getDependentInits(); 1157 } 1158 1159 ArrayRef<Expr *> finals_conditions() { return getFinalsConditions(); } 1160 1161 ArrayRef<Expr *> finals_conditions() const { 1162 return const_cast<OMPLoopDirective *>(this)->getFinalsConditions(); 1163 } 1164 1165 static bool classof(const Stmt *T) { 1166 return T->getStmtClass() == OMPSimdDirectiveClass || 1167 T->getStmtClass() == OMPForDirectiveClass || 1168 T->getStmtClass() == OMPForSimdDirectiveClass || 1169 T->getStmtClass() == OMPParallelForDirectiveClass || 1170 T->getStmtClass() == OMPParallelForSimdDirectiveClass || 1171 T->getStmtClass() == OMPTaskLoopDirectiveClass || 1172 T->getStmtClass() == OMPTaskLoopSimdDirectiveClass || 1173 T->getStmtClass() == OMPMasterTaskLoopDirectiveClass || 1174 T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass || 1175 T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass || 1176 T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass || 1177 T->getStmtClass() == OMPDistributeDirectiveClass || 1178 T->getStmtClass() == OMPTargetParallelForDirectiveClass || 1179 T->getStmtClass() == OMPDistributeParallelForDirectiveClass || 1180 T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass || 1181 T->getStmtClass() == OMPDistributeSimdDirectiveClass || 1182 T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass || 1183 T->getStmtClass() == OMPTargetSimdDirectiveClass || 1184 T->getStmtClass() == OMPTeamsDistributeDirectiveClass || 1185 T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass || 1186 T->getStmtClass() == 1187 OMPTeamsDistributeParallelForSimdDirectiveClass || 1188 T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass || 1189 T->getStmtClass() == 1190 OMPTargetTeamsDistributeParallelForDirectiveClass || 1191 T->getStmtClass() == 1192 OMPTargetTeamsDistributeParallelForSimdDirectiveClass || 1193 T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass || 1194 T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass; 1195 } 1196 }; 1197 1198 /// This represents '#pragma omp simd' directive. 1199 /// 1200 /// \code 1201 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d) 1202 /// \endcode 1203 /// In this example directive '#pragma omp simd' has clauses 'private' 1204 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and 1205 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. 1206 /// 1207 class OMPSimdDirective : public OMPLoopDirective { 1208 friend class ASTStmtReader; 1209 /// Build directive with the given start and end location. 1210 /// 1211 /// \param StartLoc Starting location of the directive kind. 1212 /// \param EndLoc Ending location of the directive. 1213 /// \param CollapsedNum Number of collapsed nested loops. 1214 /// \param NumClauses Number of clauses. 1215 /// 1216 OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1217 unsigned CollapsedNum, unsigned NumClauses) 1218 : OMPLoopDirective(this, OMPSimdDirectiveClass, llvm::omp::OMPD_simd, 1219 StartLoc, EndLoc, CollapsedNum, NumClauses) {} 1220 1221 /// Build an empty directive. 1222 /// 1223 /// \param CollapsedNum Number of collapsed nested loops. 1224 /// \param NumClauses Number of clauses. 1225 /// 1226 explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses) 1227 : OMPLoopDirective(this, OMPSimdDirectiveClass, llvm::omp::OMPD_simd, 1228 SourceLocation(), SourceLocation(), CollapsedNum, 1229 NumClauses) {} 1230 1231 public: 1232 /// Creates directive with a list of \a Clauses. 1233 /// 1234 /// \param C AST context. 1235 /// \param StartLoc Starting location of the directive kind. 1236 /// \param EndLoc Ending Location of the directive. 1237 /// \param CollapsedNum Number of collapsed loops. 1238 /// \param Clauses List of clauses. 1239 /// \param AssociatedStmt Statement, associated with the directive. 1240 /// \param Exprs Helper expressions for CodeGen. 1241 /// 1242 static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc, 1243 SourceLocation EndLoc, unsigned CollapsedNum, 1244 ArrayRef<OMPClause *> Clauses, 1245 Stmt *AssociatedStmt, 1246 const HelperExprs &Exprs); 1247 1248 /// Creates an empty directive with the place 1249 /// for \a NumClauses clauses. 1250 /// 1251 /// \param C AST context. 1252 /// \param CollapsedNum Number of collapsed nested loops. 1253 /// \param NumClauses Number of clauses. 1254 /// 1255 static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 1256 unsigned CollapsedNum, EmptyShell); 1257 1258 static bool classof(const Stmt *T) { 1259 return T->getStmtClass() == OMPSimdDirectiveClass; 1260 } 1261 }; 1262 1263 /// This represents '#pragma omp for' directive. 1264 /// 1265 /// \code 1266 /// #pragma omp for private(a,b) reduction(+:c,d) 1267 /// \endcode 1268 /// In this example directive '#pragma omp for' has clauses 'private' with the 1269 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c' 1270 /// and 'd'. 1271 /// 1272 class OMPForDirective : public OMPLoopDirective { 1273 friend class ASTStmtReader; 1274 /// Special reference expression for handling task reduction. Used to store 1275 /// the taskgroup descriptor returned by the runtime functions. 1276 Expr *TaskRedRef = nullptr; 1277 /// true if current directive has inner cancel directive. 1278 bool HasCancel; 1279 1280 /// Build directive with the given start and end location. 1281 /// 1282 /// \param StartLoc Starting location of the directive kind. 1283 /// \param EndLoc Ending location of the directive. 1284 /// \param CollapsedNum Number of collapsed nested loops. 1285 /// \param NumClauses Number of clauses. 1286 /// 1287 OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1288 unsigned CollapsedNum, unsigned NumClauses) 1289 : OMPLoopDirective(this, OMPForDirectiveClass, llvm::omp::OMPD_for, 1290 StartLoc, EndLoc, CollapsedNum, NumClauses), 1291 HasCancel(false) {} 1292 1293 /// Build an empty directive. 1294 /// 1295 /// \param CollapsedNum Number of collapsed nested loops. 1296 /// \param NumClauses Number of clauses. 1297 /// 1298 explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses) 1299 : OMPLoopDirective(this, OMPForDirectiveClass, llvm::omp::OMPD_for, 1300 SourceLocation(), SourceLocation(), CollapsedNum, 1301 NumClauses), 1302 HasCancel(false) {} 1303 1304 /// Sets special task reduction descriptor. 1305 void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } 1306 1307 /// Set cancel state. 1308 void setHasCancel(bool Has) { HasCancel = Has; } 1309 1310 public: 1311 /// Creates directive with a list of \a Clauses. 1312 /// 1313 /// \param C AST context. 1314 /// \param StartLoc Starting location of the directive kind. 1315 /// \param EndLoc Ending Location of the directive. 1316 /// \param CollapsedNum Number of collapsed loops. 1317 /// \param Clauses List of clauses. 1318 /// \param AssociatedStmt Statement, associated with the directive. 1319 /// \param Exprs Helper expressions for CodeGen. 1320 /// \param TaskRedRef Task reduction special reference expression to handle 1321 /// taskgroup descriptor. 1322 /// \param HasCancel true if current directive has inner cancel directive. 1323 /// 1324 static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc, 1325 SourceLocation EndLoc, unsigned CollapsedNum, 1326 ArrayRef<OMPClause *> Clauses, 1327 Stmt *AssociatedStmt, const HelperExprs &Exprs, 1328 Expr *TaskRedRef, bool HasCancel); 1329 1330 /// Creates an empty directive with the place 1331 /// for \a NumClauses clauses. 1332 /// 1333 /// \param C AST context. 1334 /// \param CollapsedNum Number of collapsed nested loops. 1335 /// \param NumClauses Number of clauses. 1336 /// 1337 static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 1338 unsigned CollapsedNum, EmptyShell); 1339 1340 /// Returns special task reduction reference expression. 1341 Expr *getTaskReductionRefExpr() { return TaskRedRef; } 1342 const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } 1343 1344 /// Return true if current directive has inner cancel directive. 1345 bool hasCancel() const { return HasCancel; } 1346 1347 static bool classof(const Stmt *T) { 1348 return T->getStmtClass() == OMPForDirectiveClass; 1349 } 1350 }; 1351 1352 /// This represents '#pragma omp for simd' directive. 1353 /// 1354 /// \code 1355 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d) 1356 /// \endcode 1357 /// In this example directive '#pragma omp for simd' has clauses 'private' 1358 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and 1359 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. 1360 /// 1361 class OMPForSimdDirective : public OMPLoopDirective { 1362 friend class ASTStmtReader; 1363 /// Build directive with the given start and end location. 1364 /// 1365 /// \param StartLoc Starting location of the directive kind. 1366 /// \param EndLoc Ending location of the directive. 1367 /// \param CollapsedNum Number of collapsed nested loops. 1368 /// \param NumClauses Number of clauses. 1369 /// 1370 OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1371 unsigned CollapsedNum, unsigned NumClauses) 1372 : OMPLoopDirective(this, OMPForSimdDirectiveClass, 1373 llvm::omp::OMPD_for_simd, StartLoc, EndLoc, 1374 CollapsedNum, NumClauses) {} 1375 1376 /// Build an empty directive. 1377 /// 1378 /// \param CollapsedNum Number of collapsed nested loops. 1379 /// \param NumClauses Number of clauses. 1380 /// 1381 explicit OMPForSimdDirective(unsigned CollapsedNum, unsigned NumClauses) 1382 : OMPLoopDirective(this, OMPForSimdDirectiveClass, 1383 llvm::omp::OMPD_for_simd, SourceLocation(), 1384 SourceLocation(), CollapsedNum, NumClauses) {} 1385 1386 public: 1387 /// Creates directive with a list of \a Clauses. 1388 /// 1389 /// \param C AST context. 1390 /// \param StartLoc Starting location of the directive kind. 1391 /// \param EndLoc Ending Location of the directive. 1392 /// \param CollapsedNum Number of collapsed loops. 1393 /// \param Clauses List of clauses. 1394 /// \param AssociatedStmt Statement, associated with the directive. 1395 /// \param Exprs Helper expressions for CodeGen. 1396 /// 1397 static OMPForSimdDirective * 1398 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1399 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 1400 Stmt *AssociatedStmt, const HelperExprs &Exprs); 1401 1402 /// Creates an empty directive with the place 1403 /// for \a NumClauses clauses. 1404 /// 1405 /// \param C AST context. 1406 /// \param CollapsedNum Number of collapsed nested loops. 1407 /// \param NumClauses Number of clauses. 1408 /// 1409 static OMPForSimdDirective *CreateEmpty(const ASTContext &C, 1410 unsigned NumClauses, 1411 unsigned CollapsedNum, EmptyShell); 1412 1413 static bool classof(const Stmt *T) { 1414 return T->getStmtClass() == OMPForSimdDirectiveClass; 1415 } 1416 }; 1417 1418 /// This represents '#pragma omp sections' directive. 1419 /// 1420 /// \code 1421 /// #pragma omp sections private(a,b) reduction(+:c,d) 1422 /// \endcode 1423 /// In this example directive '#pragma omp sections' has clauses 'private' with 1424 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables 1425 /// 'c' and 'd'. 1426 /// 1427 class OMPSectionsDirective : public OMPExecutableDirective { 1428 friend class ASTStmtReader; 1429 1430 /// Special reference expression for handling task reduction. Used to store 1431 /// the taskgroup descriptor returned by the runtime functions. 1432 Expr *TaskRedRef = nullptr; 1433 /// true if current directive has inner cancel directive. 1434 bool HasCancel; 1435 1436 /// Build directive with the given start and end location. 1437 /// 1438 /// \param StartLoc Starting location of the directive kind. 1439 /// \param EndLoc Ending location of the directive. 1440 /// \param NumClauses Number of clauses. 1441 /// 1442 OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1443 unsigned NumClauses) 1444 : OMPExecutableDirective(this, OMPSectionsDirectiveClass, 1445 llvm::omp::OMPD_sections, StartLoc, EndLoc, 1446 NumClauses, 1), 1447 HasCancel(false) {} 1448 1449 /// Build an empty directive. 1450 /// 1451 /// \param NumClauses Number of clauses. 1452 /// 1453 explicit OMPSectionsDirective(unsigned NumClauses) 1454 : OMPExecutableDirective(this, OMPSectionsDirectiveClass, 1455 llvm::omp::OMPD_sections, SourceLocation(), 1456 SourceLocation(), NumClauses, 1), 1457 HasCancel(false) {} 1458 1459 /// Sets special task reduction descriptor. 1460 void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } 1461 1462 /// Set cancel state. 1463 void setHasCancel(bool Has) { HasCancel = Has; } 1464 1465 public: 1466 /// Creates directive with a list of \a Clauses. 1467 /// 1468 /// \param C AST context. 1469 /// \param StartLoc Starting location of the directive kind. 1470 /// \param EndLoc Ending Location of the directive. 1471 /// \param Clauses List of clauses. 1472 /// \param AssociatedStmt Statement, associated with the directive. 1473 /// \param TaskRedRef Task reduction special reference expression to handle 1474 /// taskgroup descriptor. 1475 /// \param HasCancel true if current directive has inner directive. 1476 /// 1477 static OMPSectionsDirective * 1478 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1479 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 1480 bool HasCancel); 1481 1482 /// Creates an empty directive with the place for \a NumClauses 1483 /// clauses. 1484 /// 1485 /// \param C AST context. 1486 /// \param NumClauses Number of clauses. 1487 /// 1488 static OMPSectionsDirective *CreateEmpty(const ASTContext &C, 1489 unsigned NumClauses, EmptyShell); 1490 1491 /// Returns special task reduction reference expression. 1492 Expr *getTaskReductionRefExpr() { return TaskRedRef; } 1493 const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } 1494 1495 /// Return true if current directive has inner cancel directive. 1496 bool hasCancel() const { return HasCancel; } 1497 1498 static bool classof(const Stmt *T) { 1499 return T->getStmtClass() == OMPSectionsDirectiveClass; 1500 } 1501 }; 1502 1503 /// This represents '#pragma omp section' directive. 1504 /// 1505 /// \code 1506 /// #pragma omp section 1507 /// \endcode 1508 /// 1509 class OMPSectionDirective : public OMPExecutableDirective { 1510 friend class ASTStmtReader; 1511 1512 /// true if current directive has inner cancel directive. 1513 bool HasCancel; 1514 1515 /// Build directive with the given start and end location. 1516 /// 1517 /// \param StartLoc Starting location of the directive kind. 1518 /// \param EndLoc Ending location of the directive. 1519 /// 1520 OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1521 : OMPExecutableDirective(this, OMPSectionDirectiveClass, 1522 llvm::omp::OMPD_section, StartLoc, EndLoc, 0, 1), 1523 HasCancel(false) {} 1524 1525 /// Build an empty directive. 1526 /// 1527 explicit OMPSectionDirective() 1528 : OMPExecutableDirective(this, OMPSectionDirectiveClass, 1529 llvm::omp::OMPD_section, SourceLocation(), 1530 SourceLocation(), 0, 1), 1531 HasCancel(false) {} 1532 1533 public: 1534 /// Creates directive. 1535 /// 1536 /// \param C AST context. 1537 /// \param StartLoc Starting location of the directive kind. 1538 /// \param EndLoc Ending Location of the directive. 1539 /// \param AssociatedStmt Statement, associated with the directive. 1540 /// \param HasCancel true if current directive has inner directive. 1541 /// 1542 static OMPSectionDirective *Create(const ASTContext &C, 1543 SourceLocation StartLoc, 1544 SourceLocation EndLoc, 1545 Stmt *AssociatedStmt, bool HasCancel); 1546 1547 /// Creates an empty directive. 1548 /// 1549 /// \param C AST context. 1550 /// 1551 static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell); 1552 1553 /// Set cancel state. 1554 void setHasCancel(bool Has) { HasCancel = Has; } 1555 1556 /// Return true if current directive has inner cancel directive. 1557 bool hasCancel() const { return HasCancel; } 1558 1559 static bool classof(const Stmt *T) { 1560 return T->getStmtClass() == OMPSectionDirectiveClass; 1561 } 1562 }; 1563 1564 /// This represents '#pragma omp single' directive. 1565 /// 1566 /// \code 1567 /// #pragma omp single private(a,b) copyprivate(c,d) 1568 /// \endcode 1569 /// In this example directive '#pragma omp single' has clauses 'private' with 1570 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'. 1571 /// 1572 class OMPSingleDirective : public OMPExecutableDirective { 1573 friend class ASTStmtReader; 1574 /// Build directive with the given start and end location. 1575 /// 1576 /// \param StartLoc Starting location of the directive kind. 1577 /// \param EndLoc Ending location of the directive. 1578 /// \param NumClauses Number of clauses. 1579 /// 1580 OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1581 unsigned NumClauses) 1582 : OMPExecutableDirective(this, OMPSingleDirectiveClass, 1583 llvm::omp::OMPD_single, StartLoc, EndLoc, 1584 NumClauses, 1) {} 1585 1586 /// Build an empty directive. 1587 /// 1588 /// \param NumClauses Number of clauses. 1589 /// 1590 explicit OMPSingleDirective(unsigned NumClauses) 1591 : OMPExecutableDirective(this, OMPSingleDirectiveClass, 1592 llvm::omp::OMPD_single, SourceLocation(), 1593 SourceLocation(), NumClauses, 1) {} 1594 1595 public: 1596 /// Creates directive with a list of \a Clauses. 1597 /// 1598 /// \param C AST context. 1599 /// \param StartLoc Starting location of the directive kind. 1600 /// \param EndLoc Ending Location of the directive. 1601 /// \param Clauses List of clauses. 1602 /// \param AssociatedStmt Statement, associated with the directive. 1603 /// 1604 static OMPSingleDirective * 1605 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1606 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 1607 1608 /// Creates an empty directive with the place for \a NumClauses 1609 /// clauses. 1610 /// 1611 /// \param C AST context. 1612 /// \param NumClauses Number of clauses. 1613 /// 1614 static OMPSingleDirective *CreateEmpty(const ASTContext &C, 1615 unsigned NumClauses, EmptyShell); 1616 1617 static bool classof(const Stmt *T) { 1618 return T->getStmtClass() == OMPSingleDirectiveClass; 1619 } 1620 }; 1621 1622 /// This represents '#pragma omp master' directive. 1623 /// 1624 /// \code 1625 /// #pragma omp master 1626 /// \endcode 1627 /// 1628 class OMPMasterDirective : public OMPExecutableDirective { 1629 friend class ASTStmtReader; 1630 /// Build directive with the given start and end location. 1631 /// 1632 /// \param StartLoc Starting location of the directive kind. 1633 /// \param EndLoc Ending location of the directive. 1634 /// 1635 OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc) 1636 : OMPExecutableDirective(this, OMPMasterDirectiveClass, 1637 llvm::omp::OMPD_master, StartLoc, EndLoc, 0, 1) { 1638 } 1639 1640 /// Build an empty directive. 1641 /// 1642 explicit OMPMasterDirective() 1643 : OMPExecutableDirective(this, OMPMasterDirectiveClass, 1644 llvm::omp::OMPD_master, SourceLocation(), 1645 SourceLocation(), 0, 1) {} 1646 1647 public: 1648 /// Creates directive. 1649 /// 1650 /// \param C AST context. 1651 /// \param StartLoc Starting location of the directive kind. 1652 /// \param EndLoc Ending Location of the directive. 1653 /// \param AssociatedStmt Statement, associated with the directive. 1654 /// 1655 static OMPMasterDirective *Create(const ASTContext &C, 1656 SourceLocation StartLoc, 1657 SourceLocation EndLoc, 1658 Stmt *AssociatedStmt); 1659 1660 /// Creates an empty directive. 1661 /// 1662 /// \param C AST context. 1663 /// 1664 static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell); 1665 1666 static bool classof(const Stmt *T) { 1667 return T->getStmtClass() == OMPMasterDirectiveClass; 1668 } 1669 }; 1670 1671 /// This represents '#pragma omp critical' directive. 1672 /// 1673 /// \code 1674 /// #pragma omp critical 1675 /// \endcode 1676 /// 1677 class OMPCriticalDirective : public OMPExecutableDirective { 1678 friend class ASTStmtReader; 1679 /// Name of the directive. 1680 DeclarationNameInfo DirName; 1681 /// Build directive with the given start and end location. 1682 /// 1683 /// \param Name Name of the directive. 1684 /// \param StartLoc Starting location of the directive kind. 1685 /// \param EndLoc Ending location of the directive. 1686 /// \param NumClauses Number of clauses. 1687 /// 1688 OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc, 1689 SourceLocation EndLoc, unsigned NumClauses) 1690 : OMPExecutableDirective(this, OMPCriticalDirectiveClass, 1691 llvm::omp::OMPD_critical, StartLoc, EndLoc, 1692 NumClauses, 1), 1693 DirName(Name) {} 1694 1695 /// Build an empty directive. 1696 /// 1697 /// \param NumClauses Number of clauses. 1698 /// 1699 explicit OMPCriticalDirective(unsigned NumClauses) 1700 : OMPExecutableDirective(this, OMPCriticalDirectiveClass, 1701 llvm::omp::OMPD_critical, SourceLocation(), 1702 SourceLocation(), NumClauses, 1), 1703 DirName() {} 1704 1705 /// Set name of the directive. 1706 /// 1707 /// \param Name Name of the directive. 1708 /// 1709 void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; } 1710 1711 public: 1712 /// Creates directive. 1713 /// 1714 /// \param C AST context. 1715 /// \param Name Name of the directive. 1716 /// \param StartLoc Starting location of the directive kind. 1717 /// \param EndLoc Ending Location of the directive. 1718 /// \param Clauses List of clauses. 1719 /// \param AssociatedStmt Statement, associated with the directive. 1720 /// 1721 static OMPCriticalDirective * 1722 Create(const ASTContext &C, const DeclarationNameInfo &Name, 1723 SourceLocation StartLoc, SourceLocation EndLoc, 1724 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 1725 1726 /// Creates an empty directive. 1727 /// 1728 /// \param C AST context. 1729 /// \param NumClauses Number of clauses. 1730 /// 1731 static OMPCriticalDirective *CreateEmpty(const ASTContext &C, 1732 unsigned NumClauses, EmptyShell); 1733 1734 /// Return name of the directive. 1735 /// 1736 DeclarationNameInfo getDirectiveName() const { return DirName; } 1737 1738 static bool classof(const Stmt *T) { 1739 return T->getStmtClass() == OMPCriticalDirectiveClass; 1740 } 1741 }; 1742 1743 /// This represents '#pragma omp parallel for' directive. 1744 /// 1745 /// \code 1746 /// #pragma omp parallel for private(a,b) reduction(+:c,d) 1747 /// \endcode 1748 /// In this example directive '#pragma omp parallel for' has clauses 'private' 1749 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and 1750 /// variables 'c' and 'd'. 1751 /// 1752 class OMPParallelForDirective : public OMPLoopDirective { 1753 friend class ASTStmtReader; 1754 1755 /// Special reference expression for handling task reduction. Used to store 1756 /// the taskgroup descriptor returned by the runtime functions. 1757 Expr *TaskRedRef = nullptr; 1758 /// true if current region has inner cancel directive. 1759 bool HasCancel; 1760 1761 /// Build directive with the given start and end location. 1762 /// 1763 /// \param StartLoc Starting location of the directive kind. 1764 /// \param EndLoc Ending location of the directive. 1765 /// \param CollapsedNum Number of collapsed nested loops. 1766 /// \param NumClauses Number of clauses. 1767 /// 1768 OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1769 unsigned CollapsedNum, unsigned NumClauses) 1770 : OMPLoopDirective(this, OMPParallelForDirectiveClass, 1771 llvm::omp::OMPD_parallel_for, StartLoc, EndLoc, 1772 CollapsedNum, NumClauses), 1773 HasCancel(false) {} 1774 1775 /// Build an empty directive. 1776 /// 1777 /// \param CollapsedNum Number of collapsed nested loops. 1778 /// \param NumClauses Number of clauses. 1779 /// 1780 explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses) 1781 : OMPLoopDirective(this, OMPParallelForDirectiveClass, 1782 llvm::omp::OMPD_parallel_for, SourceLocation(), 1783 SourceLocation(), CollapsedNum, NumClauses), 1784 HasCancel(false) {} 1785 1786 /// Sets special task reduction descriptor. 1787 void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } 1788 1789 /// Set cancel state. 1790 void setHasCancel(bool Has) { HasCancel = Has; } 1791 1792 public: 1793 /// Creates directive with a list of \a Clauses. 1794 /// 1795 /// \param C AST context. 1796 /// \param StartLoc Starting location of the directive kind. 1797 /// \param EndLoc Ending Location of the directive. 1798 /// \param CollapsedNum Number of collapsed loops. 1799 /// \param Clauses List of clauses. 1800 /// \param AssociatedStmt Statement, associated with the directive. 1801 /// \param Exprs Helper expressions for CodeGen. 1802 /// \param TaskRedRef Task reduction special reference expression to handle 1803 /// taskgroup descriptor. 1804 /// \param HasCancel true if current directive has inner cancel directive. 1805 /// 1806 static OMPParallelForDirective * 1807 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1808 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 1809 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 1810 bool HasCancel); 1811 1812 /// Creates an empty directive with the place 1813 /// for \a NumClauses clauses. 1814 /// 1815 /// \param C AST context. 1816 /// \param CollapsedNum Number of collapsed nested loops. 1817 /// \param NumClauses Number of clauses. 1818 /// 1819 static OMPParallelForDirective *CreateEmpty(const ASTContext &C, 1820 unsigned NumClauses, 1821 unsigned CollapsedNum, 1822 EmptyShell); 1823 1824 /// Returns special task reduction reference expression. 1825 Expr *getTaskReductionRefExpr() { return TaskRedRef; } 1826 const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } 1827 1828 /// Return true if current directive has inner cancel directive. 1829 bool hasCancel() const { return HasCancel; } 1830 1831 static bool classof(const Stmt *T) { 1832 return T->getStmtClass() == OMPParallelForDirectiveClass; 1833 } 1834 }; 1835 1836 /// This represents '#pragma omp parallel for simd' directive. 1837 /// 1838 /// \code 1839 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d) 1840 /// \endcode 1841 /// In this example directive '#pragma omp parallel for simd' has clauses 1842 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j' 1843 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and 1844 /// 'd'. 1845 /// 1846 class OMPParallelForSimdDirective : public OMPLoopDirective { 1847 friend class ASTStmtReader; 1848 /// Build directive with the given start and end location. 1849 /// 1850 /// \param StartLoc Starting location of the directive kind. 1851 /// \param EndLoc Ending location of the directive. 1852 /// \param CollapsedNum Number of collapsed nested loops. 1853 /// \param NumClauses Number of clauses. 1854 /// 1855 OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1856 unsigned CollapsedNum, unsigned NumClauses) 1857 : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass, 1858 llvm::omp::OMPD_parallel_for_simd, StartLoc, EndLoc, 1859 CollapsedNum, NumClauses) {} 1860 1861 /// Build an empty directive. 1862 /// 1863 /// \param CollapsedNum Number of collapsed nested loops. 1864 /// \param NumClauses Number of clauses. 1865 /// 1866 explicit OMPParallelForSimdDirective(unsigned CollapsedNum, 1867 unsigned NumClauses) 1868 : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass, 1869 llvm::omp::OMPD_parallel_for_simd, SourceLocation(), 1870 SourceLocation(), CollapsedNum, NumClauses) {} 1871 1872 public: 1873 /// Creates directive with a list of \a Clauses. 1874 /// 1875 /// \param C AST context. 1876 /// \param StartLoc Starting location of the directive kind. 1877 /// \param EndLoc Ending Location of the directive. 1878 /// \param CollapsedNum Number of collapsed loops. 1879 /// \param Clauses List of clauses. 1880 /// \param AssociatedStmt Statement, associated with the directive. 1881 /// \param Exprs Helper expressions for CodeGen. 1882 /// 1883 static OMPParallelForSimdDirective * 1884 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1885 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 1886 Stmt *AssociatedStmt, const HelperExprs &Exprs); 1887 1888 /// Creates an empty directive with the place 1889 /// for \a NumClauses clauses. 1890 /// 1891 /// \param C AST context. 1892 /// \param CollapsedNum Number of collapsed nested loops. 1893 /// \param NumClauses Number of clauses. 1894 /// 1895 static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C, 1896 unsigned NumClauses, 1897 unsigned CollapsedNum, 1898 EmptyShell); 1899 1900 static bool classof(const Stmt *T) { 1901 return T->getStmtClass() == OMPParallelForSimdDirectiveClass; 1902 } 1903 }; 1904 1905 /// This represents '#pragma omp parallel master' directive. 1906 /// 1907 /// \code 1908 /// #pragma omp parallel master private(a,b) 1909 /// \endcode 1910 /// In this example directive '#pragma omp parallel master' has clauses 1911 /// 'private' with the variables 'a' and 'b' 1912 /// 1913 class OMPParallelMasterDirective : public OMPExecutableDirective { 1914 friend class ASTStmtReader; 1915 1916 /// Special reference expression for handling task reduction. Used to store 1917 /// the taskgroup descriptor returned by the runtime functions. 1918 Expr *TaskRedRef = nullptr; 1919 1920 OMPParallelMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1921 unsigned NumClauses) 1922 : OMPExecutableDirective(this, OMPParallelMasterDirectiveClass, 1923 llvm::omp::OMPD_parallel_master, StartLoc, 1924 EndLoc, NumClauses, 1) {} 1925 1926 explicit OMPParallelMasterDirective(unsigned NumClauses) 1927 : OMPExecutableDirective(this, OMPParallelMasterDirectiveClass, 1928 llvm::omp::OMPD_parallel_master, 1929 SourceLocation(), SourceLocation(), NumClauses, 1930 1) {} 1931 1932 /// Sets special task reduction descriptor. 1933 void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } 1934 1935 public: 1936 /// Creates directive with a list of \a Clauses. 1937 /// 1938 /// \param C AST context. 1939 /// \param StartLoc Starting location of the directive kind. 1940 /// \param EndLoc Ending Location of the directive. 1941 /// \param Clauses List of clauses. 1942 /// \param AssociatedStmt Statement, associated with the directive. 1943 /// \param TaskRedRef Task reduction special reference expression to handle 1944 /// taskgroup descriptor. 1945 /// 1946 static OMPParallelMasterDirective * 1947 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 1948 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef); 1949 1950 /// Creates an empty directive with the place for \a NumClauses 1951 /// clauses. 1952 /// 1953 /// \param C AST context. 1954 /// \param NumClauses Number of clauses. 1955 /// 1956 static OMPParallelMasterDirective * 1957 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 1958 1959 /// Returns special task reduction reference expression. 1960 Expr *getTaskReductionRefExpr() { return TaskRedRef; } 1961 const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } 1962 1963 static bool classof(const Stmt *T) { 1964 return T->getStmtClass() == OMPParallelMasterDirectiveClass; 1965 } 1966 }; 1967 1968 /// This represents '#pragma omp parallel sections' directive. 1969 /// 1970 /// \code 1971 /// #pragma omp parallel sections private(a,b) reduction(+:c,d) 1972 /// \endcode 1973 /// In this example directive '#pragma omp parallel sections' has clauses 1974 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' 1975 /// and variables 'c' and 'd'. 1976 /// 1977 class OMPParallelSectionsDirective : public OMPExecutableDirective { 1978 friend class ASTStmtReader; 1979 1980 /// Special reference expression for handling task reduction. Used to store 1981 /// the taskgroup descriptor returned by the runtime functions. 1982 Expr *TaskRedRef = nullptr; 1983 /// true if current directive has inner cancel directive. 1984 bool HasCancel; 1985 1986 /// Build directive with the given start and end location. 1987 /// 1988 /// \param StartLoc Starting location of the directive kind. 1989 /// \param EndLoc Ending location of the directive. 1990 /// \param NumClauses Number of clauses. 1991 /// 1992 OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc, 1993 unsigned NumClauses) 1994 : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass, 1995 llvm::omp::OMPD_parallel_sections, StartLoc, 1996 EndLoc, NumClauses, 1), 1997 HasCancel(false) {} 1998 1999 /// Build an empty directive. 2000 /// 2001 /// \param NumClauses Number of clauses. 2002 /// 2003 explicit OMPParallelSectionsDirective(unsigned NumClauses) 2004 : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass, 2005 llvm::omp::OMPD_parallel_sections, 2006 SourceLocation(), SourceLocation(), NumClauses, 2007 1), 2008 HasCancel(false) {} 2009 2010 /// Sets special task reduction descriptor. 2011 void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } 2012 2013 /// Set cancel state. 2014 void setHasCancel(bool Has) { HasCancel = Has; } 2015 2016 public: 2017 /// Creates directive with a list of \a Clauses. 2018 /// 2019 /// \param C AST context. 2020 /// \param StartLoc Starting location of the directive kind. 2021 /// \param EndLoc Ending Location of the directive. 2022 /// \param Clauses List of clauses. 2023 /// \param AssociatedStmt Statement, associated with the directive. 2024 /// \param TaskRedRef Task reduction special reference expression to handle 2025 /// taskgroup descriptor. 2026 /// \param HasCancel true if current directive has inner cancel directive. 2027 /// 2028 static OMPParallelSectionsDirective * 2029 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2030 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 2031 bool HasCancel); 2032 2033 /// Creates an empty directive with the place for \a NumClauses 2034 /// clauses. 2035 /// 2036 /// \param C AST context. 2037 /// \param NumClauses Number of clauses. 2038 /// 2039 static OMPParallelSectionsDirective * 2040 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 2041 2042 /// Returns special task reduction reference expression. 2043 Expr *getTaskReductionRefExpr() { return TaskRedRef; } 2044 const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } 2045 2046 /// Return true if current directive has inner cancel directive. 2047 bool hasCancel() const { return HasCancel; } 2048 2049 static bool classof(const Stmt *T) { 2050 return T->getStmtClass() == OMPParallelSectionsDirectiveClass; 2051 } 2052 }; 2053 2054 /// This represents '#pragma omp task' directive. 2055 /// 2056 /// \code 2057 /// #pragma omp task private(a,b) final(d) 2058 /// \endcode 2059 /// In this example directive '#pragma omp task' has clauses 'private' with the 2060 /// variables 'a' and 'b' and 'final' with condition 'd'. 2061 /// 2062 class OMPTaskDirective : public OMPExecutableDirective { 2063 friend class ASTStmtReader; 2064 /// true if this directive has inner cancel directive. 2065 bool HasCancel; 2066 2067 /// Build directive with the given start and end location. 2068 /// 2069 /// \param StartLoc Starting location of the directive kind. 2070 /// \param EndLoc Ending location of the directive. 2071 /// \param NumClauses Number of clauses. 2072 /// 2073 OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2074 unsigned NumClauses) 2075 : OMPExecutableDirective(this, OMPTaskDirectiveClass, 2076 llvm::omp::OMPD_task, StartLoc, EndLoc, 2077 NumClauses, 1), 2078 HasCancel(false) {} 2079 2080 /// Build an empty directive. 2081 /// 2082 /// \param NumClauses Number of clauses. 2083 /// 2084 explicit OMPTaskDirective(unsigned NumClauses) 2085 : OMPExecutableDirective(this, OMPTaskDirectiveClass, 2086 llvm::omp::OMPD_task, SourceLocation(), 2087 SourceLocation(), NumClauses, 1), 2088 HasCancel(false) {} 2089 2090 /// Set cancel state. 2091 void setHasCancel(bool Has) { HasCancel = Has; } 2092 2093 public: 2094 /// Creates directive with a list of \a Clauses. 2095 /// 2096 /// \param C AST context. 2097 /// \param StartLoc Starting location of the directive kind. 2098 /// \param EndLoc Ending Location of the directive. 2099 /// \param Clauses List of clauses. 2100 /// \param AssociatedStmt Statement, associated with the directive. 2101 /// \param HasCancel true, if current directive has inner cancel directive. 2102 /// 2103 static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc, 2104 SourceLocation EndLoc, 2105 ArrayRef<OMPClause *> Clauses, 2106 Stmt *AssociatedStmt, bool HasCancel); 2107 2108 /// Creates an empty directive with the place for \a NumClauses 2109 /// clauses. 2110 /// 2111 /// \param C AST context. 2112 /// \param NumClauses Number of clauses. 2113 /// 2114 static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 2115 EmptyShell); 2116 2117 /// Return true if current directive has inner cancel directive. 2118 bool hasCancel() const { return HasCancel; } 2119 2120 static bool classof(const Stmt *T) { 2121 return T->getStmtClass() == OMPTaskDirectiveClass; 2122 } 2123 }; 2124 2125 /// This represents '#pragma omp taskyield' directive. 2126 /// 2127 /// \code 2128 /// #pragma omp taskyield 2129 /// \endcode 2130 /// 2131 class OMPTaskyieldDirective : public OMPExecutableDirective { 2132 friend class ASTStmtReader; 2133 /// Build directive with the given start and end location. 2134 /// 2135 /// \param StartLoc Starting location of the directive kind. 2136 /// \param EndLoc Ending location of the directive. 2137 /// 2138 OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2139 : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, 2140 llvm::omp::OMPD_taskyield, StartLoc, EndLoc, 0, 2141 0) {} 2142 2143 /// Build an empty directive. 2144 /// 2145 explicit OMPTaskyieldDirective() 2146 : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, 2147 llvm::omp::OMPD_taskyield, SourceLocation(), 2148 SourceLocation(), 0, 0) {} 2149 2150 public: 2151 /// Creates directive. 2152 /// 2153 /// \param C AST context. 2154 /// \param StartLoc Starting location of the directive kind. 2155 /// \param EndLoc Ending Location of the directive. 2156 /// 2157 static OMPTaskyieldDirective * 2158 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); 2159 2160 /// Creates an empty directive. 2161 /// 2162 /// \param C AST context. 2163 /// 2164 static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell); 2165 2166 static bool classof(const Stmt *T) { 2167 return T->getStmtClass() == OMPTaskyieldDirectiveClass; 2168 } 2169 }; 2170 2171 /// This represents '#pragma omp barrier' directive. 2172 /// 2173 /// \code 2174 /// #pragma omp barrier 2175 /// \endcode 2176 /// 2177 class OMPBarrierDirective : public OMPExecutableDirective { 2178 friend class ASTStmtReader; 2179 /// Build directive with the given start and end location. 2180 /// 2181 /// \param StartLoc Starting location of the directive kind. 2182 /// \param EndLoc Ending location of the directive. 2183 /// 2184 OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2185 : OMPExecutableDirective(this, OMPBarrierDirectiveClass, 2186 llvm::omp::OMPD_barrier, StartLoc, EndLoc, 0, 2187 0) {} 2188 2189 /// Build an empty directive. 2190 /// 2191 explicit OMPBarrierDirective() 2192 : OMPExecutableDirective(this, OMPBarrierDirectiveClass, 2193 llvm::omp::OMPD_barrier, SourceLocation(), 2194 SourceLocation(), 0, 0) {} 2195 2196 public: 2197 /// Creates directive. 2198 /// 2199 /// \param C AST context. 2200 /// \param StartLoc Starting location of the directive kind. 2201 /// \param EndLoc Ending Location of the directive. 2202 /// 2203 static OMPBarrierDirective * 2204 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); 2205 2206 /// Creates an empty directive. 2207 /// 2208 /// \param C AST context. 2209 /// 2210 static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell); 2211 2212 static bool classof(const Stmt *T) { 2213 return T->getStmtClass() == OMPBarrierDirectiveClass; 2214 } 2215 }; 2216 2217 /// This represents '#pragma omp taskwait' directive. 2218 /// 2219 /// \code 2220 /// #pragma omp taskwait 2221 /// \endcode 2222 /// 2223 class OMPTaskwaitDirective : public OMPExecutableDirective { 2224 friend class ASTStmtReader; 2225 /// Build directive with the given start and end location. 2226 /// 2227 /// \param StartLoc Starting location of the directive kind. 2228 /// \param EndLoc Ending location of the directive. 2229 /// 2230 OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2231 : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, 2232 llvm::omp::OMPD_taskwait, StartLoc, EndLoc, 0, 2233 0) {} 2234 2235 /// Build an empty directive. 2236 /// 2237 explicit OMPTaskwaitDirective() 2238 : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, 2239 llvm::omp::OMPD_taskwait, SourceLocation(), 2240 SourceLocation(), 0, 0) {} 2241 2242 public: 2243 /// Creates directive. 2244 /// 2245 /// \param C AST context. 2246 /// \param StartLoc Starting location of the directive kind. 2247 /// \param EndLoc Ending Location of the directive. 2248 /// 2249 static OMPTaskwaitDirective * 2250 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); 2251 2252 /// Creates an empty directive. 2253 /// 2254 /// \param C AST context. 2255 /// 2256 static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell); 2257 2258 static bool classof(const Stmt *T) { 2259 return T->getStmtClass() == OMPTaskwaitDirectiveClass; 2260 } 2261 }; 2262 2263 /// This represents '#pragma omp taskgroup' directive. 2264 /// 2265 /// \code 2266 /// #pragma omp taskgroup 2267 /// \endcode 2268 /// 2269 class OMPTaskgroupDirective : public OMPExecutableDirective { 2270 friend class ASTStmtReader; 2271 /// Build directive with the given start and end location. 2272 /// 2273 /// \param StartLoc Starting location of the directive kind. 2274 /// \param EndLoc Ending location of the directive. 2275 /// \param NumClauses Number of clauses. 2276 /// 2277 OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2278 unsigned NumClauses) 2279 : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, 2280 llvm::omp::OMPD_taskgroup, StartLoc, EndLoc, 2281 NumClauses, 2) {} 2282 2283 /// Build an empty directive. 2284 /// \param NumClauses Number of clauses. 2285 /// 2286 explicit OMPTaskgroupDirective(unsigned NumClauses) 2287 : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, 2288 llvm::omp::OMPD_taskgroup, SourceLocation(), 2289 SourceLocation(), NumClauses, 2) {} 2290 2291 /// Sets the task_reduction return variable. 2292 void setReductionRef(Expr *RR) { 2293 *std::next(child_begin(), 1) = RR; 2294 } 2295 2296 public: 2297 /// Creates directive. 2298 /// 2299 /// \param C AST context. 2300 /// \param StartLoc Starting location of the directive kind. 2301 /// \param EndLoc Ending Location of the directive. 2302 /// \param Clauses List of clauses. 2303 /// \param AssociatedStmt Statement, associated with the directive. 2304 /// \param ReductionRef Reference to the task_reduction return variable. 2305 /// 2306 static OMPTaskgroupDirective * 2307 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2308 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, 2309 Expr *ReductionRef); 2310 2311 /// Creates an empty directive. 2312 /// 2313 /// \param C AST context. 2314 /// \param NumClauses Number of clauses. 2315 /// 2316 static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, 2317 unsigned NumClauses, EmptyShell); 2318 2319 2320 /// Returns reference to the task_reduction return variable. 2321 const Expr *getReductionRef() const { 2322 return static_cast<const Expr *>(*std::next(child_begin(), 1)); 2323 } 2324 Expr *getReductionRef() { 2325 return static_cast<Expr *>(*std::next(child_begin(), 1)); 2326 } 2327 2328 static bool classof(const Stmt *T) { 2329 return T->getStmtClass() == OMPTaskgroupDirectiveClass; 2330 } 2331 }; 2332 2333 /// This represents '#pragma omp flush' directive. 2334 /// 2335 /// \code 2336 /// #pragma omp flush(a,b) 2337 /// \endcode 2338 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a' 2339 /// and 'b'. 2340 /// 'omp flush' directive does not have clauses but have an optional list of 2341 /// variables to flush. This list of variables is stored within some fake clause 2342 /// FlushClause. 2343 class OMPFlushDirective : public OMPExecutableDirective { 2344 friend class ASTStmtReader; 2345 /// Build directive with the given start and end location. 2346 /// 2347 /// \param StartLoc Starting location of the directive kind. 2348 /// \param EndLoc Ending location of the directive. 2349 /// \param NumClauses Number of clauses. 2350 /// 2351 OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2352 unsigned NumClauses) 2353 : OMPExecutableDirective(this, OMPFlushDirectiveClass, 2354 llvm::omp::OMPD_flush, StartLoc, EndLoc, 2355 NumClauses, 0) {} 2356 2357 /// Build an empty directive. 2358 /// 2359 /// \param NumClauses Number of clauses. 2360 /// 2361 explicit OMPFlushDirective(unsigned NumClauses) 2362 : OMPExecutableDirective(this, OMPFlushDirectiveClass, 2363 llvm::omp::OMPD_flush, SourceLocation(), 2364 SourceLocation(), NumClauses, 0) {} 2365 2366 public: 2367 /// Creates directive with a list of \a Clauses. 2368 /// 2369 /// \param C AST context. 2370 /// \param StartLoc Starting location of the directive kind. 2371 /// \param EndLoc Ending Location of the directive. 2372 /// \param Clauses List of clauses (only single OMPFlushClause clause is 2373 /// allowed). 2374 /// 2375 static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc, 2376 SourceLocation EndLoc, 2377 ArrayRef<OMPClause *> Clauses); 2378 2379 /// Creates an empty directive with the place for \a NumClauses 2380 /// clauses. 2381 /// 2382 /// \param C AST context. 2383 /// \param NumClauses Number of clauses. 2384 /// 2385 static OMPFlushDirective *CreateEmpty(const ASTContext &C, 2386 unsigned NumClauses, EmptyShell); 2387 2388 static bool classof(const Stmt *T) { 2389 return T->getStmtClass() == OMPFlushDirectiveClass; 2390 } 2391 }; 2392 2393 /// This represents '#pragma omp depobj' directive. 2394 /// 2395 /// \code 2396 /// #pragma omp depobj(a) depend(in:x,y) 2397 /// \endcode 2398 /// In this example directive '#pragma omp depobj' initializes a depobj object 2399 /// 'a' with dependence type 'in' and a list with 'x' and 'y' locators. 2400 class OMPDepobjDirective final : public OMPExecutableDirective { 2401 friend class ASTStmtReader; 2402 2403 /// Build directive with the given start and end location. 2404 /// 2405 /// \param StartLoc Starting location of the directive kind. 2406 /// \param EndLoc Ending location of the directive. 2407 /// \param NumClauses Number of clauses. 2408 /// 2409 OMPDepobjDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2410 unsigned NumClauses) 2411 : OMPExecutableDirective(this, OMPDepobjDirectiveClass, 2412 llvm::omp::OMPD_depobj, StartLoc, EndLoc, 2413 NumClauses, 0) {} 2414 2415 /// Build an empty directive. 2416 /// 2417 /// \param NumClauses Number of clauses. 2418 /// 2419 explicit OMPDepobjDirective(unsigned NumClauses) 2420 : OMPExecutableDirective(this, OMPDepobjDirectiveClass, 2421 llvm::omp::OMPD_depobj, SourceLocation(), 2422 SourceLocation(), NumClauses, 0) {} 2423 2424 public: 2425 /// Creates directive with a list of \a Clauses. 2426 /// 2427 /// \param C AST context. 2428 /// \param StartLoc Starting location of the directive kind. 2429 /// \param EndLoc Ending Location of the directive. 2430 /// \param Clauses List of clauses. 2431 /// 2432 static OMPDepobjDirective *Create(const ASTContext &C, 2433 SourceLocation StartLoc, 2434 SourceLocation EndLoc, 2435 ArrayRef<OMPClause *> Clauses); 2436 2437 /// Creates an empty directive with the place for \a NumClauses 2438 /// clauses. 2439 /// 2440 /// \param C AST context. 2441 /// \param NumClauses Number of clauses. 2442 /// 2443 static OMPDepobjDirective *CreateEmpty(const ASTContext &C, 2444 unsigned NumClauses, EmptyShell); 2445 2446 static bool classof(const Stmt *T) { 2447 return T->getStmtClass() == OMPDepobjDirectiveClass; 2448 } 2449 }; 2450 2451 /// This represents '#pragma omp ordered' directive. 2452 /// 2453 /// \code 2454 /// #pragma omp ordered 2455 /// \endcode 2456 /// 2457 class OMPOrderedDirective : public OMPExecutableDirective { 2458 friend class ASTStmtReader; 2459 /// Build directive with the given start and end location. 2460 /// 2461 /// \param StartLoc Starting location of the directive kind. 2462 /// \param EndLoc Ending location of the directive. 2463 /// \param NumClauses Number of clauses. 2464 /// 2465 OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2466 unsigned NumClauses) 2467 : OMPExecutableDirective(this, OMPOrderedDirectiveClass, 2468 llvm::omp::OMPD_ordered, StartLoc, EndLoc, 2469 NumClauses, 1) {} 2470 2471 /// Build an empty directive. 2472 /// 2473 /// \param NumClauses Number of clauses. 2474 /// 2475 explicit OMPOrderedDirective(unsigned NumClauses) 2476 : OMPExecutableDirective(this, OMPOrderedDirectiveClass, 2477 llvm::omp::OMPD_ordered, SourceLocation(), 2478 SourceLocation(), NumClauses, 1) {} 2479 2480 public: 2481 /// Creates directive. 2482 /// 2483 /// \param C AST context. 2484 /// \param StartLoc Starting location of the directive kind. 2485 /// \param EndLoc Ending Location of the directive. 2486 /// \param Clauses List of clauses. 2487 /// \param AssociatedStmt Statement, associated with the directive. 2488 /// 2489 static OMPOrderedDirective * 2490 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2491 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 2492 2493 /// Creates an empty directive. 2494 /// 2495 /// \param C AST context. 2496 /// \param NumClauses Number of clauses. 2497 /// 2498 static OMPOrderedDirective *CreateEmpty(const ASTContext &C, 2499 unsigned NumClauses, EmptyShell); 2500 2501 static bool classof(const Stmt *T) { 2502 return T->getStmtClass() == OMPOrderedDirectiveClass; 2503 } 2504 }; 2505 2506 /// This represents '#pragma omp atomic' directive. 2507 /// 2508 /// \code 2509 /// #pragma omp atomic capture 2510 /// \endcode 2511 /// In this example directive '#pragma omp atomic' has clause 'capture'. 2512 /// 2513 class OMPAtomicDirective : public OMPExecutableDirective { 2514 friend class ASTStmtReader; 2515 /// Used for 'atomic update' or 'atomic capture' constructs. They may 2516 /// have atomic expressions of forms 2517 /// \code 2518 /// x = x binop expr; 2519 /// x = expr binop x; 2520 /// \endcode 2521 /// This field is true for the first form of the expression and false for the 2522 /// second. Required for correct codegen of non-associative operations (like 2523 /// << or >>). 2524 bool IsXLHSInRHSPart; 2525 /// Used for 'atomic update' or 'atomic capture' constructs. They may 2526 /// have atomic expressions of forms 2527 /// \code 2528 /// v = x; <update x>; 2529 /// <update x>; v = x; 2530 /// \endcode 2531 /// This field is true for the first(postfix) form of the expression and false 2532 /// otherwise. 2533 bool IsPostfixUpdate; 2534 2535 /// Build directive with the given start and end location. 2536 /// 2537 /// \param StartLoc Starting location of the directive kind. 2538 /// \param EndLoc Ending location of the directive. 2539 /// \param NumClauses Number of clauses. 2540 /// 2541 OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2542 unsigned NumClauses) 2543 : OMPExecutableDirective(this, OMPAtomicDirectiveClass, 2544 llvm::omp::OMPD_atomic, StartLoc, EndLoc, 2545 NumClauses, 5), 2546 IsXLHSInRHSPart(false), IsPostfixUpdate(false) {} 2547 2548 /// Build an empty directive. 2549 /// 2550 /// \param NumClauses Number of clauses. 2551 /// 2552 explicit OMPAtomicDirective(unsigned NumClauses) 2553 : OMPExecutableDirective(this, OMPAtomicDirectiveClass, 2554 llvm::omp::OMPD_atomic, SourceLocation(), 2555 SourceLocation(), NumClauses, 5), 2556 IsXLHSInRHSPart(false), IsPostfixUpdate(false) {} 2557 2558 /// Set 'x' part of the associated expression/statement. 2559 void setX(Expr *X) { *std::next(child_begin()) = X; } 2560 /// Set helper expression of the form 2561 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 2562 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 2563 void setUpdateExpr(Expr *UE) { *std::next(child_begin(), 2) = UE; } 2564 /// Set 'v' part of the associated expression/statement. 2565 void setV(Expr *V) { *std::next(child_begin(), 3) = V; } 2566 /// Set 'expr' part of the associated expression/statement. 2567 void setExpr(Expr *E) { *std::next(child_begin(), 4) = E; } 2568 2569 public: 2570 /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr' 2571 /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for 2572 /// detailed description of 'x', 'v' and 'expr'). 2573 /// 2574 /// \param C AST context. 2575 /// \param StartLoc Starting location of the directive kind. 2576 /// \param EndLoc Ending Location of the directive. 2577 /// \param Clauses List of clauses. 2578 /// \param AssociatedStmt Statement, associated with the directive. 2579 /// \param X 'x' part of the associated expression/statement. 2580 /// \param V 'v' part of the associated expression/statement. 2581 /// \param E 'expr' part of the associated expression/statement. 2582 /// \param UE Helper expression of the form 2583 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 2584 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 2585 /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the 2586 /// second. 2587 /// \param IsPostfixUpdate true if original value of 'x' must be stored in 2588 /// 'v', not an updated one. 2589 static OMPAtomicDirective * 2590 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2591 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V, 2592 Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate); 2593 2594 /// Creates an empty directive with the place for \a NumClauses 2595 /// clauses. 2596 /// 2597 /// \param C AST context. 2598 /// \param NumClauses Number of clauses. 2599 /// 2600 static OMPAtomicDirective *CreateEmpty(const ASTContext &C, 2601 unsigned NumClauses, EmptyShell); 2602 2603 /// Get 'x' part of the associated expression/statement. 2604 Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); } 2605 const Expr *getX() const { 2606 return cast_or_null<Expr>(*std::next(child_begin())); 2607 } 2608 /// Get helper expression of the form 2609 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 2610 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 2611 Expr *getUpdateExpr() { 2612 return cast_or_null<Expr>(*std::next(child_begin(), 2)); 2613 } 2614 const Expr *getUpdateExpr() const { 2615 return cast_or_null<Expr>(*std::next(child_begin(), 2)); 2616 } 2617 /// Return true if helper update expression has form 2618 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form 2619 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 2620 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 2621 /// Return true if 'v' expression must be updated to original value of 2622 /// 'x', false if 'v' must be updated to the new value of 'x'. 2623 bool isPostfixUpdate() const { return IsPostfixUpdate; } 2624 /// Get 'v' part of the associated expression/statement. 2625 Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); } 2626 const Expr *getV() const { 2627 return cast_or_null<Expr>(*std::next(child_begin(), 3)); 2628 } 2629 /// Get 'expr' part of the associated expression/statement. 2630 Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 4)); } 2631 const Expr *getExpr() const { 2632 return cast_or_null<Expr>(*std::next(child_begin(), 4)); 2633 } 2634 2635 static bool classof(const Stmt *T) { 2636 return T->getStmtClass() == OMPAtomicDirectiveClass; 2637 } 2638 }; 2639 2640 /// This represents '#pragma omp target' directive. 2641 /// 2642 /// \code 2643 /// #pragma omp target if(a) 2644 /// \endcode 2645 /// In this example directive '#pragma omp target' has clause 'if' with 2646 /// condition 'a'. 2647 /// 2648 class OMPTargetDirective : public OMPExecutableDirective { 2649 friend class ASTStmtReader; 2650 /// Build directive with the given start and end location. 2651 /// 2652 /// \param StartLoc Starting location of the directive kind. 2653 /// \param EndLoc Ending location of the directive. 2654 /// \param NumClauses Number of clauses. 2655 /// 2656 OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2657 unsigned NumClauses) 2658 : OMPExecutableDirective(this, OMPTargetDirectiveClass, 2659 llvm::omp::OMPD_target, StartLoc, EndLoc, 2660 NumClauses, 1) {} 2661 2662 /// Build an empty directive. 2663 /// 2664 /// \param NumClauses Number of clauses. 2665 /// 2666 explicit OMPTargetDirective(unsigned NumClauses) 2667 : OMPExecutableDirective(this, OMPTargetDirectiveClass, 2668 llvm::omp::OMPD_target, SourceLocation(), 2669 SourceLocation(), NumClauses, 1) {} 2670 2671 public: 2672 /// Creates directive with a list of \a Clauses. 2673 /// 2674 /// \param C AST context. 2675 /// \param StartLoc Starting location of the directive kind. 2676 /// \param EndLoc Ending Location of the directive. 2677 /// \param Clauses List of clauses. 2678 /// \param AssociatedStmt Statement, associated with the directive. 2679 /// 2680 static OMPTargetDirective * 2681 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2682 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 2683 2684 /// Creates an empty directive with the place for \a NumClauses 2685 /// clauses. 2686 /// 2687 /// \param C AST context. 2688 /// \param NumClauses Number of clauses. 2689 /// 2690 static OMPTargetDirective *CreateEmpty(const ASTContext &C, 2691 unsigned NumClauses, EmptyShell); 2692 2693 static bool classof(const Stmt *T) { 2694 return T->getStmtClass() == OMPTargetDirectiveClass; 2695 } 2696 }; 2697 2698 /// This represents '#pragma omp target data' directive. 2699 /// 2700 /// \code 2701 /// #pragma omp target data device(0) if(a) map(b[:]) 2702 /// \endcode 2703 /// In this example directive '#pragma omp target data' has clauses 'device' 2704 /// with the value '0', 'if' with condition 'a' and 'map' with array 2705 /// section 'b[:]'. 2706 /// 2707 class OMPTargetDataDirective : public OMPExecutableDirective { 2708 friend class ASTStmtReader; 2709 /// Build directive with the given start and end location. 2710 /// 2711 /// \param StartLoc Starting location of the directive kind. 2712 /// \param EndLoc Ending Location of the directive. 2713 /// \param NumClauses The number of clauses. 2714 /// 2715 OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2716 unsigned NumClauses) 2717 : OMPExecutableDirective(this, OMPTargetDataDirectiveClass, 2718 llvm::omp::OMPD_target_data, StartLoc, EndLoc, 2719 NumClauses, 1) {} 2720 2721 /// Build an empty directive. 2722 /// 2723 /// \param NumClauses Number of clauses. 2724 /// 2725 explicit OMPTargetDataDirective(unsigned NumClauses) 2726 : OMPExecutableDirective(this, OMPTargetDataDirectiveClass, 2727 llvm::omp::OMPD_target_data, SourceLocation(), 2728 SourceLocation(), NumClauses, 1) {} 2729 2730 public: 2731 /// Creates directive with a list of \a Clauses. 2732 /// 2733 /// \param C AST context. 2734 /// \param StartLoc Starting location of the directive kind. 2735 /// \param EndLoc Ending Location of the directive. 2736 /// \param Clauses List of clauses. 2737 /// \param AssociatedStmt Statement, associated with the directive. 2738 /// 2739 static OMPTargetDataDirective * 2740 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2741 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 2742 2743 /// Creates an empty directive with the place for \a N clauses. 2744 /// 2745 /// \param C AST context. 2746 /// \param N The number of clauses. 2747 /// 2748 static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N, 2749 EmptyShell); 2750 2751 static bool classof(const Stmt *T) { 2752 return T->getStmtClass() == OMPTargetDataDirectiveClass; 2753 } 2754 }; 2755 2756 /// This represents '#pragma omp target enter data' directive. 2757 /// 2758 /// \code 2759 /// #pragma omp target enter data device(0) if(a) map(b[:]) 2760 /// \endcode 2761 /// In this example directive '#pragma omp target enter data' has clauses 2762 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array 2763 /// section 'b[:]'. 2764 /// 2765 class OMPTargetEnterDataDirective : public OMPExecutableDirective { 2766 friend class ASTStmtReader; 2767 /// Build directive with the given start and end location. 2768 /// 2769 /// \param StartLoc Starting location of the directive kind. 2770 /// \param EndLoc Ending Location of the directive. 2771 /// \param NumClauses The number of clauses. 2772 /// 2773 OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2774 unsigned NumClauses) 2775 : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass, 2776 llvm::omp::OMPD_target_enter_data, StartLoc, 2777 EndLoc, NumClauses, /*NumChildren=*/1) {} 2778 2779 /// Build an empty directive. 2780 /// 2781 /// \param NumClauses Number of clauses. 2782 /// 2783 explicit OMPTargetEnterDataDirective(unsigned NumClauses) 2784 : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass, 2785 llvm::omp::OMPD_target_enter_data, 2786 SourceLocation(), SourceLocation(), NumClauses, 2787 /*NumChildren=*/1) {} 2788 2789 public: 2790 /// Creates directive with a list of \a Clauses. 2791 /// 2792 /// \param C AST context. 2793 /// \param StartLoc Starting location of the directive kind. 2794 /// \param EndLoc Ending Location of the directive. 2795 /// \param Clauses List of clauses. 2796 /// \param AssociatedStmt Statement, associated with the directive. 2797 /// 2798 static OMPTargetEnterDataDirective * 2799 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2800 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 2801 2802 /// Creates an empty directive with the place for \a N clauses. 2803 /// 2804 /// \param C AST context. 2805 /// \param N The number of clauses. 2806 /// 2807 static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C, 2808 unsigned N, EmptyShell); 2809 2810 static bool classof(const Stmt *T) { 2811 return T->getStmtClass() == OMPTargetEnterDataDirectiveClass; 2812 } 2813 }; 2814 2815 /// This represents '#pragma omp target exit data' directive. 2816 /// 2817 /// \code 2818 /// #pragma omp target exit data device(0) if(a) map(b[:]) 2819 /// \endcode 2820 /// In this example directive '#pragma omp target exit data' has clauses 2821 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array 2822 /// section 'b[:]'. 2823 /// 2824 class OMPTargetExitDataDirective : public OMPExecutableDirective { 2825 friend class ASTStmtReader; 2826 /// Build directive with the given start and end location. 2827 /// 2828 /// \param StartLoc Starting location of the directive kind. 2829 /// \param EndLoc Ending Location of the directive. 2830 /// \param NumClauses The number of clauses. 2831 /// 2832 OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2833 unsigned NumClauses) 2834 : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass, 2835 llvm::omp::OMPD_target_exit_data, StartLoc, 2836 EndLoc, NumClauses, /*NumChildren=*/1) {} 2837 2838 /// Build an empty directive. 2839 /// 2840 /// \param NumClauses Number of clauses. 2841 /// 2842 explicit OMPTargetExitDataDirective(unsigned NumClauses) 2843 : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass, 2844 llvm::omp::OMPD_target_exit_data, 2845 SourceLocation(), SourceLocation(), NumClauses, 2846 /*NumChildren=*/1) {} 2847 2848 public: 2849 /// Creates directive with a list of \a Clauses. 2850 /// 2851 /// \param C AST context. 2852 /// \param StartLoc Starting location of the directive kind. 2853 /// \param EndLoc Ending Location of the directive. 2854 /// \param Clauses List of clauses. 2855 /// \param AssociatedStmt Statement, associated with the directive. 2856 /// 2857 static OMPTargetExitDataDirective * 2858 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2859 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 2860 2861 /// Creates an empty directive with the place for \a N clauses. 2862 /// 2863 /// \param C AST context. 2864 /// \param N The number of clauses. 2865 /// 2866 static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C, 2867 unsigned N, EmptyShell); 2868 2869 static bool classof(const Stmt *T) { 2870 return T->getStmtClass() == OMPTargetExitDataDirectiveClass; 2871 } 2872 }; 2873 2874 /// This represents '#pragma omp target parallel' directive. 2875 /// 2876 /// \code 2877 /// #pragma omp target parallel if(a) 2878 /// \endcode 2879 /// In this example directive '#pragma omp target parallel' has clause 'if' with 2880 /// condition 'a'. 2881 /// 2882 class OMPTargetParallelDirective : public OMPExecutableDirective { 2883 friend class ASTStmtReader; 2884 /// Special reference expression for handling task reduction. Used to store 2885 /// the taskgroup descriptor returned by the runtime functions. 2886 Expr *TaskRedRef = nullptr; 2887 /// true if the construct has inner cancel directive. 2888 bool HasCancel = false; 2889 2890 /// Build directive with the given start and end location. 2891 /// 2892 /// \param StartLoc Starting location of the directive kind. 2893 /// \param EndLoc Ending location of the directive. 2894 /// \param NumClauses Number of clauses. 2895 /// 2896 OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2897 unsigned NumClauses) 2898 : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass, 2899 llvm::omp::OMPD_target_parallel, StartLoc, 2900 EndLoc, NumClauses, /*NumChildren=*/1) {} 2901 2902 /// Build an empty directive. 2903 /// 2904 /// \param NumClauses Number of clauses. 2905 /// 2906 explicit OMPTargetParallelDirective(unsigned NumClauses) 2907 : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass, 2908 llvm::omp::OMPD_target_parallel, 2909 SourceLocation(), SourceLocation(), NumClauses, 2910 /*NumChildren=*/1) {} 2911 2912 /// Sets special task reduction descriptor. 2913 void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } 2914 /// Set cancel state. 2915 void setHasCancel(bool Has) { HasCancel = Has; } 2916 2917 public: 2918 /// Creates directive with a list of \a Clauses. 2919 /// 2920 /// \param C AST context. 2921 /// \param StartLoc Starting location of the directive kind. 2922 /// \param EndLoc Ending Location of the directive. 2923 /// \param Clauses List of clauses. 2924 /// \param AssociatedStmt Statement, associated with the directive. 2925 /// \param TaskRedRef Task reduction special reference expression to handle 2926 /// taskgroup descriptor. 2927 /// \param HasCancel true if this directive has inner cancel directive. 2928 /// 2929 static OMPTargetParallelDirective * 2930 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 2931 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 2932 bool HasCancel); 2933 2934 /// Creates an empty directive with the place for \a NumClauses 2935 /// clauses. 2936 /// 2937 /// \param C AST context. 2938 /// \param NumClauses Number of clauses. 2939 /// 2940 static OMPTargetParallelDirective * 2941 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 2942 2943 /// Returns special task reduction reference expression. 2944 Expr *getTaskReductionRefExpr() { return TaskRedRef; } 2945 const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } 2946 2947 /// Return true if current directive has inner cancel directive. 2948 bool hasCancel() const { return HasCancel; } 2949 2950 static bool classof(const Stmt *T) { 2951 return T->getStmtClass() == OMPTargetParallelDirectiveClass; 2952 } 2953 }; 2954 2955 /// This represents '#pragma omp target parallel for' directive. 2956 /// 2957 /// \code 2958 /// #pragma omp target parallel for private(a,b) reduction(+:c,d) 2959 /// \endcode 2960 /// In this example directive '#pragma omp target parallel for' has clauses 2961 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' 2962 /// and variables 'c' and 'd'. 2963 /// 2964 class OMPTargetParallelForDirective : public OMPLoopDirective { 2965 friend class ASTStmtReader; 2966 2967 /// Special reference expression for handling task reduction. Used to store 2968 /// the taskgroup descriptor returned by the runtime functions. 2969 Expr *TaskRedRef = nullptr; 2970 /// true if current region has inner cancel directive. 2971 bool HasCancel; 2972 2973 /// Build directive with the given start and end location. 2974 /// 2975 /// \param StartLoc Starting location of the directive kind. 2976 /// \param EndLoc Ending location of the directive. 2977 /// \param CollapsedNum Number of collapsed nested loops. 2978 /// \param NumClauses Number of clauses. 2979 /// 2980 OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 2981 unsigned CollapsedNum, unsigned NumClauses) 2982 : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass, 2983 llvm::omp::OMPD_target_parallel_for, StartLoc, EndLoc, 2984 CollapsedNum, NumClauses), 2985 HasCancel(false) {} 2986 2987 /// Build an empty directive. 2988 /// 2989 /// \param CollapsedNum Number of collapsed nested loops. 2990 /// \param NumClauses Number of clauses. 2991 /// 2992 explicit OMPTargetParallelForDirective(unsigned CollapsedNum, 2993 unsigned NumClauses) 2994 : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass, 2995 llvm::omp::OMPD_target_parallel_for, SourceLocation(), 2996 SourceLocation(), CollapsedNum, NumClauses), 2997 HasCancel(false) {} 2998 2999 /// Sets special task reduction descriptor. 3000 void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } 3001 3002 /// Set cancel state. 3003 void setHasCancel(bool Has) { HasCancel = Has; } 3004 3005 public: 3006 /// Creates directive with a list of \a Clauses. 3007 /// 3008 /// \param C AST context. 3009 /// \param StartLoc Starting location of the directive kind. 3010 /// \param EndLoc Ending Location of the directive. 3011 /// \param CollapsedNum Number of collapsed loops. 3012 /// \param Clauses List of clauses. 3013 /// \param AssociatedStmt Statement, associated with the directive. 3014 /// \param Exprs Helper expressions for CodeGen. 3015 /// \param TaskRedRef Task reduction special reference expression to handle 3016 /// taskgroup descriptor. 3017 /// \param HasCancel true if current directive has inner cancel directive. 3018 /// 3019 static OMPTargetParallelForDirective * 3020 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3021 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3022 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 3023 bool HasCancel); 3024 3025 /// Creates an empty directive with the place 3026 /// for \a NumClauses clauses. 3027 /// 3028 /// \param C AST context. 3029 /// \param CollapsedNum Number of collapsed nested loops. 3030 /// \param NumClauses Number of clauses. 3031 /// 3032 static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C, 3033 unsigned NumClauses, 3034 unsigned CollapsedNum, 3035 EmptyShell); 3036 3037 /// Returns special task reduction reference expression. 3038 Expr *getTaskReductionRefExpr() { return TaskRedRef; } 3039 const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } 3040 3041 /// Return true if current directive has inner cancel directive. 3042 bool hasCancel() const { return HasCancel; } 3043 3044 static bool classof(const Stmt *T) { 3045 return T->getStmtClass() == OMPTargetParallelForDirectiveClass; 3046 } 3047 }; 3048 3049 /// This represents '#pragma omp teams' directive. 3050 /// 3051 /// \code 3052 /// #pragma omp teams if(a) 3053 /// \endcode 3054 /// In this example directive '#pragma omp teams' has clause 'if' with 3055 /// condition 'a'. 3056 /// 3057 class OMPTeamsDirective : public OMPExecutableDirective { 3058 friend class ASTStmtReader; 3059 /// Build directive with the given start and end location. 3060 /// 3061 /// \param StartLoc Starting location of the directive kind. 3062 /// \param EndLoc Ending location of the directive. 3063 /// \param NumClauses Number of clauses. 3064 /// 3065 OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3066 unsigned NumClauses) 3067 : OMPExecutableDirective(this, OMPTeamsDirectiveClass, 3068 llvm::omp::OMPD_teams, StartLoc, EndLoc, 3069 NumClauses, 1) {} 3070 3071 /// Build an empty directive. 3072 /// 3073 /// \param NumClauses Number of clauses. 3074 /// 3075 explicit OMPTeamsDirective(unsigned NumClauses) 3076 : OMPExecutableDirective(this, OMPTeamsDirectiveClass, 3077 llvm::omp::OMPD_teams, SourceLocation(), 3078 SourceLocation(), NumClauses, 1) {} 3079 3080 public: 3081 /// Creates directive with a list of \a Clauses. 3082 /// 3083 /// \param C AST context. 3084 /// \param StartLoc Starting location of the directive kind. 3085 /// \param EndLoc Ending Location of the directive. 3086 /// \param Clauses List of clauses. 3087 /// \param AssociatedStmt Statement, associated with the directive. 3088 /// 3089 static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc, 3090 SourceLocation EndLoc, 3091 ArrayRef<OMPClause *> Clauses, 3092 Stmt *AssociatedStmt); 3093 3094 /// Creates an empty directive with the place for \a NumClauses 3095 /// clauses. 3096 /// 3097 /// \param C AST context. 3098 /// \param NumClauses Number of clauses. 3099 /// 3100 static OMPTeamsDirective *CreateEmpty(const ASTContext &C, 3101 unsigned NumClauses, EmptyShell); 3102 3103 static bool classof(const Stmt *T) { 3104 return T->getStmtClass() == OMPTeamsDirectiveClass; 3105 } 3106 }; 3107 3108 /// This represents '#pragma omp cancellation point' directive. 3109 /// 3110 /// \code 3111 /// #pragma omp cancellation point for 3112 /// \endcode 3113 /// 3114 /// In this example a cancellation point is created for innermost 'for' region. 3115 class OMPCancellationPointDirective : public OMPExecutableDirective { 3116 friend class ASTStmtReader; 3117 OpenMPDirectiveKind CancelRegion; 3118 /// Build directive with the given start and end location. 3119 /// 3120 /// \param StartLoc Starting location of the directive kind. 3121 /// \param EndLoc Ending location of the directive. 3122 /// 3123 OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3124 : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass, 3125 llvm::omp::OMPD_cancellation_point, StartLoc, 3126 EndLoc, 0, 0), 3127 CancelRegion(llvm::omp::OMPD_unknown) {} 3128 3129 /// Build an empty directive. 3130 /// 3131 explicit OMPCancellationPointDirective() 3132 : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass, 3133 llvm::omp::OMPD_cancellation_point, 3134 SourceLocation(), SourceLocation(), 0, 0), 3135 CancelRegion(llvm::omp::OMPD_unknown) {} 3136 3137 /// Set cancel region for current cancellation point. 3138 /// \param CR Cancellation region. 3139 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } 3140 3141 public: 3142 /// Creates directive. 3143 /// 3144 /// \param C AST context. 3145 /// \param StartLoc Starting location of the directive kind. 3146 /// \param EndLoc Ending Location of the directive. 3147 /// 3148 static OMPCancellationPointDirective * 3149 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3150 OpenMPDirectiveKind CancelRegion); 3151 3152 /// Creates an empty directive. 3153 /// 3154 /// \param C AST context. 3155 /// 3156 static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C, 3157 EmptyShell); 3158 3159 /// Get cancellation region for the current cancellation point. 3160 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } 3161 3162 static bool classof(const Stmt *T) { 3163 return T->getStmtClass() == OMPCancellationPointDirectiveClass; 3164 } 3165 }; 3166 3167 /// This represents '#pragma omp cancel' directive. 3168 /// 3169 /// \code 3170 /// #pragma omp cancel for 3171 /// \endcode 3172 /// 3173 /// In this example a cancel is created for innermost 'for' region. 3174 class OMPCancelDirective : public OMPExecutableDirective { 3175 friend class ASTStmtReader; 3176 OpenMPDirectiveKind CancelRegion; 3177 /// Build directive with the given start and end location. 3178 /// 3179 /// \param StartLoc Starting location of the directive kind. 3180 /// \param EndLoc Ending location of the directive. 3181 /// \param NumClauses Number of clauses. 3182 /// 3183 OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3184 unsigned NumClauses) 3185 : OMPExecutableDirective(this, OMPCancelDirectiveClass, 3186 llvm::omp::OMPD_cancel, StartLoc, EndLoc, 3187 NumClauses, 0), 3188 CancelRegion(llvm::omp::OMPD_unknown) {} 3189 3190 /// Build an empty directive. 3191 /// 3192 /// \param NumClauses Number of clauses. 3193 explicit OMPCancelDirective(unsigned NumClauses) 3194 : OMPExecutableDirective(this, OMPCancelDirectiveClass, 3195 llvm::omp::OMPD_cancel, SourceLocation(), 3196 SourceLocation(), NumClauses, 0), 3197 CancelRegion(llvm::omp::OMPD_unknown) {} 3198 3199 /// Set cancel region for current cancellation point. 3200 /// \param CR Cancellation region. 3201 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } 3202 3203 public: 3204 /// Creates directive. 3205 /// 3206 /// \param C AST context. 3207 /// \param StartLoc Starting location of the directive kind. 3208 /// \param EndLoc Ending Location of the directive. 3209 /// \param Clauses List of clauses. 3210 /// 3211 static OMPCancelDirective * 3212 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3213 ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion); 3214 3215 /// Creates an empty directive. 3216 /// 3217 /// \param C AST context. 3218 /// \param NumClauses Number of clauses. 3219 /// 3220 static OMPCancelDirective *CreateEmpty(const ASTContext &C, 3221 unsigned NumClauses, EmptyShell); 3222 3223 /// Get cancellation region for the current cancellation point. 3224 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } 3225 3226 static bool classof(const Stmt *T) { 3227 return T->getStmtClass() == OMPCancelDirectiveClass; 3228 } 3229 }; 3230 3231 /// This represents '#pragma omp taskloop' directive. 3232 /// 3233 /// \code 3234 /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num) 3235 /// \endcode 3236 /// In this example directive '#pragma omp taskloop' has clauses 'private' 3237 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and 3238 /// 'num_tasks' with expression 'num'. 3239 /// 3240 class OMPTaskLoopDirective : public OMPLoopDirective { 3241 friend class ASTStmtReader; 3242 /// true if the construct has inner cancel directive. 3243 bool HasCancel; 3244 3245 /// Build directive with the given start and end location. 3246 /// 3247 /// \param StartLoc Starting location of the directive kind. 3248 /// \param EndLoc Ending location of the directive. 3249 /// \param CollapsedNum Number of collapsed nested loops. 3250 /// \param NumClauses Number of clauses. 3251 /// 3252 OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3253 unsigned CollapsedNum, unsigned NumClauses) 3254 : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, 3255 llvm::omp::OMPD_taskloop, StartLoc, EndLoc, 3256 CollapsedNum, NumClauses), 3257 HasCancel(false) {} 3258 3259 /// Build an empty directive. 3260 /// 3261 /// \param CollapsedNum Number of collapsed nested loops. 3262 /// \param NumClauses Number of clauses. 3263 /// 3264 explicit OMPTaskLoopDirective(unsigned CollapsedNum, unsigned NumClauses) 3265 : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, 3266 llvm::omp::OMPD_taskloop, SourceLocation(), 3267 SourceLocation(), CollapsedNum, NumClauses), 3268 HasCancel(false) {} 3269 3270 /// Set cancel state. 3271 void setHasCancel(bool Has) { HasCancel = Has; } 3272 3273 public: 3274 /// Creates directive with a list of \a Clauses. 3275 /// 3276 /// \param C AST context. 3277 /// \param StartLoc Starting location of the directive kind. 3278 /// \param EndLoc Ending Location of the directive. 3279 /// \param CollapsedNum Number of collapsed loops. 3280 /// \param Clauses List of clauses. 3281 /// \param AssociatedStmt Statement, associated with the directive. 3282 /// \param Exprs Helper expressions for CodeGen. 3283 /// \param HasCancel true if this directive has inner cancel directive. 3284 /// 3285 static OMPTaskLoopDirective * 3286 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3287 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3288 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 3289 3290 /// Creates an empty directive with the place 3291 /// for \a NumClauses clauses. 3292 /// 3293 /// \param C AST context. 3294 /// \param CollapsedNum Number of collapsed nested loops. 3295 /// \param NumClauses Number of clauses. 3296 /// 3297 static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C, 3298 unsigned NumClauses, 3299 unsigned CollapsedNum, EmptyShell); 3300 3301 /// Return true if current directive has inner cancel directive. 3302 bool hasCancel() const { return HasCancel; } 3303 3304 static bool classof(const Stmt *T) { 3305 return T->getStmtClass() == OMPTaskLoopDirectiveClass; 3306 } 3307 }; 3308 3309 /// This represents '#pragma omp taskloop simd' directive. 3310 /// 3311 /// \code 3312 /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num) 3313 /// \endcode 3314 /// In this example directive '#pragma omp taskloop simd' has clauses 'private' 3315 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and 3316 /// 'num_tasks' with expression 'num'. 3317 /// 3318 class OMPTaskLoopSimdDirective : public OMPLoopDirective { 3319 friend class ASTStmtReader; 3320 /// Build directive with the given start and end location. 3321 /// 3322 /// \param StartLoc Starting location of the directive kind. 3323 /// \param EndLoc Ending location of the directive. 3324 /// \param CollapsedNum Number of collapsed nested loops. 3325 /// \param NumClauses Number of clauses. 3326 /// 3327 OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3328 unsigned CollapsedNum, unsigned NumClauses) 3329 : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass, 3330 llvm::omp::OMPD_taskloop_simd, StartLoc, EndLoc, 3331 CollapsedNum, NumClauses) {} 3332 3333 /// Build an empty directive. 3334 /// 3335 /// \param CollapsedNum Number of collapsed nested loops. 3336 /// \param NumClauses Number of clauses. 3337 /// 3338 explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum, unsigned NumClauses) 3339 : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass, 3340 llvm::omp::OMPD_taskloop_simd, SourceLocation(), 3341 SourceLocation(), CollapsedNum, NumClauses) {} 3342 3343 public: 3344 /// Creates directive with a list of \a Clauses. 3345 /// 3346 /// \param C AST context. 3347 /// \param StartLoc Starting location of the directive kind. 3348 /// \param EndLoc Ending Location of the directive. 3349 /// \param CollapsedNum Number of collapsed loops. 3350 /// \param Clauses List of clauses. 3351 /// \param AssociatedStmt Statement, associated with the directive. 3352 /// \param Exprs Helper expressions for CodeGen. 3353 /// 3354 static OMPTaskLoopSimdDirective * 3355 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3356 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3357 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3358 3359 /// Creates an empty directive with the place 3360 /// for \a NumClauses clauses. 3361 /// 3362 /// \param C AST context. 3363 /// \param CollapsedNum Number of collapsed nested loops. 3364 /// \param NumClauses Number of clauses. 3365 /// 3366 static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, 3367 unsigned NumClauses, 3368 unsigned CollapsedNum, 3369 EmptyShell); 3370 3371 static bool classof(const Stmt *T) { 3372 return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass; 3373 } 3374 }; 3375 3376 /// This represents '#pragma omp master taskloop' directive. 3377 /// 3378 /// \code 3379 /// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num) 3380 /// \endcode 3381 /// In this example directive '#pragma omp master taskloop' has clauses 3382 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 3383 /// and 'num_tasks' with expression 'num'. 3384 /// 3385 class OMPMasterTaskLoopDirective : public OMPLoopDirective { 3386 friend class ASTStmtReader; 3387 /// true if the construct has inner cancel directive. 3388 bool HasCancel; 3389 3390 /// Build directive with the given start and end location. 3391 /// 3392 /// \param StartLoc Starting location of the directive kind. 3393 /// \param EndLoc Ending location of the directive. 3394 /// \param CollapsedNum Number of collapsed nested loops. 3395 /// \param NumClauses Number of clauses. 3396 /// 3397 OMPMasterTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3398 unsigned CollapsedNum, unsigned NumClauses) 3399 : OMPLoopDirective(this, OMPMasterTaskLoopDirectiveClass, 3400 llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc, 3401 CollapsedNum, NumClauses), 3402 HasCancel(false) {} 3403 3404 /// Build an empty directive. 3405 /// 3406 /// \param CollapsedNum Number of collapsed nested loops. 3407 /// \param NumClauses Number of clauses. 3408 /// 3409 explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum, 3410 unsigned NumClauses) 3411 : OMPLoopDirective(this, OMPMasterTaskLoopDirectiveClass, 3412 llvm::omp::OMPD_master_taskloop, SourceLocation(), 3413 SourceLocation(), CollapsedNum, NumClauses), 3414 HasCancel(false) {} 3415 3416 /// Set cancel state. 3417 void setHasCancel(bool Has) { HasCancel = Has; } 3418 3419 public: 3420 /// Creates directive with a list of \a Clauses. 3421 /// 3422 /// \param C AST context. 3423 /// \param StartLoc Starting location of the directive kind. 3424 /// \param EndLoc Ending Location of the directive. 3425 /// \param CollapsedNum Number of collapsed loops. 3426 /// \param Clauses List of clauses. 3427 /// \param AssociatedStmt Statement, associated with the directive. 3428 /// \param Exprs Helper expressions for CodeGen. 3429 /// \param HasCancel true if this directive has inner cancel directive. 3430 /// 3431 static OMPMasterTaskLoopDirective * 3432 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3433 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3434 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 3435 3436 /// Creates an empty directive with the place 3437 /// for \a NumClauses clauses. 3438 /// 3439 /// \param C AST context. 3440 /// \param CollapsedNum Number of collapsed nested loops. 3441 /// \param NumClauses Number of clauses. 3442 /// 3443 static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C, 3444 unsigned NumClauses, 3445 unsigned CollapsedNum, 3446 EmptyShell); 3447 3448 /// Return true if current directive has inner cancel directive. 3449 bool hasCancel() const { return HasCancel; } 3450 3451 static bool classof(const Stmt *T) { 3452 return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass; 3453 } 3454 }; 3455 3456 /// This represents '#pragma omp master taskloop simd' directive. 3457 /// 3458 /// \code 3459 /// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num) 3460 /// \endcode 3461 /// In this example directive '#pragma omp master taskloop simd' has clauses 3462 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 3463 /// and 'num_tasks' with expression 'num'. 3464 /// 3465 class OMPMasterTaskLoopSimdDirective : public OMPLoopDirective { 3466 friend class ASTStmtReader; 3467 /// Build directive with the given start and end location. 3468 /// 3469 /// \param StartLoc Starting location of the directive kind. 3470 /// \param EndLoc Ending location of the directive. 3471 /// \param CollapsedNum Number of collapsed nested loops. 3472 /// \param NumClauses Number of clauses. 3473 /// 3474 OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3475 unsigned CollapsedNum, unsigned NumClauses) 3476 : OMPLoopDirective(this, OMPMasterTaskLoopSimdDirectiveClass, 3477 llvm::omp::OMPD_master_taskloop_simd, StartLoc, EndLoc, 3478 CollapsedNum, NumClauses) {} 3479 3480 /// Build an empty directive. 3481 /// 3482 /// \param CollapsedNum Number of collapsed nested loops. 3483 /// \param NumClauses Number of clauses. 3484 /// 3485 explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum, 3486 unsigned NumClauses) 3487 : OMPLoopDirective(this, OMPMasterTaskLoopSimdDirectiveClass, 3488 llvm::omp::OMPD_master_taskloop_simd, SourceLocation(), 3489 SourceLocation(), CollapsedNum, NumClauses) {} 3490 3491 public: 3492 /// Creates directive with a list of \p Clauses. 3493 /// 3494 /// \param C AST context. 3495 /// \param StartLoc Starting location of the directive kind. 3496 /// \param EndLoc Ending Location of the directive. 3497 /// \param CollapsedNum Number of collapsed loops. 3498 /// \param Clauses List of clauses. 3499 /// \param AssociatedStmt Statement, associated with the directive. 3500 /// \param Exprs Helper expressions for CodeGen. 3501 /// 3502 static OMPMasterTaskLoopSimdDirective * 3503 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3504 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3505 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3506 3507 /// Creates an empty directive with the place for \p NumClauses clauses. 3508 /// 3509 /// \param C AST context. 3510 /// \param CollapsedNum Number of collapsed nested loops. 3511 /// \param NumClauses Number of clauses. 3512 /// 3513 static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, 3514 unsigned NumClauses, 3515 unsigned CollapsedNum, 3516 EmptyShell); 3517 3518 static bool classof(const Stmt *T) { 3519 return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass; 3520 } 3521 }; 3522 3523 /// This represents '#pragma omp parallel master taskloop' directive. 3524 /// 3525 /// \code 3526 /// #pragma omp parallel master taskloop private(a,b) grainsize(val) 3527 /// num_tasks(num) 3528 /// \endcode 3529 /// In this example directive '#pragma omp parallel master taskloop' has clauses 3530 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 3531 /// and 'num_tasks' with expression 'num'. 3532 /// 3533 class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective { 3534 friend class ASTStmtReader; 3535 /// true if the construct has inner cancel directive. 3536 bool HasCancel; 3537 3538 /// Build directive with the given start and end location. 3539 /// 3540 /// \param StartLoc Starting location of the directive kind. 3541 /// \param EndLoc Ending location of the directive. 3542 /// \param CollapsedNum Number of collapsed nested loops. 3543 /// \param NumClauses Number of clauses. 3544 /// 3545 OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc, 3546 SourceLocation EndLoc, 3547 unsigned CollapsedNum, unsigned NumClauses) 3548 : OMPLoopDirective(this, OMPParallelMasterTaskLoopDirectiveClass, 3549 llvm::omp::OMPD_parallel_master_taskloop, StartLoc, 3550 EndLoc, CollapsedNum, NumClauses), 3551 HasCancel(false) {} 3552 3553 /// Build an empty directive. 3554 /// 3555 /// \param CollapsedNum Number of collapsed nested loops. 3556 /// \param NumClauses Number of clauses. 3557 /// 3558 explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum, 3559 unsigned NumClauses) 3560 : OMPLoopDirective(this, OMPParallelMasterTaskLoopDirectiveClass, 3561 llvm::omp::OMPD_parallel_master_taskloop, 3562 SourceLocation(), SourceLocation(), CollapsedNum, 3563 NumClauses), 3564 HasCancel(false) {} 3565 3566 /// Set cancel state. 3567 void setHasCancel(bool Has) { HasCancel = Has; } 3568 3569 public: 3570 /// Creates directive with a list of \a Clauses. 3571 /// 3572 /// \param C AST context. 3573 /// \param StartLoc Starting location of the directive kind. 3574 /// \param EndLoc Ending Location of the directive. 3575 /// \param CollapsedNum Number of collapsed loops. 3576 /// \param Clauses List of clauses. 3577 /// \param AssociatedStmt Statement, associated with the directive. 3578 /// \param Exprs Helper expressions for CodeGen. 3579 /// \param HasCancel true if this directive has inner cancel directive. 3580 /// 3581 static OMPParallelMasterTaskLoopDirective * 3582 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3583 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3584 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 3585 3586 /// Creates an empty directive with the place 3587 /// for \a NumClauses clauses. 3588 /// 3589 /// \param C AST context. 3590 /// \param CollapsedNum Number of collapsed nested loops. 3591 /// \param NumClauses Number of clauses. 3592 /// 3593 static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C, 3594 unsigned NumClauses, 3595 unsigned CollapsedNum, 3596 EmptyShell); 3597 3598 /// Return true if current directive has inner cancel directive. 3599 bool hasCancel() const { return HasCancel; } 3600 3601 static bool classof(const Stmt *T) { 3602 return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass; 3603 } 3604 }; 3605 3606 /// This represents '#pragma omp parallel master taskloop simd' directive. 3607 /// 3608 /// \code 3609 /// #pragma omp parallel master taskloop simd private(a,b) grainsize(val) 3610 /// num_tasks(num) 3611 /// \endcode 3612 /// In this example directive '#pragma omp parallel master taskloop simd' has 3613 /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with 3614 /// expression 'val' and 'num_tasks' with expression 'num'. 3615 /// 3616 class OMPParallelMasterTaskLoopSimdDirective : public OMPLoopDirective { 3617 friend class ASTStmtReader; 3618 /// Build directive with the given start and end location. 3619 /// 3620 /// \param StartLoc Starting location of the directive kind. 3621 /// \param EndLoc Ending location of the directive. 3622 /// \param CollapsedNum Number of collapsed nested loops. 3623 /// \param NumClauses Number of clauses. 3624 /// 3625 OMPParallelMasterTaskLoopSimdDirective(SourceLocation StartLoc, 3626 SourceLocation EndLoc, 3627 unsigned CollapsedNum, 3628 unsigned NumClauses) 3629 : OMPLoopDirective(this, OMPParallelMasterTaskLoopSimdDirectiveClass, 3630 llvm::omp::OMPD_parallel_master_taskloop_simd, 3631 StartLoc, EndLoc, CollapsedNum, NumClauses) {} 3632 3633 /// Build an empty directive. 3634 /// 3635 /// \param CollapsedNum Number of collapsed nested loops. 3636 /// \param NumClauses Number of clauses. 3637 /// 3638 explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum, 3639 unsigned NumClauses) 3640 : OMPLoopDirective(this, OMPParallelMasterTaskLoopSimdDirectiveClass, 3641 llvm::omp::OMPD_parallel_master_taskloop_simd, 3642 SourceLocation(), SourceLocation(), CollapsedNum, 3643 NumClauses) {} 3644 3645 public: 3646 /// Creates directive with a list of \p Clauses. 3647 /// 3648 /// \param C AST context. 3649 /// \param StartLoc Starting location of the directive kind. 3650 /// \param EndLoc Ending Location of the directive. 3651 /// \param CollapsedNum Number of collapsed loops. 3652 /// \param Clauses List of clauses. 3653 /// \param AssociatedStmt Statement, associated with the directive. 3654 /// \param Exprs Helper expressions for CodeGen. 3655 /// 3656 static OMPParallelMasterTaskLoopSimdDirective * 3657 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3658 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3659 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3660 3661 /// Creates an empty directive with the place 3662 /// for \a NumClauses clauses. 3663 /// 3664 /// \param C AST context. 3665 /// \param CollapsedNum Number of collapsed nested loops. 3666 /// \param NumClauses Number of clauses. 3667 /// 3668 static OMPParallelMasterTaskLoopSimdDirective * 3669 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 3670 EmptyShell); 3671 3672 static bool classof(const Stmt *T) { 3673 return T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass; 3674 } 3675 }; 3676 3677 /// This represents '#pragma omp distribute' directive. 3678 /// 3679 /// \code 3680 /// #pragma omp distribute private(a,b) 3681 /// \endcode 3682 /// In this example directive '#pragma omp distribute' has clauses 'private' 3683 /// with the variables 'a' and 'b' 3684 /// 3685 class OMPDistributeDirective : public OMPLoopDirective { 3686 friend class ASTStmtReader; 3687 3688 /// Build directive with the given start and end location. 3689 /// 3690 /// \param StartLoc Starting location of the directive kind. 3691 /// \param EndLoc Ending location of the directive. 3692 /// \param CollapsedNum Number of collapsed nested loops. 3693 /// \param NumClauses Number of clauses. 3694 /// 3695 OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3696 unsigned CollapsedNum, unsigned NumClauses) 3697 : OMPLoopDirective(this, OMPDistributeDirectiveClass, 3698 llvm::omp::OMPD_distribute, StartLoc, EndLoc, 3699 CollapsedNum, NumClauses) {} 3700 3701 /// Build an empty directive. 3702 /// 3703 /// \param CollapsedNum Number of collapsed nested loops. 3704 /// \param NumClauses Number of clauses. 3705 /// 3706 explicit OMPDistributeDirective(unsigned CollapsedNum, unsigned NumClauses) 3707 : OMPLoopDirective(this, OMPDistributeDirectiveClass, 3708 llvm::omp::OMPD_distribute, SourceLocation(), 3709 SourceLocation(), CollapsedNum, NumClauses) {} 3710 3711 public: 3712 /// Creates directive with a list of \a Clauses. 3713 /// 3714 /// \param C AST context. 3715 /// \param StartLoc Starting location of the directive kind. 3716 /// \param EndLoc Ending Location of the directive. 3717 /// \param CollapsedNum Number of collapsed loops. 3718 /// \param Clauses List of clauses. 3719 /// \param AssociatedStmt Statement, associated with the directive. 3720 /// \param Exprs Helper expressions for CodeGen. 3721 /// 3722 static OMPDistributeDirective * 3723 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3724 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3725 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3726 3727 /// Creates an empty directive with the place 3728 /// for \a NumClauses clauses. 3729 /// 3730 /// \param C AST context. 3731 /// \param CollapsedNum Number of collapsed nested loops. 3732 /// \param NumClauses Number of clauses. 3733 /// 3734 static OMPDistributeDirective *CreateEmpty(const ASTContext &C, 3735 unsigned NumClauses, 3736 unsigned CollapsedNum, EmptyShell); 3737 3738 static bool classof(const Stmt *T) { 3739 return T->getStmtClass() == OMPDistributeDirectiveClass; 3740 } 3741 }; 3742 3743 /// This represents '#pragma omp target update' directive. 3744 /// 3745 /// \code 3746 /// #pragma omp target update to(a) from(b) device(1) 3747 /// \endcode 3748 /// In this example directive '#pragma omp target update' has clause 'to' with 3749 /// argument 'a', clause 'from' with argument 'b' and clause 'device' with 3750 /// argument '1'. 3751 /// 3752 class OMPTargetUpdateDirective : public OMPExecutableDirective { 3753 friend class ASTStmtReader; 3754 /// Build directive with the given start and end location. 3755 /// 3756 /// \param StartLoc Starting location of the directive kind. 3757 /// \param EndLoc Ending Location of the directive. 3758 /// \param NumClauses The number of clauses. 3759 /// 3760 OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3761 unsigned NumClauses) 3762 : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass, 3763 llvm::omp::OMPD_target_update, StartLoc, EndLoc, 3764 NumClauses, 1) {} 3765 3766 /// Build an empty directive. 3767 /// 3768 /// \param NumClauses Number of clauses. 3769 /// 3770 explicit OMPTargetUpdateDirective(unsigned NumClauses) 3771 : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass, 3772 llvm::omp::OMPD_target_update, SourceLocation(), 3773 SourceLocation(), NumClauses, 1) {} 3774 3775 public: 3776 /// Creates directive with a list of \a Clauses. 3777 /// 3778 /// \param C AST context. 3779 /// \param StartLoc Starting location of the directive kind. 3780 /// \param EndLoc Ending Location of the directive. 3781 /// \param Clauses List of clauses. 3782 /// \param AssociatedStmt Statement, associated with the directive. 3783 /// 3784 static OMPTargetUpdateDirective * 3785 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3786 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 3787 3788 /// Creates an empty directive with the place for \a NumClauses 3789 /// clauses. 3790 /// 3791 /// \param C AST context. 3792 /// \param NumClauses The number of clauses. 3793 /// 3794 static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C, 3795 unsigned NumClauses, EmptyShell); 3796 3797 static bool classof(const Stmt *T) { 3798 return T->getStmtClass() == OMPTargetUpdateDirectiveClass; 3799 } 3800 }; 3801 3802 /// This represents '#pragma omp distribute parallel for' composite 3803 /// directive. 3804 /// 3805 /// \code 3806 /// #pragma omp distribute parallel for private(a,b) 3807 /// \endcode 3808 /// In this example directive '#pragma omp distribute parallel for' has clause 3809 /// 'private' with the variables 'a' and 'b' 3810 /// 3811 class OMPDistributeParallelForDirective : public OMPLoopDirective { 3812 friend class ASTStmtReader; 3813 /// Special reference expression for handling task reduction. Used to store 3814 /// the taskgroup descriptor returned by the runtime functions. 3815 Expr *TaskRedRef = nullptr; 3816 /// true if the construct has inner cancel directive. 3817 bool HasCancel = false; 3818 3819 /// Build directive with the given start and end location. 3820 /// 3821 /// \param StartLoc Starting location of the directive kind. 3822 /// \param EndLoc Ending location of the directive. 3823 /// \param CollapsedNum Number of collapsed nested loops. 3824 /// \param NumClauses Number of clauses. 3825 /// 3826 OMPDistributeParallelForDirective(SourceLocation StartLoc, 3827 SourceLocation EndLoc, 3828 unsigned CollapsedNum, unsigned NumClauses) 3829 : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass, 3830 llvm::omp::OMPD_distribute_parallel_for, StartLoc, 3831 EndLoc, CollapsedNum, NumClauses), 3832 HasCancel(false) {} 3833 3834 /// Build an empty directive. 3835 /// 3836 /// \param CollapsedNum Number of collapsed nested loops. 3837 /// \param NumClauses Number of clauses. 3838 /// 3839 explicit OMPDistributeParallelForDirective(unsigned CollapsedNum, 3840 unsigned NumClauses) 3841 : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass, 3842 llvm::omp::OMPD_distribute_parallel_for, 3843 SourceLocation(), SourceLocation(), CollapsedNum, 3844 NumClauses), 3845 HasCancel(false) {} 3846 3847 /// Sets special task reduction descriptor. 3848 void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } 3849 3850 /// Set cancel state. 3851 void setHasCancel(bool Has) { HasCancel = Has; } 3852 3853 public: 3854 /// Creates directive with a list of \a Clauses. 3855 /// 3856 /// \param C AST context. 3857 /// \param StartLoc Starting location of the directive kind. 3858 /// \param EndLoc Ending Location of the directive. 3859 /// \param CollapsedNum Number of collapsed loops. 3860 /// \param Clauses List of clauses. 3861 /// \param AssociatedStmt Statement, associated with the directive. 3862 /// \param Exprs Helper expressions for CodeGen. 3863 /// \param TaskRedRef Task reduction special reference expression to handle 3864 /// taskgroup descriptor. 3865 /// \param HasCancel true if this directive has inner cancel directive. 3866 /// 3867 static OMPDistributeParallelForDirective * 3868 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3869 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3870 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 3871 bool HasCancel); 3872 3873 /// Creates an empty directive with the place 3874 /// for \a NumClauses clauses. 3875 /// 3876 /// \param C AST context. 3877 /// \param CollapsedNum Number of collapsed nested loops. 3878 /// \param NumClauses Number of clauses. 3879 /// 3880 static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C, 3881 unsigned NumClauses, 3882 unsigned CollapsedNum, 3883 EmptyShell); 3884 3885 /// Returns special task reduction reference expression. 3886 Expr *getTaskReductionRefExpr() { return TaskRedRef; } 3887 const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } 3888 3889 /// Return true if current directive has inner cancel directive. 3890 bool hasCancel() const { return HasCancel; } 3891 3892 static bool classof(const Stmt *T) { 3893 return T->getStmtClass() == OMPDistributeParallelForDirectiveClass; 3894 } 3895 }; 3896 3897 /// This represents '#pragma omp distribute parallel for simd' composite 3898 /// directive. 3899 /// 3900 /// \code 3901 /// #pragma omp distribute parallel for simd private(x) 3902 /// \endcode 3903 /// In this example directive '#pragma omp distribute parallel for simd' has 3904 /// clause 'private' with the variables 'x' 3905 /// 3906 class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective { 3907 friend class ASTStmtReader; 3908 3909 /// Build directive with the given start and end location. 3910 /// 3911 /// \param StartLoc Starting location of the directive kind. 3912 /// \param EndLoc Ending location of the directive. 3913 /// \param CollapsedNum Number of collapsed nested loops. 3914 /// \param NumClauses Number of clauses. 3915 /// 3916 OMPDistributeParallelForSimdDirective(SourceLocation StartLoc, 3917 SourceLocation EndLoc, 3918 unsigned CollapsedNum, 3919 unsigned NumClauses) 3920 : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass, 3921 llvm::omp::OMPD_distribute_parallel_for_simd, StartLoc, 3922 EndLoc, CollapsedNum, NumClauses) {} 3923 3924 /// Build an empty directive. 3925 /// 3926 /// \param CollapsedNum Number of collapsed nested loops. 3927 /// \param NumClauses Number of clauses. 3928 /// 3929 explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum, 3930 unsigned NumClauses) 3931 : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass, 3932 llvm::omp::OMPD_distribute_parallel_for_simd, 3933 SourceLocation(), SourceLocation(), CollapsedNum, 3934 NumClauses) {} 3935 3936 public: 3937 /// Creates directive with a list of \a Clauses. 3938 /// 3939 /// \param C AST context. 3940 /// \param StartLoc Starting location of the directive kind. 3941 /// \param EndLoc Ending Location of the directive. 3942 /// \param CollapsedNum Number of collapsed loops. 3943 /// \param Clauses List of clauses. 3944 /// \param AssociatedStmt Statement, associated with the directive. 3945 /// \param Exprs Helper expressions for CodeGen. 3946 /// 3947 static OMPDistributeParallelForSimdDirective *Create( 3948 const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3949 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3950 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3951 3952 /// Creates an empty directive with the place for \a NumClauses clauses. 3953 /// 3954 /// \param C AST context. 3955 /// \param CollapsedNum Number of collapsed nested loops. 3956 /// \param NumClauses Number of clauses. 3957 /// 3958 static OMPDistributeParallelForSimdDirective *CreateEmpty( 3959 const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 3960 EmptyShell); 3961 3962 static bool classof(const Stmt *T) { 3963 return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass; 3964 } 3965 }; 3966 3967 /// This represents '#pragma omp distribute simd' composite directive. 3968 /// 3969 /// \code 3970 /// #pragma omp distribute simd private(x) 3971 /// \endcode 3972 /// In this example directive '#pragma omp distribute simd' has clause 3973 /// 'private' with the variables 'x' 3974 /// 3975 class OMPDistributeSimdDirective final : public OMPLoopDirective { 3976 friend class ASTStmtReader; 3977 3978 /// Build directive with the given start and end location. 3979 /// 3980 /// \param StartLoc Starting location of the directive kind. 3981 /// \param EndLoc Ending location of the directive. 3982 /// \param CollapsedNum Number of collapsed nested loops. 3983 /// \param NumClauses Number of clauses. 3984 /// 3985 OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3986 unsigned CollapsedNum, unsigned NumClauses) 3987 : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass, 3988 llvm::omp::OMPD_distribute_simd, StartLoc, EndLoc, 3989 CollapsedNum, NumClauses) {} 3990 3991 /// Build an empty directive. 3992 /// 3993 /// \param CollapsedNum Number of collapsed nested loops. 3994 /// \param NumClauses Number of clauses. 3995 /// 3996 explicit OMPDistributeSimdDirective(unsigned CollapsedNum, 3997 unsigned NumClauses) 3998 : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass, 3999 llvm::omp::OMPD_distribute_simd, SourceLocation(), 4000 SourceLocation(), CollapsedNum, NumClauses) {} 4001 4002 public: 4003 /// Creates directive with a list of \a Clauses. 4004 /// 4005 /// \param C AST context. 4006 /// \param StartLoc Starting location of the directive kind. 4007 /// \param EndLoc Ending Location of the directive. 4008 /// \param CollapsedNum Number of collapsed loops. 4009 /// \param Clauses List of clauses. 4010 /// \param AssociatedStmt Statement, associated with the directive. 4011 /// \param Exprs Helper expressions for CodeGen. 4012 /// 4013 static OMPDistributeSimdDirective * 4014 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4015 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4016 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4017 4018 /// Creates an empty directive with the place for \a NumClauses clauses. 4019 /// 4020 /// \param C AST context. 4021 /// \param CollapsedNum Number of collapsed nested loops. 4022 /// \param NumClauses Number of clauses. 4023 /// 4024 static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C, 4025 unsigned NumClauses, 4026 unsigned CollapsedNum, 4027 EmptyShell); 4028 4029 static bool classof(const Stmt *T) { 4030 return T->getStmtClass() == OMPDistributeSimdDirectiveClass; 4031 } 4032 }; 4033 4034 /// This represents '#pragma omp target parallel for simd' directive. 4035 /// 4036 /// \code 4037 /// #pragma omp target parallel for simd private(a) map(b) safelen(c) 4038 /// \endcode 4039 /// In this example directive '#pragma omp target parallel for simd' has clauses 4040 /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen' 4041 /// with the variable 'c'. 4042 /// 4043 class OMPTargetParallelForSimdDirective final : public OMPLoopDirective { 4044 friend class ASTStmtReader; 4045 4046 /// Build directive with the given start and end location. 4047 /// 4048 /// \param StartLoc Starting location of the directive kind. 4049 /// \param EndLoc Ending location of the directive. 4050 /// \param CollapsedNum Number of collapsed nested loops. 4051 /// \param NumClauses Number of clauses. 4052 /// 4053 OMPTargetParallelForSimdDirective(SourceLocation StartLoc, 4054 SourceLocation EndLoc, 4055 unsigned CollapsedNum, unsigned NumClauses) 4056 : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass, 4057 llvm::omp::OMPD_target_parallel_for_simd, StartLoc, 4058 EndLoc, CollapsedNum, NumClauses) {} 4059 4060 /// Build an empty directive. 4061 /// 4062 /// \param CollapsedNum Number of collapsed nested loops. 4063 /// \param NumClauses Number of clauses. 4064 /// 4065 explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum, 4066 unsigned NumClauses) 4067 : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass, 4068 llvm::omp::OMPD_target_parallel_for_simd, 4069 SourceLocation(), SourceLocation(), CollapsedNum, 4070 NumClauses) {} 4071 4072 public: 4073 /// Creates directive with a list of \a Clauses. 4074 /// 4075 /// \param C AST context. 4076 /// \param StartLoc Starting location of the directive kind. 4077 /// \param EndLoc Ending Location of the directive. 4078 /// \param CollapsedNum Number of collapsed loops. 4079 /// \param Clauses List of clauses. 4080 /// \param AssociatedStmt Statement, associated with the directive. 4081 /// \param Exprs Helper expressions for CodeGen. 4082 /// 4083 static OMPTargetParallelForSimdDirective * 4084 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4085 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4086 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4087 4088 /// Creates an empty directive with the place for \a NumClauses clauses. 4089 /// 4090 /// \param C AST context. 4091 /// \param CollapsedNum Number of collapsed nested loops. 4092 /// \param NumClauses Number of clauses. 4093 /// 4094 static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C, 4095 unsigned NumClauses, 4096 unsigned CollapsedNum, 4097 EmptyShell); 4098 4099 static bool classof(const Stmt *T) { 4100 return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass; 4101 } 4102 }; 4103 4104 /// This represents '#pragma omp target simd' directive. 4105 /// 4106 /// \code 4107 /// #pragma omp target simd private(a) map(b) safelen(c) 4108 /// \endcode 4109 /// In this example directive '#pragma omp target simd' has clauses 'private' 4110 /// with the variable 'a', 'map' with the variable 'b' and 'safelen' with 4111 /// the variable 'c'. 4112 /// 4113 class OMPTargetSimdDirective final : public OMPLoopDirective { 4114 friend class ASTStmtReader; 4115 4116 /// Build directive with the given start and end location. 4117 /// 4118 /// \param StartLoc Starting location of the directive kind. 4119 /// \param EndLoc Ending location of the directive. 4120 /// \param CollapsedNum Number of collapsed nested loops. 4121 /// \param NumClauses Number of clauses. 4122 /// 4123 OMPTargetSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4124 unsigned CollapsedNum, unsigned NumClauses) 4125 : OMPLoopDirective(this, OMPTargetSimdDirectiveClass, 4126 llvm::omp::OMPD_target_simd, StartLoc, EndLoc, 4127 CollapsedNum, NumClauses) {} 4128 4129 /// Build an empty directive. 4130 /// 4131 /// \param CollapsedNum Number of collapsed nested loops. 4132 /// \param NumClauses Number of clauses. 4133 /// 4134 explicit OMPTargetSimdDirective(unsigned CollapsedNum, unsigned NumClauses) 4135 : OMPLoopDirective(this, OMPTargetSimdDirectiveClass, 4136 llvm::omp::OMPD_target_simd, SourceLocation(), 4137 SourceLocation(), CollapsedNum, NumClauses) {} 4138 4139 public: 4140 /// Creates directive with a list of \a Clauses. 4141 /// 4142 /// \param C AST context. 4143 /// \param StartLoc Starting location of the directive kind. 4144 /// \param EndLoc Ending Location of the directive. 4145 /// \param CollapsedNum Number of collapsed loops. 4146 /// \param Clauses List of clauses. 4147 /// \param AssociatedStmt Statement, associated with the directive. 4148 /// \param Exprs Helper expressions for CodeGen. 4149 /// 4150 static OMPTargetSimdDirective * 4151 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4152 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4153 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4154 4155 /// Creates an empty directive with the place for \a NumClauses clauses. 4156 /// 4157 /// \param C AST context. 4158 /// \param CollapsedNum Number of collapsed nested loops. 4159 /// \param NumClauses Number of clauses. 4160 /// 4161 static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C, 4162 unsigned NumClauses, 4163 unsigned CollapsedNum, 4164 EmptyShell); 4165 4166 static bool classof(const Stmt *T) { 4167 return T->getStmtClass() == OMPTargetSimdDirectiveClass; 4168 } 4169 }; 4170 4171 /// This represents '#pragma omp teams distribute' directive. 4172 /// 4173 /// \code 4174 /// #pragma omp teams distribute private(a,b) 4175 /// \endcode 4176 /// In this example directive '#pragma omp teams distribute' has clauses 4177 /// 'private' with the variables 'a' and 'b' 4178 /// 4179 class OMPTeamsDistributeDirective final : public OMPLoopDirective { 4180 friend class ASTStmtReader; 4181 4182 /// Build directive with the given start and end location. 4183 /// 4184 /// \param StartLoc Starting location of the directive kind. 4185 /// \param EndLoc Ending location of the directive. 4186 /// \param CollapsedNum Number of collapsed nested loops. 4187 /// \param NumClauses Number of clauses. 4188 /// 4189 OMPTeamsDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4190 unsigned CollapsedNum, unsigned NumClauses) 4191 : OMPLoopDirective(this, OMPTeamsDistributeDirectiveClass, 4192 llvm::omp::OMPD_teams_distribute, StartLoc, EndLoc, 4193 CollapsedNum, NumClauses) {} 4194 4195 /// Build an empty directive. 4196 /// 4197 /// \param CollapsedNum Number of collapsed nested loops. 4198 /// \param NumClauses Number of clauses. 4199 /// 4200 explicit OMPTeamsDistributeDirective(unsigned CollapsedNum, 4201 unsigned NumClauses) 4202 : OMPLoopDirective(this, OMPTeamsDistributeDirectiveClass, 4203 llvm::omp::OMPD_teams_distribute, SourceLocation(), 4204 SourceLocation(), CollapsedNum, NumClauses) {} 4205 4206 public: 4207 /// Creates directive with a list of \a Clauses. 4208 /// 4209 /// \param C AST context. 4210 /// \param StartLoc Starting location of the directive kind. 4211 /// \param EndLoc Ending Location of the directive. 4212 /// \param CollapsedNum Number of collapsed loops. 4213 /// \param Clauses List of clauses. 4214 /// \param AssociatedStmt Statement, associated with the directive. 4215 /// \param Exprs Helper expressions for CodeGen. 4216 /// 4217 static OMPTeamsDistributeDirective * 4218 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4219 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4220 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4221 4222 /// Creates an empty directive with the place for \a NumClauses clauses. 4223 /// 4224 /// \param C AST context. 4225 /// \param CollapsedNum Number of collapsed nested loops. 4226 /// \param NumClauses Number of clauses. 4227 /// 4228 static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C, 4229 unsigned NumClauses, 4230 unsigned CollapsedNum, 4231 EmptyShell); 4232 4233 static bool classof(const Stmt *T) { 4234 return T->getStmtClass() == OMPTeamsDistributeDirectiveClass; 4235 } 4236 }; 4237 4238 /// This represents '#pragma omp teams distribute simd' 4239 /// combined directive. 4240 /// 4241 /// \code 4242 /// #pragma omp teams distribute simd private(a,b) 4243 /// \endcode 4244 /// In this example directive '#pragma omp teams distribute simd' 4245 /// has clause 'private' with the variables 'a' and 'b' 4246 /// 4247 class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective { 4248 friend class ASTStmtReader; 4249 4250 /// Build directive with the given start and end location. 4251 /// 4252 /// \param StartLoc Starting location of the directive kind. 4253 /// \param EndLoc Ending location of the directive. 4254 /// \param CollapsedNum Number of collapsed nested loops. 4255 /// \param NumClauses Number of clauses. 4256 /// 4257 OMPTeamsDistributeSimdDirective(SourceLocation StartLoc, 4258 SourceLocation EndLoc, unsigned CollapsedNum, 4259 unsigned NumClauses) 4260 : OMPLoopDirective(this, OMPTeamsDistributeSimdDirectiveClass, 4261 llvm::omp::OMPD_teams_distribute_simd, StartLoc, 4262 EndLoc, CollapsedNum, NumClauses) {} 4263 4264 /// Build an empty directive. 4265 /// 4266 /// \param CollapsedNum Number of collapsed nested loops. 4267 /// \param NumClauses Number of clauses. 4268 /// 4269 explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum, 4270 unsigned NumClauses) 4271 : OMPLoopDirective(this, OMPTeamsDistributeSimdDirectiveClass, 4272 llvm::omp::OMPD_teams_distribute_simd, 4273 SourceLocation(), SourceLocation(), CollapsedNum, 4274 NumClauses) {} 4275 4276 public: 4277 /// Creates directive with a list of \a Clauses. 4278 /// 4279 /// \param C AST context. 4280 /// \param StartLoc Starting location of the directive kind. 4281 /// \param EndLoc Ending Location of the directive. 4282 /// \param CollapsedNum Number of collapsed loops. 4283 /// \param Clauses List of clauses. 4284 /// \param AssociatedStmt Statement, associated with the directive. 4285 /// \param Exprs Helper expressions for CodeGen. 4286 /// 4287 static OMPTeamsDistributeSimdDirective * 4288 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4289 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4290 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4291 4292 /// Creates an empty directive with the place 4293 /// for \a NumClauses clauses. 4294 /// 4295 /// \param C AST context. 4296 /// \param CollapsedNum Number of collapsed nested loops. 4297 /// \param NumClauses Number of clauses. 4298 /// 4299 static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C, 4300 unsigned NumClauses, 4301 unsigned CollapsedNum, 4302 EmptyShell); 4303 4304 static bool classof(const Stmt *T) { 4305 return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass; 4306 } 4307 }; 4308 4309 /// This represents '#pragma omp teams distribute parallel for simd' composite 4310 /// directive. 4311 /// 4312 /// \code 4313 /// #pragma omp teams distribute parallel for simd private(x) 4314 /// \endcode 4315 /// In this example directive '#pragma omp teams distribute parallel for simd' 4316 /// has clause 'private' with the variables 'x' 4317 /// 4318 class OMPTeamsDistributeParallelForSimdDirective final 4319 : public OMPLoopDirective { 4320 friend class ASTStmtReader; 4321 4322 /// Build directive with the given start and end location. 4323 /// 4324 /// \param StartLoc Starting location of the directive kind. 4325 /// \param EndLoc Ending location of the directive. 4326 /// \param CollapsedNum Number of collapsed nested loops. 4327 /// \param NumClauses Number of clauses. 4328 /// 4329 OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc, 4330 SourceLocation EndLoc, 4331 unsigned CollapsedNum, 4332 unsigned NumClauses) 4333 : OMPLoopDirective(this, OMPTeamsDistributeParallelForSimdDirectiveClass, 4334 llvm::omp::OMPD_teams_distribute_parallel_for_simd, 4335 StartLoc, EndLoc, CollapsedNum, NumClauses) {} 4336 4337 /// Build an empty directive. 4338 /// 4339 /// \param CollapsedNum Number of collapsed nested loops. 4340 /// \param NumClauses Number of clauses. 4341 /// 4342 explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum, 4343 unsigned NumClauses) 4344 : OMPLoopDirective(this, OMPTeamsDistributeParallelForSimdDirectiveClass, 4345 llvm::omp::OMPD_teams_distribute_parallel_for_simd, 4346 SourceLocation(), SourceLocation(), CollapsedNum, 4347 NumClauses) {} 4348 4349 public: 4350 /// Creates directive with a list of \a Clauses. 4351 /// 4352 /// \param C AST context. 4353 /// \param StartLoc Starting location of the directive kind. 4354 /// \param EndLoc Ending Location of the directive. 4355 /// \param CollapsedNum Number of collapsed loops. 4356 /// \param Clauses List of clauses. 4357 /// \param AssociatedStmt Statement, associated with the directive. 4358 /// \param Exprs Helper expressions for CodeGen. 4359 /// 4360 static OMPTeamsDistributeParallelForSimdDirective * 4361 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4362 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4363 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4364 4365 /// Creates an empty directive with the place for \a NumClauses clauses. 4366 /// 4367 /// \param C AST context. 4368 /// \param CollapsedNum Number of collapsed nested loops. 4369 /// \param NumClauses Number of clauses. 4370 /// 4371 static OMPTeamsDistributeParallelForSimdDirective * 4372 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4373 EmptyShell); 4374 4375 static bool classof(const Stmt *T) { 4376 return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass; 4377 } 4378 }; 4379 4380 /// This represents '#pragma omp teams distribute parallel for' composite 4381 /// directive. 4382 /// 4383 /// \code 4384 /// #pragma omp teams distribute parallel for private(x) 4385 /// \endcode 4386 /// In this example directive '#pragma omp teams distribute parallel for' 4387 /// has clause 'private' with the variables 'x' 4388 /// 4389 class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective { 4390 friend class ASTStmtReader; 4391 /// Special reference expression for handling task reduction. Used to store 4392 /// the taskgroup descriptor returned by the runtime functions. 4393 Expr *TaskRedRef = nullptr; 4394 /// true if the construct has inner cancel directive. 4395 bool HasCancel = false; 4396 4397 /// Build directive with the given start and end location. 4398 /// 4399 /// \param StartLoc Starting location of the directive kind. 4400 /// \param EndLoc Ending location of the directive. 4401 /// \param CollapsedNum Number of collapsed nested loops. 4402 /// \param NumClauses Number of clauses. 4403 /// 4404 OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc, 4405 SourceLocation EndLoc, 4406 unsigned CollapsedNum, 4407 unsigned NumClauses) 4408 : OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass, 4409 llvm::omp::OMPD_teams_distribute_parallel_for, 4410 StartLoc, EndLoc, CollapsedNum, NumClauses), 4411 HasCancel(false) {} 4412 4413 /// Build an empty directive. 4414 /// 4415 /// \param CollapsedNum Number of collapsed nested loops. 4416 /// \param NumClauses Number of clauses. 4417 /// 4418 explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum, 4419 unsigned NumClauses) 4420 : OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass, 4421 llvm::omp::OMPD_teams_distribute_parallel_for, 4422 SourceLocation(), SourceLocation(), CollapsedNum, 4423 NumClauses), 4424 HasCancel(false) {} 4425 4426 /// Sets special task reduction descriptor. 4427 void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } 4428 4429 /// Set cancel state. 4430 void setHasCancel(bool Has) { HasCancel = Has; } 4431 4432 public: 4433 /// Creates directive with a list of \a Clauses. 4434 /// 4435 /// \param C AST context. 4436 /// \param StartLoc Starting location of the directive kind. 4437 /// \param EndLoc Ending Location of the directive. 4438 /// \param CollapsedNum Number of collapsed loops. 4439 /// \param Clauses List of clauses. 4440 /// \param AssociatedStmt Statement, associated with the directive. 4441 /// \param Exprs Helper expressions for CodeGen. 4442 /// \param TaskRedRef Task reduction special reference expression to handle 4443 /// taskgroup descriptor. 4444 /// \param HasCancel true if this directive has inner cancel directive. 4445 /// 4446 static OMPTeamsDistributeParallelForDirective * 4447 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4448 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4449 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 4450 bool HasCancel); 4451 4452 /// Creates an empty directive with the place for \a NumClauses clauses. 4453 /// 4454 /// \param C AST context. 4455 /// \param CollapsedNum Number of collapsed nested loops. 4456 /// \param NumClauses Number of clauses. 4457 /// 4458 static OMPTeamsDistributeParallelForDirective * 4459 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4460 EmptyShell); 4461 4462 /// Returns special task reduction reference expression. 4463 Expr *getTaskReductionRefExpr() { return TaskRedRef; } 4464 const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } 4465 4466 /// Return true if current directive has inner cancel directive. 4467 bool hasCancel() const { return HasCancel; } 4468 4469 static bool classof(const Stmt *T) { 4470 return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass; 4471 } 4472 }; 4473 4474 /// This represents '#pragma omp target teams' directive. 4475 /// 4476 /// \code 4477 /// #pragma omp target teams if(a>0) 4478 /// \endcode 4479 /// In this example directive '#pragma omp target teams' has clause 'if' with 4480 /// condition 'a>0'. 4481 /// 4482 class OMPTargetTeamsDirective final : public OMPExecutableDirective { 4483 friend class ASTStmtReader; 4484 /// Build directive with the given start and end location. 4485 /// 4486 /// \param StartLoc Starting location of the directive kind. 4487 /// \param EndLoc Ending location of the directive. 4488 /// \param NumClauses Number of clauses. 4489 /// 4490 OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4491 unsigned NumClauses) 4492 : OMPExecutableDirective(this, OMPTargetTeamsDirectiveClass, 4493 llvm::omp::OMPD_target_teams, StartLoc, EndLoc, 4494 NumClauses, 1) {} 4495 4496 /// Build an empty directive. 4497 /// 4498 /// \param NumClauses Number of clauses. 4499 /// 4500 explicit OMPTargetTeamsDirective(unsigned NumClauses) 4501 : OMPExecutableDirective(this, OMPTargetTeamsDirectiveClass, 4502 llvm::omp::OMPD_target_teams, SourceLocation(), 4503 SourceLocation(), NumClauses, 1) {} 4504 4505 public: 4506 /// Creates directive with a list of \a Clauses. 4507 /// 4508 /// \param C AST context. 4509 /// \param StartLoc Starting location of the directive kind. 4510 /// \param EndLoc Ending Location of the directive. 4511 /// \param Clauses List of clauses. 4512 /// \param AssociatedStmt Statement, associated with the directive. 4513 /// 4514 static OMPTargetTeamsDirective *Create(const ASTContext &C, 4515 SourceLocation StartLoc, 4516 SourceLocation EndLoc, 4517 ArrayRef<OMPClause *> Clauses, 4518 Stmt *AssociatedStmt); 4519 4520 /// Creates an empty directive with the place for \a NumClauses clauses. 4521 /// 4522 /// \param C AST context. 4523 /// \param NumClauses Number of clauses. 4524 /// 4525 static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C, 4526 unsigned NumClauses, EmptyShell); 4527 4528 static bool classof(const Stmt *T) { 4529 return T->getStmtClass() == OMPTargetTeamsDirectiveClass; 4530 } 4531 }; 4532 4533 /// This represents '#pragma omp target teams distribute' combined directive. 4534 /// 4535 /// \code 4536 /// #pragma omp target teams distribute private(x) 4537 /// \endcode 4538 /// In this example directive '#pragma omp target teams distribute' has clause 4539 /// 'private' with the variables 'x' 4540 /// 4541 class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective { 4542 friend class ASTStmtReader; 4543 4544 /// Build directive with the given start and end location. 4545 /// 4546 /// \param StartLoc Starting location of the directive kind. 4547 /// \param EndLoc Ending location of the directive. 4548 /// \param CollapsedNum Number of collapsed nested loops. 4549 /// \param NumClauses Number of clauses. 4550 /// 4551 OMPTargetTeamsDistributeDirective(SourceLocation StartLoc, 4552 SourceLocation EndLoc, 4553 unsigned CollapsedNum, unsigned NumClauses) 4554 : OMPLoopDirective(this, OMPTargetTeamsDistributeDirectiveClass, 4555 llvm::omp::OMPD_target_teams_distribute, StartLoc, 4556 EndLoc, CollapsedNum, NumClauses) {} 4557 4558 /// Build an empty directive. 4559 /// 4560 /// \param CollapsedNum Number of collapsed nested loops. 4561 /// \param NumClauses Number of clauses. 4562 /// 4563 explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum, 4564 unsigned NumClauses) 4565 : OMPLoopDirective(this, OMPTargetTeamsDistributeDirectiveClass, 4566 llvm::omp::OMPD_target_teams_distribute, 4567 SourceLocation(), SourceLocation(), CollapsedNum, 4568 NumClauses) {} 4569 4570 public: 4571 /// Creates directive with a list of \a Clauses. 4572 /// 4573 /// \param C AST context. 4574 /// \param StartLoc Starting location of the directive kind. 4575 /// \param EndLoc Ending Location of the directive. 4576 /// \param CollapsedNum Number of collapsed loops. 4577 /// \param Clauses List of clauses. 4578 /// \param AssociatedStmt Statement, associated with the directive. 4579 /// \param Exprs Helper expressions for CodeGen. 4580 /// 4581 static OMPTargetTeamsDistributeDirective * 4582 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4583 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4584 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4585 4586 /// Creates an empty directive with the place for \a NumClauses clauses. 4587 /// 4588 /// \param C AST context. 4589 /// \param CollapsedNum Number of collapsed nested loops. 4590 /// \param NumClauses Number of clauses. 4591 /// 4592 static OMPTargetTeamsDistributeDirective * 4593 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4594 EmptyShell); 4595 4596 static bool classof(const Stmt *T) { 4597 return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass; 4598 } 4599 }; 4600 4601 /// This represents '#pragma omp target teams distribute parallel for' combined 4602 /// directive. 4603 /// 4604 /// \code 4605 /// #pragma omp target teams distribute parallel for private(x) 4606 /// \endcode 4607 /// In this example directive '#pragma omp target teams distribute parallel 4608 /// for' has clause 'private' with the variables 'x' 4609 /// 4610 class OMPTargetTeamsDistributeParallelForDirective final 4611 : public OMPLoopDirective { 4612 friend class ASTStmtReader; 4613 /// Special reference expression for handling task reduction. Used to store 4614 /// the taskgroup descriptor returned by the runtime functions. 4615 Expr *TaskRedRef = nullptr; 4616 /// true if the construct has inner cancel directive. 4617 bool HasCancel = false; 4618 4619 /// Build directive with the given start and end location. 4620 /// 4621 /// \param StartLoc Starting location of the directive kind. 4622 /// \param EndLoc Ending location of the directive. 4623 /// \param CollapsedNum Number of collapsed nested loops. 4624 /// \param NumClauses Number of clauses. 4625 /// 4626 OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc, 4627 SourceLocation EndLoc, 4628 unsigned CollapsedNum, 4629 unsigned NumClauses) 4630 : OMPLoopDirective(this, 4631 OMPTargetTeamsDistributeParallelForDirectiveClass, 4632 llvm::omp::OMPD_target_teams_distribute_parallel_for, 4633 StartLoc, EndLoc, CollapsedNum, NumClauses), 4634 HasCancel(false) {} 4635 4636 /// Build an empty directive. 4637 /// 4638 /// \param CollapsedNum Number of collapsed nested loops. 4639 /// \param NumClauses Number of clauses. 4640 /// 4641 explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum, 4642 unsigned NumClauses) 4643 : OMPLoopDirective( 4644 this, OMPTargetTeamsDistributeParallelForDirectiveClass, 4645 llvm::omp::OMPD_target_teams_distribute_parallel_for, 4646 SourceLocation(), SourceLocation(), CollapsedNum, NumClauses), 4647 HasCancel(false) {} 4648 4649 /// Sets special task reduction descriptor. 4650 void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } 4651 4652 /// Set cancel state. 4653 void setHasCancel(bool Has) { HasCancel = Has; } 4654 4655 public: 4656 /// Creates directive with a list of \a Clauses. 4657 /// 4658 /// \param C AST context. 4659 /// \param StartLoc Starting location of the directive kind. 4660 /// \param EndLoc Ending Location of the directive. 4661 /// \param CollapsedNum Number of collapsed loops. 4662 /// \param Clauses List of clauses. 4663 /// \param AssociatedStmt Statement, associated with the directive. 4664 /// \param Exprs Helper expressions for CodeGen. 4665 /// \param TaskRedRef Task reduction special reference expression to handle 4666 /// taskgroup descriptor. 4667 /// \param HasCancel true if this directive has inner cancel directive. 4668 /// 4669 static OMPTargetTeamsDistributeParallelForDirective * 4670 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4671 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4672 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 4673 bool HasCancel); 4674 4675 /// Creates an empty directive with the place for \a NumClauses clauses. 4676 /// 4677 /// \param C AST context. 4678 /// \param CollapsedNum Number of collapsed nested loops. 4679 /// \param NumClauses Number of clauses. 4680 /// 4681 static OMPTargetTeamsDistributeParallelForDirective * 4682 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4683 EmptyShell); 4684 4685 /// Returns special task reduction reference expression. 4686 Expr *getTaskReductionRefExpr() { return TaskRedRef; } 4687 const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } 4688 4689 /// Return true if current directive has inner cancel directive. 4690 bool hasCancel() const { return HasCancel; } 4691 4692 static bool classof(const Stmt *T) { 4693 return T->getStmtClass() == 4694 OMPTargetTeamsDistributeParallelForDirectiveClass; 4695 } 4696 }; 4697 4698 /// This represents '#pragma omp target teams distribute parallel for simd' 4699 /// combined directive. 4700 /// 4701 /// \code 4702 /// #pragma omp target teams distribute parallel for simd private(x) 4703 /// \endcode 4704 /// In this example directive '#pragma omp target teams distribute parallel 4705 /// for simd' has clause 'private' with the variables 'x' 4706 /// 4707 class OMPTargetTeamsDistributeParallelForSimdDirective final 4708 : public OMPLoopDirective { 4709 friend class ASTStmtReader; 4710 4711 /// Build directive with the given start and end location. 4712 /// 4713 /// \param StartLoc Starting location of the directive kind. 4714 /// \param EndLoc Ending location of the directive. 4715 /// \param CollapsedNum Number of collapsed nested loops. 4716 /// \param NumClauses Number of clauses. 4717 /// 4718 OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc, 4719 SourceLocation EndLoc, 4720 unsigned CollapsedNum, 4721 unsigned NumClauses) 4722 : OMPLoopDirective( 4723 this, OMPTargetTeamsDistributeParallelForSimdDirectiveClass, 4724 llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, StartLoc, 4725 EndLoc, CollapsedNum, NumClauses) {} 4726 4727 /// Build an empty directive. 4728 /// 4729 /// \param CollapsedNum Number of collapsed nested loops. 4730 /// \param NumClauses Number of clauses. 4731 /// 4732 explicit OMPTargetTeamsDistributeParallelForSimdDirective( 4733 unsigned CollapsedNum, unsigned NumClauses) 4734 : OMPLoopDirective( 4735 this, OMPTargetTeamsDistributeParallelForSimdDirectiveClass, 4736 llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, 4737 SourceLocation(), SourceLocation(), CollapsedNum, NumClauses) {} 4738 4739 public: 4740 /// Creates directive with a list of \a Clauses. 4741 /// 4742 /// \param C AST context. 4743 /// \param StartLoc Starting location of the directive kind. 4744 /// \param EndLoc Ending Location of the directive. 4745 /// \param CollapsedNum Number of collapsed loops. 4746 /// \param Clauses List of clauses. 4747 /// \param AssociatedStmt Statement, associated with the directive. 4748 /// \param Exprs Helper expressions for CodeGen. 4749 /// 4750 static OMPTargetTeamsDistributeParallelForSimdDirective * 4751 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4752 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4753 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4754 4755 /// Creates an empty directive with the place for \a NumClauses clauses. 4756 /// 4757 /// \param C AST context. 4758 /// \param CollapsedNum Number of collapsed nested loops. 4759 /// \param NumClauses Number of clauses. 4760 /// 4761 static OMPTargetTeamsDistributeParallelForSimdDirective * 4762 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4763 EmptyShell); 4764 4765 static bool classof(const Stmt *T) { 4766 return T->getStmtClass() == 4767 OMPTargetTeamsDistributeParallelForSimdDirectiveClass; 4768 } 4769 }; 4770 4771 /// This represents '#pragma omp target teams distribute simd' combined 4772 /// directive. 4773 /// 4774 /// \code 4775 /// #pragma omp target teams distribute simd private(x) 4776 /// \endcode 4777 /// In this example directive '#pragma omp target teams distribute simd' 4778 /// has clause 'private' with the variables 'x' 4779 /// 4780 class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective { 4781 friend class ASTStmtReader; 4782 4783 /// Build directive with the given start and end location. 4784 /// 4785 /// \param StartLoc Starting location of the directive kind. 4786 /// \param EndLoc Ending location of the directive. 4787 /// \param CollapsedNum Number of collapsed nested loops. 4788 /// \param NumClauses Number of clauses. 4789 /// 4790 OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc, 4791 SourceLocation EndLoc, 4792 unsigned CollapsedNum, 4793 unsigned NumClauses) 4794 : OMPLoopDirective(this, OMPTargetTeamsDistributeSimdDirectiveClass, 4795 llvm::omp::OMPD_target_teams_distribute_simd, StartLoc, 4796 EndLoc, CollapsedNum, NumClauses) {} 4797 4798 /// Build an empty directive. 4799 /// 4800 /// \param CollapsedNum Number of collapsed nested loops. 4801 /// \param NumClauses Number of clauses. 4802 /// 4803 explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum, 4804 unsigned NumClauses) 4805 : OMPLoopDirective(this, OMPTargetTeamsDistributeSimdDirectiveClass, 4806 llvm::omp::OMPD_target_teams_distribute_simd, 4807 SourceLocation(), SourceLocation(), CollapsedNum, 4808 NumClauses) {} 4809 4810 public: 4811 /// Creates directive with a list of \a Clauses. 4812 /// 4813 /// \param C AST context. 4814 /// \param StartLoc Starting location of the directive kind. 4815 /// \param EndLoc Ending Location of the directive. 4816 /// \param CollapsedNum Number of collapsed loops. 4817 /// \param Clauses List of clauses. 4818 /// \param AssociatedStmt Statement, associated with the directive. 4819 /// \param Exprs Helper expressions for CodeGen. 4820 /// 4821 static OMPTargetTeamsDistributeSimdDirective * 4822 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4823 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4824 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4825 4826 /// Creates an empty directive with the place for \a NumClauses clauses. 4827 /// 4828 /// \param C AST context. 4829 /// \param CollapsedNum Number of collapsed nested loops. 4830 /// \param NumClauses Number of clauses. 4831 /// 4832 static OMPTargetTeamsDistributeSimdDirective * 4833 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4834 EmptyShell); 4835 4836 static bool classof(const Stmt *T) { 4837 return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass; 4838 } 4839 }; 4840 4841 /// This represents '#pragma omp scan' directive. 4842 /// 4843 /// \code 4844 /// #pragma omp scan inclusive(a) 4845 /// \endcode 4846 /// In this example directive '#pragma omp scan' has clause 'inclusive' with 4847 /// list item 'a'. 4848 class OMPScanDirective final : public OMPExecutableDirective { 4849 friend class ASTStmtReader; 4850 /// Build directive with the given start and end location. 4851 /// 4852 /// \param StartLoc Starting location of the directive kind. 4853 /// \param EndLoc Ending location of the directive. 4854 /// \param NumClauses Number of clauses. 4855 /// 4856 OMPScanDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4857 unsigned NumClauses) 4858 : OMPExecutableDirective(this, OMPScanDirectiveClass, 4859 llvm::omp::OMPD_scan, StartLoc, EndLoc, 4860 NumClauses, 0) {} 4861 4862 /// Build an empty directive. 4863 /// 4864 /// \param NumClauses Number of clauses. 4865 /// 4866 explicit OMPScanDirective(unsigned NumClauses) 4867 : OMPExecutableDirective(this, OMPScanDirectiveClass, 4868 llvm::omp::OMPD_scan, SourceLocation(), 4869 SourceLocation(), NumClauses, 0) {} 4870 4871 public: 4872 /// Creates directive with a list of \a Clauses. 4873 /// 4874 /// \param C AST context. 4875 /// \param StartLoc Starting location of the directive kind. 4876 /// \param EndLoc Ending Location of the directive. 4877 /// \param Clauses List of clauses (only single OMPFlushClause clause is 4878 /// allowed). 4879 /// 4880 static OMPScanDirective *Create(const ASTContext &C, SourceLocation StartLoc, 4881 SourceLocation EndLoc, 4882 ArrayRef<OMPClause *> Clauses); 4883 4884 /// Creates an empty directive with the place for \a NumClauses 4885 /// clauses. 4886 /// 4887 /// \param C AST context. 4888 /// \param NumClauses Number of clauses. 4889 /// 4890 static OMPScanDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 4891 EmptyShell); 4892 4893 static bool classof(const Stmt *T) { 4894 return T->getStmtClass() == OMPScanDirectiveClass; 4895 } 4896 }; 4897 4898 } // end namespace clang 4899 4900 #endif 4901