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