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