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 uint8_t IsXLHSInRHSPart : 1; 2978 /// Used for 'atomic update' or 'atomic capture' constructs. They may 2979 /// have atomic expressions of forms: 2980 /// \code 2981 /// v = x; <update x>; 2982 /// <update x>; v = x; 2983 /// \endcode 2984 /// This field is 1 for the first(postfix) form of the expression and 0 2985 /// otherwise. 2986 uint8_t IsPostfixUpdate : 1; 2987 /// 1 if 'v' is updated only when the condition is false (compare capture 2988 /// only). 2989 uint8_t IsFailOnly : 1; 2990 } Flags; 2991 2992 /// Build directive with the given start and end location. 2993 /// 2994 /// \param StartLoc Starting location of the directive kind. 2995 /// \param EndLoc Ending location of the directive. 2996 /// OMPAtomicDirective(SourceLocation StartLoc,SourceLocation EndLoc)2997 OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc) 2998 : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic, 2999 StartLoc, EndLoc) {} 3000 3001 /// Build an empty directive. 3002 /// OMPAtomicDirective()3003 explicit OMPAtomicDirective() 3004 : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic, 3005 SourceLocation(), SourceLocation()) {} 3006 3007 enum DataPositionTy : size_t { 3008 POS_X = 0, 3009 POS_V, 3010 POS_E, 3011 POS_UpdateExpr, 3012 POS_D, 3013 POS_Cond, 3014 POS_R, 3015 }; 3016 3017 /// Set 'x' part of the associated expression/statement. setX(Expr * X)3018 void setX(Expr *X) { Data->getChildren()[DataPositionTy::POS_X] = X; } 3019 /// Set helper expression of the form 3020 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 3021 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. setUpdateExpr(Expr * UE)3022 void setUpdateExpr(Expr *UE) { 3023 Data->getChildren()[DataPositionTy::POS_UpdateExpr] = UE; 3024 } 3025 /// Set 'v' part of the associated expression/statement. setV(Expr * V)3026 void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; } 3027 /// Set 'r' part of the associated expression/statement. setR(Expr * R)3028 void setR(Expr *R) { Data->getChildren()[DataPositionTy::POS_R] = R; } 3029 /// Set 'expr' part of the associated expression/statement. setExpr(Expr * E)3030 void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; } 3031 /// Set 'd' part of the associated expression/statement. setD(Expr * D)3032 void setD(Expr *D) { Data->getChildren()[DataPositionTy::POS_D] = D; } 3033 /// Set conditional expression in `atomic compare`. setCond(Expr * C)3034 void setCond(Expr *C) { Data->getChildren()[DataPositionTy::POS_Cond] = C; } 3035 3036 public: 3037 struct Expressions { 3038 /// 'x' part of the associated expression/statement. 3039 Expr *X = nullptr; 3040 /// 'v' part of the associated expression/statement. 3041 Expr *V = nullptr; 3042 // 'r' part of the associated expression/statement. 3043 Expr *R = nullptr; 3044 /// 'expr' part of the associated expression/statement. 3045 Expr *E = nullptr; 3046 /// UE Helper expression of the form: 3047 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 3048 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 3049 Expr *UE = nullptr; 3050 /// 'd' part of the associated expression/statement. 3051 Expr *D = nullptr; 3052 /// Conditional expression in `atomic compare` construct. 3053 Expr *Cond = nullptr; 3054 /// True if UE has the first form and false if the second. 3055 bool IsXLHSInRHSPart; 3056 /// True if original value of 'x' must be stored in 'v', not an updated one. 3057 bool IsPostfixUpdate; 3058 /// True if 'v' is updated only when the condition is false (compare capture 3059 /// only). 3060 bool IsFailOnly; 3061 }; 3062 3063 /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr' 3064 /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for 3065 /// detailed description of 'x', 'v' and 'expr'). 3066 /// 3067 /// \param C AST context. 3068 /// \param StartLoc Starting location of the directive kind. 3069 /// \param EndLoc Ending Location of the directive. 3070 /// \param Clauses List of clauses. 3071 /// \param AssociatedStmt Statement, associated with the directive. 3072 /// \param Exprs Associated expressions or statements. 3073 static OMPAtomicDirective *Create(const ASTContext &C, 3074 SourceLocation StartLoc, 3075 SourceLocation EndLoc, 3076 ArrayRef<OMPClause *> Clauses, 3077 Stmt *AssociatedStmt, Expressions Exprs); 3078 3079 /// Creates an empty directive with the place for \a NumClauses 3080 /// clauses. 3081 /// 3082 /// \param C AST context. 3083 /// \param NumClauses Number of clauses. 3084 /// 3085 static OMPAtomicDirective *CreateEmpty(const ASTContext &C, 3086 unsigned NumClauses, EmptyShell); 3087 3088 /// Get 'x' part of the associated expression/statement. getX()3089 Expr *getX() { 3090 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]); 3091 } getX()3092 const Expr *getX() const { 3093 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]); 3094 } 3095 /// Get helper expression of the form 3096 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 3097 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. getUpdateExpr()3098 Expr *getUpdateExpr() { 3099 return cast_or_null<Expr>( 3100 Data->getChildren()[DataPositionTy::POS_UpdateExpr]); 3101 } getUpdateExpr()3102 const Expr *getUpdateExpr() const { 3103 return cast_or_null<Expr>( 3104 Data->getChildren()[DataPositionTy::POS_UpdateExpr]); 3105 } 3106 /// Return true if helper update expression has form 3107 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form 3108 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. isXLHSInRHSPart()3109 bool isXLHSInRHSPart() const { return Flags.IsXLHSInRHSPart; } 3110 /// Return true if 'v' expression must be updated to original value of 3111 /// 'x', false if 'v' must be updated to the new value of 'x'. isPostfixUpdate()3112 bool isPostfixUpdate() const { return Flags.IsPostfixUpdate; } 3113 /// Return true if 'v' is updated only when the condition is evaluated false 3114 /// (compare capture only). isFailOnly()3115 bool isFailOnly() const { return Flags.IsFailOnly; } 3116 /// Get 'v' part of the associated expression/statement. getV()3117 Expr *getV() { 3118 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]); 3119 } getV()3120 const Expr *getV() const { 3121 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]); 3122 } 3123 /// Get 'r' part of the associated expression/statement. getR()3124 Expr *getR() { 3125 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]); 3126 } getR()3127 const Expr *getR() const { 3128 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]); 3129 } 3130 /// Get 'expr' part of the associated expression/statement. getExpr()3131 Expr *getExpr() { 3132 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]); 3133 } getExpr()3134 const Expr *getExpr() const { 3135 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]); 3136 } 3137 /// Get 'd' part of the associated expression/statement. getD()3138 Expr *getD() { 3139 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]); 3140 } getD()3141 Expr *getD() const { 3142 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]); 3143 } 3144 /// Get the 'cond' part of the source atomic expression. getCondExpr()3145 Expr *getCondExpr() { 3146 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]); 3147 } getCondExpr()3148 Expr *getCondExpr() const { 3149 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]); 3150 } 3151 classof(const Stmt * T)3152 static bool classof(const Stmt *T) { 3153 return T->getStmtClass() == OMPAtomicDirectiveClass; 3154 } 3155 }; 3156 3157 /// This represents '#pragma omp target' directive. 3158 /// 3159 /// \code 3160 /// #pragma omp target if(a) 3161 /// \endcode 3162 /// In this example directive '#pragma omp target' has clause 'if' with 3163 /// condition 'a'. 3164 /// 3165 class OMPTargetDirective : public OMPExecutableDirective { 3166 friend class ASTStmtReader; 3167 friend class OMPExecutableDirective; 3168 /// Build directive with the given start and end location. 3169 /// 3170 /// \param StartLoc Starting location of the directive kind. 3171 /// \param EndLoc Ending location of the directive. 3172 /// OMPTargetDirective(SourceLocation StartLoc,SourceLocation EndLoc)3173 OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3174 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target, 3175 StartLoc, EndLoc) {} 3176 3177 /// Build an empty directive. 3178 /// OMPTargetDirective()3179 explicit OMPTargetDirective() 3180 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target, 3181 SourceLocation(), SourceLocation()) {} 3182 3183 public: 3184 /// Creates directive with a list of \a Clauses. 3185 /// 3186 /// \param C AST context. 3187 /// \param StartLoc Starting location of the directive kind. 3188 /// \param EndLoc Ending Location of the directive. 3189 /// \param Clauses List of clauses. 3190 /// \param AssociatedStmt Statement, associated with the directive. 3191 /// 3192 static OMPTargetDirective * 3193 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3194 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 3195 3196 /// Creates an empty directive with the place for \a NumClauses 3197 /// clauses. 3198 /// 3199 /// \param C AST context. 3200 /// \param NumClauses Number of clauses. 3201 /// 3202 static OMPTargetDirective *CreateEmpty(const ASTContext &C, 3203 unsigned NumClauses, EmptyShell); 3204 classof(const Stmt * T)3205 static bool classof(const Stmt *T) { 3206 return T->getStmtClass() == OMPTargetDirectiveClass; 3207 } 3208 }; 3209 3210 /// This represents '#pragma omp target data' directive. 3211 /// 3212 /// \code 3213 /// #pragma omp target data device(0) if(a) map(b[:]) 3214 /// \endcode 3215 /// In this example directive '#pragma omp target data' has clauses 'device' 3216 /// with the value '0', 'if' with condition 'a' and 'map' with array 3217 /// section 'b[:]'. 3218 /// 3219 class OMPTargetDataDirective : public OMPExecutableDirective { 3220 friend class ASTStmtReader; 3221 friend class OMPExecutableDirective; 3222 /// Build directive with the given start and end location. 3223 /// 3224 /// \param StartLoc Starting location of the directive kind. 3225 /// \param EndLoc Ending Location of the directive. 3226 /// OMPTargetDataDirective(SourceLocation StartLoc,SourceLocation EndLoc)3227 OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3228 : OMPExecutableDirective(OMPTargetDataDirectiveClass, 3229 llvm::omp::OMPD_target_data, StartLoc, EndLoc) {} 3230 3231 /// Build an empty directive. 3232 /// OMPTargetDataDirective()3233 explicit OMPTargetDataDirective() 3234 : OMPExecutableDirective(OMPTargetDataDirectiveClass, 3235 llvm::omp::OMPD_target_data, SourceLocation(), 3236 SourceLocation()) {} 3237 3238 public: 3239 /// Creates directive with a list of \a Clauses. 3240 /// 3241 /// \param C AST context. 3242 /// \param StartLoc Starting location of the directive kind. 3243 /// \param EndLoc Ending Location of the directive. 3244 /// \param Clauses List of clauses. 3245 /// \param AssociatedStmt Statement, associated with the directive. 3246 /// 3247 static OMPTargetDataDirective * 3248 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3249 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 3250 3251 /// Creates an empty directive with the place for \a N clauses. 3252 /// 3253 /// \param C AST context. 3254 /// \param N The number of clauses. 3255 /// 3256 static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N, 3257 EmptyShell); 3258 classof(const Stmt * T)3259 static bool classof(const Stmt *T) { 3260 return T->getStmtClass() == OMPTargetDataDirectiveClass; 3261 } 3262 }; 3263 3264 /// This represents '#pragma omp target enter data' directive. 3265 /// 3266 /// \code 3267 /// #pragma omp target enter data device(0) if(a) map(b[:]) 3268 /// \endcode 3269 /// In this example directive '#pragma omp target enter data' has clauses 3270 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array 3271 /// section 'b[:]'. 3272 /// 3273 class OMPTargetEnterDataDirective : public OMPExecutableDirective { 3274 friend class ASTStmtReader; 3275 friend class OMPExecutableDirective; 3276 /// Build directive with the given start and end location. 3277 /// 3278 /// \param StartLoc Starting location of the directive kind. 3279 /// \param EndLoc Ending Location of the directive. 3280 /// OMPTargetEnterDataDirective(SourceLocation StartLoc,SourceLocation EndLoc)3281 OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3282 : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass, 3283 llvm::omp::OMPD_target_enter_data, StartLoc, 3284 EndLoc) {} 3285 3286 /// Build an empty directive. 3287 /// OMPTargetEnterDataDirective()3288 explicit OMPTargetEnterDataDirective() 3289 : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass, 3290 llvm::omp::OMPD_target_enter_data, 3291 SourceLocation(), SourceLocation()) {} 3292 3293 public: 3294 /// Creates directive with a list of \a Clauses. 3295 /// 3296 /// \param C AST context. 3297 /// \param StartLoc Starting location of the directive kind. 3298 /// \param EndLoc Ending Location of the directive. 3299 /// \param Clauses List of clauses. 3300 /// \param AssociatedStmt Statement, associated with the directive. 3301 /// 3302 static OMPTargetEnterDataDirective * 3303 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3304 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 3305 3306 /// Creates an empty directive with the place for \a N clauses. 3307 /// 3308 /// \param C AST context. 3309 /// \param N The number of clauses. 3310 /// 3311 static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C, 3312 unsigned N, EmptyShell); 3313 classof(const Stmt * T)3314 static bool classof(const Stmt *T) { 3315 return T->getStmtClass() == OMPTargetEnterDataDirectiveClass; 3316 } 3317 }; 3318 3319 /// This represents '#pragma omp target exit data' directive. 3320 /// 3321 /// \code 3322 /// #pragma omp target exit data device(0) if(a) map(b[:]) 3323 /// \endcode 3324 /// In this example directive '#pragma omp target exit data' has clauses 3325 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array 3326 /// section 'b[:]'. 3327 /// 3328 class OMPTargetExitDataDirective : public OMPExecutableDirective { 3329 friend class ASTStmtReader; 3330 friend class OMPExecutableDirective; 3331 /// Build directive with the given start and end location. 3332 /// 3333 /// \param StartLoc Starting location of the directive kind. 3334 /// \param EndLoc Ending Location of the directive. 3335 /// OMPTargetExitDataDirective(SourceLocation StartLoc,SourceLocation EndLoc)3336 OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3337 : OMPExecutableDirective(OMPTargetExitDataDirectiveClass, 3338 llvm::omp::OMPD_target_exit_data, StartLoc, 3339 EndLoc) {} 3340 3341 /// Build an empty directive. 3342 /// OMPTargetExitDataDirective()3343 explicit OMPTargetExitDataDirective() 3344 : OMPExecutableDirective(OMPTargetExitDataDirectiveClass, 3345 llvm::omp::OMPD_target_exit_data, 3346 SourceLocation(), SourceLocation()) {} 3347 3348 public: 3349 /// Creates directive with a list of \a Clauses. 3350 /// 3351 /// \param C AST context. 3352 /// \param StartLoc Starting location of the directive kind. 3353 /// \param EndLoc Ending Location of the directive. 3354 /// \param Clauses List of clauses. 3355 /// \param AssociatedStmt Statement, associated with the directive. 3356 /// 3357 static OMPTargetExitDataDirective * 3358 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3359 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 3360 3361 /// Creates an empty directive with the place for \a N clauses. 3362 /// 3363 /// \param C AST context. 3364 /// \param N The number of clauses. 3365 /// 3366 static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C, 3367 unsigned N, EmptyShell); 3368 classof(const Stmt * T)3369 static bool classof(const Stmt *T) { 3370 return T->getStmtClass() == OMPTargetExitDataDirectiveClass; 3371 } 3372 }; 3373 3374 /// This represents '#pragma omp target parallel' directive. 3375 /// 3376 /// \code 3377 /// #pragma omp target parallel if(a) 3378 /// \endcode 3379 /// In this example directive '#pragma omp target parallel' has clause 'if' with 3380 /// condition 'a'. 3381 /// 3382 class OMPTargetParallelDirective : public OMPExecutableDirective { 3383 friend class ASTStmtReader; 3384 friend class OMPExecutableDirective; 3385 /// true if the construct has inner cancel directive. 3386 bool HasCancel = false; 3387 3388 /// Build directive with the given start and end location. 3389 /// 3390 /// \param StartLoc Starting location of the directive kind. 3391 /// \param EndLoc Ending location of the directive. 3392 /// OMPTargetParallelDirective(SourceLocation StartLoc,SourceLocation EndLoc)3393 OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3394 : OMPExecutableDirective(OMPTargetParallelDirectiveClass, 3395 llvm::omp::OMPD_target_parallel, StartLoc, 3396 EndLoc) {} 3397 3398 /// Build an empty directive. 3399 /// OMPTargetParallelDirective()3400 explicit OMPTargetParallelDirective() 3401 : OMPExecutableDirective(OMPTargetParallelDirectiveClass, 3402 llvm::omp::OMPD_target_parallel, 3403 SourceLocation(), SourceLocation()) {} 3404 3405 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)3406 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 3407 /// Set cancel state. setHasCancel(bool Has)3408 void setHasCancel(bool Has) { HasCancel = Has; } 3409 3410 public: 3411 /// Creates directive with a list of \a Clauses. 3412 /// 3413 /// \param C AST context. 3414 /// \param StartLoc Starting location of the directive kind. 3415 /// \param EndLoc Ending Location of the directive. 3416 /// \param Clauses List of clauses. 3417 /// \param AssociatedStmt Statement, associated with the directive. 3418 /// \param TaskRedRef Task reduction special reference expression to handle 3419 /// taskgroup descriptor. 3420 /// \param HasCancel true if this directive has inner cancel directive. 3421 /// 3422 static OMPTargetParallelDirective * 3423 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3424 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 3425 bool HasCancel); 3426 3427 /// Creates an empty directive with the place for \a NumClauses 3428 /// clauses. 3429 /// 3430 /// \param C AST context. 3431 /// \param NumClauses Number of clauses. 3432 /// 3433 static OMPTargetParallelDirective * 3434 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 3435 3436 /// Returns special task reduction reference expression. getTaskReductionRefExpr()3437 Expr *getTaskReductionRefExpr() { 3438 return cast_or_null<Expr>(Data->getChildren()[0]); 3439 } getTaskReductionRefExpr()3440 const Expr *getTaskReductionRefExpr() const { 3441 return const_cast<OMPTargetParallelDirective *>(this) 3442 ->getTaskReductionRefExpr(); 3443 } 3444 3445 /// Return true if current directive has inner cancel directive. hasCancel()3446 bool hasCancel() const { return HasCancel; } 3447 classof(const Stmt * T)3448 static bool classof(const Stmt *T) { 3449 return T->getStmtClass() == OMPTargetParallelDirectiveClass; 3450 } 3451 }; 3452 3453 /// This represents '#pragma omp target parallel for' directive. 3454 /// 3455 /// \code 3456 /// #pragma omp target parallel for private(a,b) reduction(+:c,d) 3457 /// \endcode 3458 /// In this example directive '#pragma omp target parallel for' has clauses 3459 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' 3460 /// and variables 'c' and 'd'. 3461 /// 3462 class OMPTargetParallelForDirective : public OMPLoopDirective { 3463 friend class ASTStmtReader; 3464 friend class OMPExecutableDirective; 3465 3466 /// true if current region has inner cancel directive. 3467 bool HasCancel = false; 3468 3469 /// Build directive with the given start and end location. 3470 /// 3471 /// \param StartLoc Starting location of the directive kind. 3472 /// \param EndLoc Ending location of the directive. 3473 /// \param CollapsedNum Number of collapsed nested loops. 3474 /// OMPTargetParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)3475 OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3476 unsigned CollapsedNum) 3477 : OMPLoopDirective(OMPTargetParallelForDirectiveClass, 3478 llvm::omp::OMPD_target_parallel_for, StartLoc, EndLoc, 3479 CollapsedNum) {} 3480 3481 /// Build an empty directive. 3482 /// 3483 /// \param CollapsedNum Number of collapsed nested loops. 3484 /// OMPTargetParallelForDirective(unsigned CollapsedNum)3485 explicit OMPTargetParallelForDirective(unsigned CollapsedNum) 3486 : OMPLoopDirective(OMPTargetParallelForDirectiveClass, 3487 llvm::omp::OMPD_target_parallel_for, SourceLocation(), 3488 SourceLocation(), CollapsedNum) {} 3489 3490 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)3491 void setTaskReductionRefExpr(Expr *E) { 3492 Data->getChildren()[numLoopChildren( 3493 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)] = E; 3494 } 3495 3496 /// Set cancel state. setHasCancel(bool Has)3497 void setHasCancel(bool Has) { HasCancel = Has; } 3498 3499 public: 3500 /// Creates directive with a list of \a Clauses. 3501 /// 3502 /// \param C AST context. 3503 /// \param StartLoc Starting location of the directive kind. 3504 /// \param EndLoc Ending Location of the directive. 3505 /// \param CollapsedNum Number of collapsed loops. 3506 /// \param Clauses List of clauses. 3507 /// \param AssociatedStmt Statement, associated with the directive. 3508 /// \param Exprs Helper expressions for CodeGen. 3509 /// \param TaskRedRef Task reduction special reference expression to handle 3510 /// taskgroup descriptor. 3511 /// \param HasCancel true if current directive has inner cancel directive. 3512 /// 3513 static OMPTargetParallelForDirective * 3514 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3515 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3516 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 3517 bool HasCancel); 3518 3519 /// Creates an empty directive with the place 3520 /// for \a NumClauses clauses. 3521 /// 3522 /// \param C AST context. 3523 /// \param CollapsedNum Number of collapsed nested loops. 3524 /// \param NumClauses Number of clauses. 3525 /// 3526 static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C, 3527 unsigned NumClauses, 3528 unsigned CollapsedNum, 3529 EmptyShell); 3530 3531 /// Returns special task reduction reference expression. getTaskReductionRefExpr()3532 Expr *getTaskReductionRefExpr() { 3533 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 3534 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)]); 3535 } getTaskReductionRefExpr()3536 const Expr *getTaskReductionRefExpr() const { 3537 return const_cast<OMPTargetParallelForDirective *>(this) 3538 ->getTaskReductionRefExpr(); 3539 } 3540 3541 /// Return true if current directive has inner cancel directive. hasCancel()3542 bool hasCancel() const { return HasCancel; } 3543 classof(const Stmt * T)3544 static bool classof(const Stmt *T) { 3545 return T->getStmtClass() == OMPTargetParallelForDirectiveClass; 3546 } 3547 }; 3548 3549 /// This represents '#pragma omp teams' directive. 3550 /// 3551 /// \code 3552 /// #pragma omp teams if(a) 3553 /// \endcode 3554 /// In this example directive '#pragma omp teams' has clause 'if' with 3555 /// condition 'a'. 3556 /// 3557 class OMPTeamsDirective : public OMPExecutableDirective { 3558 friend class ASTStmtReader; 3559 friend class OMPExecutableDirective; 3560 /// Build directive with the given start and end location. 3561 /// 3562 /// \param StartLoc Starting location of the directive kind. 3563 /// \param EndLoc Ending location of the directive. 3564 /// OMPTeamsDirective(SourceLocation StartLoc,SourceLocation EndLoc)3565 OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3566 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams, 3567 StartLoc, EndLoc) {} 3568 3569 /// Build an empty directive. 3570 /// OMPTeamsDirective()3571 explicit OMPTeamsDirective() 3572 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams, 3573 SourceLocation(), SourceLocation()) {} 3574 3575 public: 3576 /// Creates directive with a list of \a Clauses. 3577 /// 3578 /// \param C AST context. 3579 /// \param StartLoc Starting location of the directive kind. 3580 /// \param EndLoc Ending Location of the directive. 3581 /// \param Clauses List of clauses. 3582 /// \param AssociatedStmt Statement, associated with the directive. 3583 /// 3584 static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc, 3585 SourceLocation EndLoc, 3586 ArrayRef<OMPClause *> Clauses, 3587 Stmt *AssociatedStmt); 3588 3589 /// Creates an empty directive with the place for \a NumClauses 3590 /// clauses. 3591 /// 3592 /// \param C AST context. 3593 /// \param NumClauses Number of clauses. 3594 /// 3595 static OMPTeamsDirective *CreateEmpty(const ASTContext &C, 3596 unsigned NumClauses, EmptyShell); 3597 classof(const Stmt * T)3598 static bool classof(const Stmt *T) { 3599 return T->getStmtClass() == OMPTeamsDirectiveClass; 3600 } 3601 }; 3602 3603 /// This represents '#pragma omp cancellation point' directive. 3604 /// 3605 /// \code 3606 /// #pragma omp cancellation point for 3607 /// \endcode 3608 /// 3609 /// In this example a cancellation point is created for innermost 'for' region. 3610 class OMPCancellationPointDirective : public OMPExecutableDirective { 3611 friend class ASTStmtReader; 3612 friend class OMPExecutableDirective; 3613 OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown; 3614 /// Build directive with the given start and end location. 3615 /// 3616 /// \param StartLoc Starting location of the directive kind. 3617 /// \param EndLoc Ending location of the directive. 3618 /// statements and child expressions. 3619 /// OMPCancellationPointDirective(SourceLocation StartLoc,SourceLocation EndLoc)3620 OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3621 : OMPExecutableDirective(OMPCancellationPointDirectiveClass, 3622 llvm::omp::OMPD_cancellation_point, StartLoc, 3623 EndLoc) {} 3624 3625 /// Build an empty directive. OMPCancellationPointDirective()3626 explicit OMPCancellationPointDirective() 3627 : OMPExecutableDirective(OMPCancellationPointDirectiveClass, 3628 llvm::omp::OMPD_cancellation_point, 3629 SourceLocation(), SourceLocation()) {} 3630 3631 /// Set cancel region for current cancellation point. 3632 /// \param CR Cancellation region. setCancelRegion(OpenMPDirectiveKind CR)3633 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } 3634 3635 public: 3636 /// Creates directive. 3637 /// 3638 /// \param C AST context. 3639 /// \param StartLoc Starting location of the directive kind. 3640 /// \param EndLoc Ending Location of the directive. 3641 /// 3642 static OMPCancellationPointDirective * 3643 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3644 OpenMPDirectiveKind CancelRegion); 3645 3646 /// Creates an empty directive. 3647 /// 3648 /// \param C AST context. 3649 /// 3650 static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C, 3651 EmptyShell); 3652 3653 /// Get cancellation region for the current cancellation point. getCancelRegion()3654 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } 3655 classof(const Stmt * T)3656 static bool classof(const Stmt *T) { 3657 return T->getStmtClass() == OMPCancellationPointDirectiveClass; 3658 } 3659 }; 3660 3661 /// This represents '#pragma omp cancel' directive. 3662 /// 3663 /// \code 3664 /// #pragma omp cancel for 3665 /// \endcode 3666 /// 3667 /// In this example a cancel is created for innermost 'for' region. 3668 class OMPCancelDirective : public OMPExecutableDirective { 3669 friend class ASTStmtReader; 3670 friend class OMPExecutableDirective; 3671 OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown; 3672 /// Build directive with the given start and end location. 3673 /// 3674 /// \param StartLoc Starting location of the directive kind. 3675 /// \param EndLoc Ending location of the directive. 3676 /// OMPCancelDirective(SourceLocation StartLoc,SourceLocation EndLoc)3677 OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc) 3678 : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel, 3679 StartLoc, EndLoc) {} 3680 3681 /// Build an empty directive. 3682 /// OMPCancelDirective()3683 explicit OMPCancelDirective() 3684 : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel, 3685 SourceLocation(), SourceLocation()) {} 3686 3687 /// Set cancel region for current cancellation point. 3688 /// \param CR Cancellation region. setCancelRegion(OpenMPDirectiveKind CR)3689 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } 3690 3691 public: 3692 /// Creates directive. 3693 /// 3694 /// \param C AST context. 3695 /// \param StartLoc Starting location of the directive kind. 3696 /// \param EndLoc Ending Location of the directive. 3697 /// \param Clauses List of clauses. 3698 /// 3699 static OMPCancelDirective * 3700 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3701 ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion); 3702 3703 /// Creates an empty directive. 3704 /// 3705 /// \param C AST context. 3706 /// \param NumClauses Number of clauses. 3707 /// 3708 static OMPCancelDirective *CreateEmpty(const ASTContext &C, 3709 unsigned NumClauses, EmptyShell); 3710 3711 /// Get cancellation region for the current cancellation point. getCancelRegion()3712 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } 3713 classof(const Stmt * T)3714 static bool classof(const Stmt *T) { 3715 return T->getStmtClass() == OMPCancelDirectiveClass; 3716 } 3717 }; 3718 3719 /// This represents '#pragma omp taskloop' directive. 3720 /// 3721 /// \code 3722 /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num) 3723 /// \endcode 3724 /// In this example directive '#pragma omp taskloop' has clauses 'private' 3725 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and 3726 /// 'num_tasks' with expression 'num'. 3727 /// 3728 class OMPTaskLoopDirective : public OMPLoopDirective { 3729 friend class ASTStmtReader; 3730 friend class OMPExecutableDirective; 3731 /// true if the construct has inner cancel directive. 3732 bool HasCancel = false; 3733 3734 /// Build directive with the given start and end location. 3735 /// 3736 /// \param StartLoc Starting location of the directive kind. 3737 /// \param EndLoc Ending location of the directive. 3738 /// \param CollapsedNum Number of collapsed nested loops. 3739 /// OMPTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)3740 OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3741 unsigned CollapsedNum) 3742 : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop, 3743 StartLoc, EndLoc, CollapsedNum) {} 3744 3745 /// Build an empty directive. 3746 /// 3747 /// \param CollapsedNum Number of collapsed nested loops. 3748 /// OMPTaskLoopDirective(unsigned CollapsedNum)3749 explicit OMPTaskLoopDirective(unsigned CollapsedNum) 3750 : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop, 3751 SourceLocation(), SourceLocation(), CollapsedNum) {} 3752 3753 /// Set cancel state. setHasCancel(bool Has)3754 void setHasCancel(bool Has) { HasCancel = Has; } 3755 3756 public: 3757 /// Creates directive with a list of \a Clauses. 3758 /// 3759 /// \param C AST context. 3760 /// \param StartLoc Starting location of the directive kind. 3761 /// \param EndLoc Ending Location of the directive. 3762 /// \param CollapsedNum Number of collapsed loops. 3763 /// \param Clauses List of clauses. 3764 /// \param AssociatedStmt Statement, associated with the directive. 3765 /// \param Exprs Helper expressions for CodeGen. 3766 /// \param HasCancel true if this directive has inner cancel directive. 3767 /// 3768 static OMPTaskLoopDirective * 3769 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3770 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3771 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 3772 3773 /// Creates an empty directive with the place 3774 /// for \a NumClauses clauses. 3775 /// 3776 /// \param C AST context. 3777 /// \param CollapsedNum Number of collapsed nested loops. 3778 /// \param NumClauses Number of clauses. 3779 /// 3780 static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C, 3781 unsigned NumClauses, 3782 unsigned CollapsedNum, EmptyShell); 3783 3784 /// Return true if current directive has inner cancel directive. hasCancel()3785 bool hasCancel() const { return HasCancel; } 3786 classof(const Stmt * T)3787 static bool classof(const Stmt *T) { 3788 return T->getStmtClass() == OMPTaskLoopDirectiveClass; 3789 } 3790 }; 3791 3792 /// This represents '#pragma omp taskloop simd' directive. 3793 /// 3794 /// \code 3795 /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num) 3796 /// \endcode 3797 /// In this example directive '#pragma omp taskloop simd' has clauses 'private' 3798 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and 3799 /// 'num_tasks' with expression 'num'. 3800 /// 3801 class OMPTaskLoopSimdDirective : public OMPLoopDirective { 3802 friend class ASTStmtReader; 3803 friend class OMPExecutableDirective; 3804 /// Build directive with the given start and end location. 3805 /// 3806 /// \param StartLoc Starting location of the directive kind. 3807 /// \param EndLoc Ending location of the directive. 3808 /// \param CollapsedNum Number of collapsed nested loops. 3809 /// OMPTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)3810 OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3811 unsigned CollapsedNum) 3812 : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass, 3813 llvm::omp::OMPD_taskloop_simd, StartLoc, EndLoc, 3814 CollapsedNum) {} 3815 3816 /// Build an empty directive. 3817 /// 3818 /// \param CollapsedNum Number of collapsed nested loops. 3819 /// OMPTaskLoopSimdDirective(unsigned CollapsedNum)3820 explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum) 3821 : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass, 3822 llvm::omp::OMPD_taskloop_simd, SourceLocation(), 3823 SourceLocation(), CollapsedNum) {} 3824 3825 public: 3826 /// Creates directive with a list of \a Clauses. 3827 /// 3828 /// \param C AST context. 3829 /// \param StartLoc Starting location of the directive kind. 3830 /// \param EndLoc Ending Location of the directive. 3831 /// \param CollapsedNum Number of collapsed loops. 3832 /// \param Clauses List of clauses. 3833 /// \param AssociatedStmt Statement, associated with the directive. 3834 /// \param Exprs Helper expressions for CodeGen. 3835 /// 3836 static OMPTaskLoopSimdDirective * 3837 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3838 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3839 Stmt *AssociatedStmt, const HelperExprs &Exprs); 3840 3841 /// Creates an empty directive with the place 3842 /// for \a NumClauses clauses. 3843 /// 3844 /// \param C AST context. 3845 /// \param CollapsedNum Number of collapsed nested loops. 3846 /// \param NumClauses Number of clauses. 3847 /// 3848 static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, 3849 unsigned NumClauses, 3850 unsigned CollapsedNum, 3851 EmptyShell); 3852 classof(const Stmt * T)3853 static bool classof(const Stmt *T) { 3854 return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass; 3855 } 3856 }; 3857 3858 /// This represents '#pragma omp master taskloop' directive. 3859 /// 3860 /// \code 3861 /// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num) 3862 /// \endcode 3863 /// In this example directive '#pragma omp master taskloop' has clauses 3864 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 3865 /// and 'num_tasks' with expression 'num'. 3866 /// 3867 class OMPMasterTaskLoopDirective : public OMPLoopDirective { 3868 friend class ASTStmtReader; 3869 friend class OMPExecutableDirective; 3870 /// true if the construct has inner cancel directive. 3871 bool HasCancel = false; 3872 3873 /// Build directive with the given start and end location. 3874 /// 3875 /// \param StartLoc Starting location of the directive kind. 3876 /// \param EndLoc Ending location of the directive. 3877 /// \param CollapsedNum Number of collapsed nested loops. 3878 /// OMPMasterTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)3879 OMPMasterTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3880 unsigned CollapsedNum) 3881 : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass, 3882 llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc, 3883 CollapsedNum) {} 3884 3885 /// Build an empty directive. 3886 /// 3887 /// \param CollapsedNum Number of collapsed nested loops. 3888 /// OMPMasterTaskLoopDirective(unsigned CollapsedNum)3889 explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum) 3890 : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass, 3891 llvm::omp::OMPD_master_taskloop, SourceLocation(), 3892 SourceLocation(), CollapsedNum) {} 3893 3894 /// Set cancel state. setHasCancel(bool Has)3895 void setHasCancel(bool Has) { HasCancel = Has; } 3896 3897 public: 3898 /// Creates directive with a list of \a Clauses. 3899 /// 3900 /// \param C AST context. 3901 /// \param StartLoc Starting location of the directive kind. 3902 /// \param EndLoc Ending Location of the directive. 3903 /// \param CollapsedNum Number of collapsed loops. 3904 /// \param Clauses List of clauses. 3905 /// \param AssociatedStmt Statement, associated with the directive. 3906 /// \param Exprs Helper expressions for CodeGen. 3907 /// \param HasCancel true if this directive has inner cancel directive. 3908 /// 3909 static OMPMasterTaskLoopDirective * 3910 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3911 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3912 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 3913 3914 /// Creates an empty directive with the place 3915 /// for \a NumClauses clauses. 3916 /// 3917 /// \param C AST context. 3918 /// \param CollapsedNum Number of collapsed nested loops. 3919 /// \param NumClauses Number of clauses. 3920 /// 3921 static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C, 3922 unsigned NumClauses, 3923 unsigned CollapsedNum, 3924 EmptyShell); 3925 3926 /// Return true if current directive has inner cancel directive. hasCancel()3927 bool hasCancel() const { return HasCancel; } 3928 classof(const Stmt * T)3929 static bool classof(const Stmt *T) { 3930 return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass; 3931 } 3932 }; 3933 3934 /// This represents '#pragma omp masked taskloop' directive. 3935 /// 3936 /// \code 3937 /// #pragma omp masked taskloop private(a,b) grainsize(val) num_tasks(num) 3938 /// \endcode 3939 /// In this example directive '#pragma omp masked taskloop' has clauses 3940 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 3941 /// and 'num_tasks' with expression 'num'. 3942 /// 3943 class OMPMaskedTaskLoopDirective final : public OMPLoopDirective { 3944 friend class ASTStmtReader; 3945 friend class OMPExecutableDirective; 3946 /// true if the construct has inner cancel directive. 3947 bool HasCancel = false; 3948 3949 /// Build directive with the given start and end location. 3950 /// 3951 /// \param StartLoc Starting location of the directive kind. 3952 /// \param EndLoc Ending location of the directive. 3953 /// \param CollapsedNum Number of collapsed nested loops. 3954 /// OMPMaskedTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)3955 OMPMaskedTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 3956 unsigned CollapsedNum) 3957 : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass, 3958 llvm::omp::OMPD_masked_taskloop, StartLoc, EndLoc, 3959 CollapsedNum) {} 3960 3961 /// Build an empty directive. 3962 /// 3963 /// \param CollapsedNum Number of collapsed nested loops. 3964 /// OMPMaskedTaskLoopDirective(unsigned CollapsedNum)3965 explicit OMPMaskedTaskLoopDirective(unsigned CollapsedNum) 3966 : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass, 3967 llvm::omp::OMPD_masked_taskloop, SourceLocation(), 3968 SourceLocation(), CollapsedNum) {} 3969 3970 /// Set cancel state. setHasCancel(bool Has)3971 void setHasCancel(bool Has) { HasCancel = Has; } 3972 3973 public: 3974 /// Creates directive with a list of \a Clauses. 3975 /// 3976 /// \param C AST context. 3977 /// \param StartLoc Starting location of the directive kind. 3978 /// \param EndLoc Ending Location of the directive. 3979 /// \param CollapsedNum Number of collapsed loops. 3980 /// \param Clauses List of clauses. 3981 /// \param AssociatedStmt Statement, associated with the directive. 3982 /// \param Exprs Helper expressions for CodeGen. 3983 /// \param HasCancel true if this directive has inner cancel directive. 3984 /// 3985 static OMPMaskedTaskLoopDirective * 3986 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 3987 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 3988 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 3989 3990 /// Creates an empty directive with the place 3991 /// for \a NumClauses clauses. 3992 /// 3993 /// \param C AST context. 3994 /// \param CollapsedNum Number of collapsed nested loops. 3995 /// \param NumClauses Number of clauses. 3996 /// 3997 static OMPMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C, 3998 unsigned NumClauses, 3999 unsigned CollapsedNum, 4000 EmptyShell); 4001 4002 /// Return true if current directive has inner cancel directive. hasCancel()4003 bool hasCancel() const { return HasCancel; } 4004 classof(const Stmt * T)4005 static bool classof(const Stmt *T) { 4006 return T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass; 4007 } 4008 }; 4009 4010 /// This represents '#pragma omp master taskloop simd' directive. 4011 /// 4012 /// \code 4013 /// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num) 4014 /// \endcode 4015 /// In this example directive '#pragma omp master taskloop simd' has clauses 4016 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 4017 /// and 'num_tasks' with expression 'num'. 4018 /// 4019 class OMPMasterTaskLoopSimdDirective : public OMPLoopDirective { 4020 friend class ASTStmtReader; 4021 friend class OMPExecutableDirective; 4022 /// Build directive with the given start and end location. 4023 /// 4024 /// \param StartLoc Starting location of the directive kind. 4025 /// \param EndLoc Ending location of the directive. 4026 /// \param CollapsedNum Number of collapsed nested loops. 4027 /// OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4028 OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4029 unsigned CollapsedNum) 4030 : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass, 4031 llvm::omp::OMPD_master_taskloop_simd, StartLoc, EndLoc, 4032 CollapsedNum) {} 4033 4034 /// Build an empty directive. 4035 /// 4036 /// \param CollapsedNum Number of collapsed nested loops. 4037 /// OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum)4038 explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum) 4039 : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass, 4040 llvm::omp::OMPD_master_taskloop_simd, SourceLocation(), 4041 SourceLocation(), CollapsedNum) {} 4042 4043 public: 4044 /// Creates directive with a list of \p Clauses. 4045 /// 4046 /// \param C AST context. 4047 /// \param StartLoc Starting location of the directive kind. 4048 /// \param EndLoc Ending Location of the directive. 4049 /// \param CollapsedNum Number of collapsed loops. 4050 /// \param Clauses List of clauses. 4051 /// \param AssociatedStmt Statement, associated with the directive. 4052 /// \param Exprs Helper expressions for CodeGen. 4053 /// 4054 static OMPMasterTaskLoopSimdDirective * 4055 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4056 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4057 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4058 4059 /// Creates an empty directive with the place for \p NumClauses clauses. 4060 /// 4061 /// \param C AST context. 4062 /// \param CollapsedNum Number of collapsed nested loops. 4063 /// \param NumClauses Number of clauses. 4064 /// 4065 static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, 4066 unsigned NumClauses, 4067 unsigned CollapsedNum, 4068 EmptyShell); 4069 classof(const Stmt * T)4070 static bool classof(const Stmt *T) { 4071 return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass; 4072 } 4073 }; 4074 4075 /// This represents '#pragma omp masked taskloop simd' directive. 4076 /// 4077 /// \code 4078 /// #pragma omp masked taskloop simd private(a,b) grainsize(val) num_tasks(num) 4079 /// \endcode 4080 /// In this example directive '#pragma omp masked taskloop simd' has clauses 4081 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 4082 /// and 'num_tasks' with expression 'num'. 4083 /// 4084 class OMPMaskedTaskLoopSimdDirective final : public OMPLoopDirective { 4085 friend class ASTStmtReader; 4086 friend class OMPExecutableDirective; 4087 /// Build directive with the given start and end location. 4088 /// 4089 /// \param StartLoc Starting location of the directive kind. 4090 /// \param EndLoc Ending location of the directive. 4091 /// \param CollapsedNum Number of collapsed nested loops. 4092 /// OMPMaskedTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4093 OMPMaskedTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4094 unsigned CollapsedNum) 4095 : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass, 4096 llvm::omp::OMPD_masked_taskloop_simd, StartLoc, EndLoc, 4097 CollapsedNum) {} 4098 4099 /// Build an empty directive. 4100 /// 4101 /// \param CollapsedNum Number of collapsed nested loops. 4102 /// OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum)4103 explicit OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum) 4104 : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass, 4105 llvm::omp::OMPD_masked_taskloop_simd, SourceLocation(), 4106 SourceLocation(), CollapsedNum) {} 4107 4108 public: 4109 /// Creates directive with a list of \p Clauses. 4110 /// 4111 /// \param C AST context. 4112 /// \param StartLoc Starting location of the directive kind. 4113 /// \param EndLoc Ending Location of the directive. 4114 /// \param CollapsedNum Number of collapsed loops. 4115 /// \param Clauses List of clauses. 4116 /// \param AssociatedStmt Statement, associated with the directive. 4117 /// \param Exprs Helper expressions for CodeGen. 4118 /// 4119 static OMPMaskedTaskLoopSimdDirective * 4120 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4121 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4122 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4123 4124 /// Creates an empty directive with the place for \p NumClauses clauses. 4125 /// 4126 /// \param C AST context. 4127 /// \param CollapsedNum Number of collapsed nested loops. 4128 /// \param NumClauses Number of clauses. 4129 /// 4130 static OMPMaskedTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, 4131 unsigned NumClauses, 4132 unsigned CollapsedNum, 4133 EmptyShell); 4134 classof(const Stmt * T)4135 static bool classof(const Stmt *T) { 4136 return T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass; 4137 } 4138 }; 4139 4140 /// This represents '#pragma omp parallel master taskloop' directive. 4141 /// 4142 /// \code 4143 /// #pragma omp parallel master taskloop private(a,b) grainsize(val) 4144 /// num_tasks(num) 4145 /// \endcode 4146 /// In this example directive '#pragma omp parallel master taskloop' has clauses 4147 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 4148 /// and 'num_tasks' with expression 'num'. 4149 /// 4150 class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective { 4151 friend class ASTStmtReader; 4152 friend class OMPExecutableDirective; 4153 /// true if the construct has inner cancel directive. 4154 bool HasCancel = false; 4155 4156 /// Build directive with the given start and end location. 4157 /// 4158 /// \param StartLoc Starting location of the directive kind. 4159 /// \param EndLoc Ending location of the directive. 4160 /// \param CollapsedNum Number of collapsed nested loops. 4161 /// OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4162 OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc, 4163 SourceLocation EndLoc, 4164 unsigned CollapsedNum) 4165 : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass, 4166 llvm::omp::OMPD_parallel_master_taskloop, StartLoc, 4167 EndLoc, CollapsedNum) {} 4168 4169 /// Build an empty directive. 4170 /// 4171 /// \param CollapsedNum Number of collapsed nested loops. 4172 /// OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum)4173 explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum) 4174 : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass, 4175 llvm::omp::OMPD_parallel_master_taskloop, 4176 SourceLocation(), SourceLocation(), CollapsedNum) {} 4177 4178 /// Set cancel state. setHasCancel(bool Has)4179 void setHasCancel(bool Has) { HasCancel = Has; } 4180 4181 public: 4182 /// Creates directive with a list of \a Clauses. 4183 /// 4184 /// \param C AST context. 4185 /// \param StartLoc Starting location of the directive kind. 4186 /// \param EndLoc Ending Location of the directive. 4187 /// \param CollapsedNum Number of collapsed loops. 4188 /// \param Clauses List of clauses. 4189 /// \param AssociatedStmt Statement, associated with the directive. 4190 /// \param Exprs Helper expressions for CodeGen. 4191 /// \param HasCancel true if this directive has inner cancel directive. 4192 /// 4193 static OMPParallelMasterTaskLoopDirective * 4194 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4195 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4196 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 4197 4198 /// Creates an empty directive with the place 4199 /// for \a NumClauses clauses. 4200 /// 4201 /// \param C AST context. 4202 /// \param CollapsedNum Number of collapsed nested loops. 4203 /// \param NumClauses Number of clauses. 4204 /// 4205 static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C, 4206 unsigned NumClauses, 4207 unsigned CollapsedNum, 4208 EmptyShell); 4209 4210 /// Return true if current directive has inner cancel directive. hasCancel()4211 bool hasCancel() const { return HasCancel; } 4212 classof(const Stmt * T)4213 static bool classof(const Stmt *T) { 4214 return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass; 4215 } 4216 }; 4217 4218 /// This represents '#pragma omp parallel masked taskloop' directive. 4219 /// 4220 /// \code 4221 /// #pragma omp parallel masked taskloop private(a,b) grainsize(val) 4222 /// num_tasks(num) 4223 /// \endcode 4224 /// In this example directive '#pragma omp parallel masked taskloop' has clauses 4225 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 4226 /// and 'num_tasks' with expression 'num'. 4227 /// 4228 class OMPParallelMaskedTaskLoopDirective final : public OMPLoopDirective { 4229 friend class ASTStmtReader; 4230 friend class OMPExecutableDirective; 4231 /// true if the construct has inner cancel directive. 4232 bool HasCancel = false; 4233 4234 /// Build directive with the given start and end location. 4235 /// 4236 /// \param StartLoc Starting location of the directive kind. 4237 /// \param EndLoc Ending location of the directive. 4238 /// \param CollapsedNum Number of collapsed nested loops. 4239 /// OMPParallelMaskedTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4240 OMPParallelMaskedTaskLoopDirective(SourceLocation StartLoc, 4241 SourceLocation EndLoc, 4242 unsigned CollapsedNum) 4243 : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass, 4244 llvm::omp::OMPD_parallel_masked_taskloop, StartLoc, 4245 EndLoc, CollapsedNum) {} 4246 4247 /// Build an empty directive. 4248 /// 4249 /// \param CollapsedNum Number of collapsed nested loops. 4250 /// OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum)4251 explicit OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum) 4252 : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass, 4253 llvm::omp::OMPD_parallel_masked_taskloop, 4254 SourceLocation(), SourceLocation(), CollapsedNum) {} 4255 4256 /// Set cancel state. setHasCancel(bool Has)4257 void setHasCancel(bool Has) { HasCancel = Has; } 4258 4259 public: 4260 /// Creates directive with a list of \a Clauses. 4261 /// 4262 /// \param C AST context. 4263 /// \param StartLoc Starting location of the directive kind. 4264 /// \param EndLoc Ending Location of the directive. 4265 /// \param CollapsedNum Number of collapsed loops. 4266 /// \param Clauses List of clauses. 4267 /// \param AssociatedStmt Statement, associated with the directive. 4268 /// \param Exprs Helper expressions for CodeGen. 4269 /// \param HasCancel true if this directive has inner cancel directive. 4270 /// 4271 static OMPParallelMaskedTaskLoopDirective * 4272 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4273 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4274 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 4275 4276 /// Creates an empty directive with the place 4277 /// for \a NumClauses clauses. 4278 /// 4279 /// \param C AST context. 4280 /// \param CollapsedNum Number of collapsed nested loops. 4281 /// \param NumClauses Number of clauses. 4282 /// 4283 static OMPParallelMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C, 4284 unsigned NumClauses, 4285 unsigned CollapsedNum, 4286 EmptyShell); 4287 4288 /// Return true if current directive has inner cancel directive. hasCancel()4289 bool hasCancel() const { return HasCancel; } 4290 classof(const Stmt * T)4291 static bool classof(const Stmt *T) { 4292 return T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass; 4293 } 4294 }; 4295 4296 /// This represents '#pragma omp parallel master taskloop simd' directive. 4297 /// 4298 /// \code 4299 /// #pragma omp parallel master taskloop simd private(a,b) grainsize(val) 4300 /// num_tasks(num) 4301 /// \endcode 4302 /// In this example directive '#pragma omp parallel master taskloop simd' has 4303 /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with 4304 /// expression 'val' and 'num_tasks' with expression 'num'. 4305 /// 4306 class OMPParallelMasterTaskLoopSimdDirective : public OMPLoopDirective { 4307 friend class ASTStmtReader; 4308 friend class OMPExecutableDirective; 4309 /// Build directive with the given start and end location. 4310 /// 4311 /// \param StartLoc Starting location of the directive kind. 4312 /// \param EndLoc Ending location of the directive. 4313 /// \param CollapsedNum Number of collapsed nested loops. 4314 /// OMPParallelMasterTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4315 OMPParallelMasterTaskLoopSimdDirective(SourceLocation StartLoc, 4316 SourceLocation EndLoc, 4317 unsigned CollapsedNum) 4318 : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass, 4319 llvm::omp::OMPD_parallel_master_taskloop_simd, 4320 StartLoc, EndLoc, CollapsedNum) {} 4321 4322 /// Build an empty directive. 4323 /// 4324 /// \param CollapsedNum Number of collapsed nested loops. 4325 /// OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum)4326 explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum) 4327 : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass, 4328 llvm::omp::OMPD_parallel_master_taskloop_simd, 4329 SourceLocation(), SourceLocation(), CollapsedNum) {} 4330 4331 public: 4332 /// Creates directive with a list of \p Clauses. 4333 /// 4334 /// \param C AST context. 4335 /// \param StartLoc Starting location of the directive kind. 4336 /// \param EndLoc Ending Location of the directive. 4337 /// \param CollapsedNum Number of collapsed loops. 4338 /// \param Clauses List of clauses. 4339 /// \param AssociatedStmt Statement, associated with the directive. 4340 /// \param Exprs Helper expressions for CodeGen. 4341 /// 4342 static OMPParallelMasterTaskLoopSimdDirective * 4343 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4344 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4345 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4346 4347 /// Creates an empty directive with the place 4348 /// for \a NumClauses clauses. 4349 /// 4350 /// \param C AST context. 4351 /// \param CollapsedNum Number of collapsed nested loops. 4352 /// \param NumClauses Number of clauses. 4353 /// 4354 static OMPParallelMasterTaskLoopSimdDirective * 4355 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4356 EmptyShell); 4357 classof(const Stmt * T)4358 static bool classof(const Stmt *T) { 4359 return T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass; 4360 } 4361 }; 4362 4363 /// This represents '#pragma omp parallel masked taskloop simd' directive. 4364 /// 4365 /// \code 4366 /// #pragma omp parallel masked taskloop simd private(a,b) grainsize(val) 4367 /// num_tasks(num) 4368 /// \endcode 4369 /// In this example directive '#pragma omp parallel masked taskloop simd' has 4370 /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with 4371 /// expression 'val' and 'num_tasks' with expression 'num'. 4372 /// 4373 class OMPParallelMaskedTaskLoopSimdDirective final : public OMPLoopDirective { 4374 friend class ASTStmtReader; 4375 friend class OMPExecutableDirective; 4376 /// Build directive with the given start and end location. 4377 /// 4378 /// \param StartLoc Starting location of the directive kind. 4379 /// \param EndLoc Ending location of the directive. 4380 /// \param CollapsedNum Number of collapsed nested loops. 4381 /// OMPParallelMaskedTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4382 OMPParallelMaskedTaskLoopSimdDirective(SourceLocation StartLoc, 4383 SourceLocation EndLoc, 4384 unsigned CollapsedNum) 4385 : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass, 4386 llvm::omp::OMPD_parallel_masked_taskloop_simd, 4387 StartLoc, EndLoc, CollapsedNum) {} 4388 4389 /// Build an empty directive. 4390 /// 4391 /// \param CollapsedNum Number of collapsed nested loops. 4392 /// OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum)4393 explicit OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum) 4394 : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass, 4395 llvm::omp::OMPD_parallel_masked_taskloop_simd, 4396 SourceLocation(), SourceLocation(), CollapsedNum) {} 4397 4398 public: 4399 /// Creates directive with a list of \p Clauses. 4400 /// 4401 /// \param C AST context. 4402 /// \param StartLoc Starting location of the directive kind. 4403 /// \param EndLoc Ending Location of the directive. 4404 /// \param CollapsedNum Number of collapsed loops. 4405 /// \param Clauses List of clauses. 4406 /// \param AssociatedStmt Statement, associated with the directive. 4407 /// \param Exprs Helper expressions for CodeGen. 4408 /// 4409 static OMPParallelMaskedTaskLoopSimdDirective * 4410 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4411 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4412 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4413 4414 /// Creates an empty directive with the place 4415 /// for \a NumClauses clauses. 4416 /// 4417 /// \param C AST context. 4418 /// \param CollapsedNum Number of collapsed nested loops. 4419 /// \param NumClauses Number of clauses. 4420 /// 4421 static OMPParallelMaskedTaskLoopSimdDirective * 4422 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4423 EmptyShell); 4424 classof(const Stmt * T)4425 static bool classof(const Stmt *T) { 4426 return T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass; 4427 } 4428 }; 4429 4430 /// This represents '#pragma omp distribute' directive. 4431 /// 4432 /// \code 4433 /// #pragma omp distribute private(a,b) 4434 /// \endcode 4435 /// In this example directive '#pragma omp distribute' has clauses 'private' 4436 /// with the variables 'a' and 'b' 4437 /// 4438 class OMPDistributeDirective : public OMPLoopDirective { 4439 friend class ASTStmtReader; 4440 friend class OMPExecutableDirective; 4441 4442 /// Build directive with the given start and end location. 4443 /// 4444 /// \param StartLoc Starting location of the directive kind. 4445 /// \param EndLoc Ending location of the directive. 4446 /// \param CollapsedNum Number of collapsed nested loops. 4447 /// OMPDistributeDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4448 OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4449 unsigned CollapsedNum) 4450 : OMPLoopDirective(OMPDistributeDirectiveClass, 4451 llvm::omp::OMPD_distribute, StartLoc, EndLoc, 4452 CollapsedNum) {} 4453 4454 /// Build an empty directive. 4455 /// 4456 /// \param CollapsedNum Number of collapsed nested loops. 4457 /// OMPDistributeDirective(unsigned CollapsedNum)4458 explicit OMPDistributeDirective(unsigned CollapsedNum) 4459 : OMPLoopDirective(OMPDistributeDirectiveClass, 4460 llvm::omp::OMPD_distribute, SourceLocation(), 4461 SourceLocation(), CollapsedNum) {} 4462 4463 public: 4464 /// Creates directive with a list of \a Clauses. 4465 /// 4466 /// \param C AST context. 4467 /// \param StartLoc Starting location of the directive kind. 4468 /// \param EndLoc Ending Location of the directive. 4469 /// \param CollapsedNum Number of collapsed loops. 4470 /// \param Clauses List of clauses. 4471 /// \param AssociatedStmt Statement, associated with the directive. 4472 /// \param Exprs Helper expressions for CodeGen. 4473 /// 4474 static OMPDistributeDirective * 4475 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4476 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4477 Stmt *AssociatedStmt, const HelperExprs &Exprs, 4478 OpenMPDirectiveKind ParamPrevMappedDirective); 4479 4480 /// Creates an empty directive with the place 4481 /// for \a NumClauses clauses. 4482 /// 4483 /// \param C AST context. 4484 /// \param CollapsedNum Number of collapsed nested loops. 4485 /// \param NumClauses Number of clauses. 4486 /// 4487 static OMPDistributeDirective *CreateEmpty(const ASTContext &C, 4488 unsigned NumClauses, 4489 unsigned CollapsedNum, EmptyShell); 4490 classof(const Stmt * T)4491 static bool classof(const Stmt *T) { 4492 return T->getStmtClass() == OMPDistributeDirectiveClass; 4493 } 4494 }; 4495 4496 /// This represents '#pragma omp target update' directive. 4497 /// 4498 /// \code 4499 /// #pragma omp target update to(a) from(b) device(1) 4500 /// \endcode 4501 /// In this example directive '#pragma omp target update' has clause 'to' with 4502 /// argument 'a', clause 'from' with argument 'b' and clause 'device' with 4503 /// argument '1'. 4504 /// 4505 class OMPTargetUpdateDirective : public OMPExecutableDirective { 4506 friend class ASTStmtReader; 4507 friend class OMPExecutableDirective; 4508 /// Build directive with the given start and end location. 4509 /// 4510 /// \param StartLoc Starting location of the directive kind. 4511 /// \param EndLoc Ending Location of the directive. 4512 /// OMPTargetUpdateDirective(SourceLocation StartLoc,SourceLocation EndLoc)4513 OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc) 4514 : OMPExecutableDirective(OMPTargetUpdateDirectiveClass, 4515 llvm::omp::OMPD_target_update, StartLoc, 4516 EndLoc) {} 4517 4518 /// Build an empty directive. 4519 /// OMPTargetUpdateDirective()4520 explicit OMPTargetUpdateDirective() 4521 : OMPExecutableDirective(OMPTargetUpdateDirectiveClass, 4522 llvm::omp::OMPD_target_update, SourceLocation(), 4523 SourceLocation()) {} 4524 4525 public: 4526 /// Creates directive with a list of \a Clauses. 4527 /// 4528 /// \param C AST context. 4529 /// \param StartLoc Starting location of the directive kind. 4530 /// \param EndLoc Ending Location of the directive. 4531 /// \param Clauses List of clauses. 4532 /// \param AssociatedStmt Statement, associated with the directive. 4533 /// 4534 static OMPTargetUpdateDirective * 4535 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4536 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 4537 4538 /// Creates an empty directive with the place for \a NumClauses 4539 /// clauses. 4540 /// 4541 /// \param C AST context. 4542 /// \param NumClauses The number of clauses. 4543 /// 4544 static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C, 4545 unsigned NumClauses, EmptyShell); 4546 classof(const Stmt * T)4547 static bool classof(const Stmt *T) { 4548 return T->getStmtClass() == OMPTargetUpdateDirectiveClass; 4549 } 4550 }; 4551 4552 /// This represents '#pragma omp distribute parallel for' composite 4553 /// directive. 4554 /// 4555 /// \code 4556 /// #pragma omp distribute parallel for private(a,b) 4557 /// \endcode 4558 /// In this example directive '#pragma omp distribute parallel for' has clause 4559 /// 'private' with the variables 'a' and 'b' 4560 /// 4561 class OMPDistributeParallelForDirective : public OMPLoopDirective { 4562 friend class ASTStmtReader; 4563 friend class OMPExecutableDirective; 4564 /// true if the construct has inner cancel directive. 4565 bool HasCancel = false; 4566 4567 /// Build directive with the given start and end location. 4568 /// 4569 /// \param StartLoc Starting location of the directive kind. 4570 /// \param EndLoc Ending location of the directive. 4571 /// \param CollapsedNum Number of collapsed nested loops. 4572 /// OMPDistributeParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4573 OMPDistributeParallelForDirective(SourceLocation StartLoc, 4574 SourceLocation EndLoc, 4575 unsigned CollapsedNum) 4576 : OMPLoopDirective(OMPDistributeParallelForDirectiveClass, 4577 llvm::omp::OMPD_distribute_parallel_for, StartLoc, 4578 EndLoc, CollapsedNum) {} 4579 4580 /// Build an empty directive. 4581 /// 4582 /// \param CollapsedNum Number of collapsed nested loops. 4583 /// OMPDistributeParallelForDirective(unsigned CollapsedNum)4584 explicit OMPDistributeParallelForDirective(unsigned CollapsedNum) 4585 : OMPLoopDirective(OMPDistributeParallelForDirectiveClass, 4586 llvm::omp::OMPD_distribute_parallel_for, 4587 SourceLocation(), SourceLocation(), CollapsedNum) {} 4588 4589 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)4590 void setTaskReductionRefExpr(Expr *E) { 4591 Data->getChildren()[numLoopChildren( 4592 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)] = E; 4593 } 4594 4595 /// Set cancel state. setHasCancel(bool Has)4596 void setHasCancel(bool Has) { HasCancel = Has; } 4597 4598 public: 4599 /// Creates directive with a list of \a Clauses. 4600 /// 4601 /// \param C AST context. 4602 /// \param StartLoc Starting location of the directive kind. 4603 /// \param EndLoc Ending Location of the directive. 4604 /// \param CollapsedNum Number of collapsed loops. 4605 /// \param Clauses List of clauses. 4606 /// \param AssociatedStmt Statement, associated with the directive. 4607 /// \param Exprs Helper expressions for CodeGen. 4608 /// \param TaskRedRef Task reduction special reference expression to handle 4609 /// taskgroup descriptor. 4610 /// \param HasCancel true if this directive has inner cancel directive. 4611 /// 4612 static OMPDistributeParallelForDirective * 4613 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4614 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4615 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 4616 bool HasCancel); 4617 4618 /// Creates an empty directive with the place 4619 /// for \a NumClauses clauses. 4620 /// 4621 /// \param C AST context. 4622 /// \param CollapsedNum Number of collapsed nested loops. 4623 /// \param NumClauses Number of clauses. 4624 /// 4625 static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C, 4626 unsigned NumClauses, 4627 unsigned CollapsedNum, 4628 EmptyShell); 4629 4630 /// Returns special task reduction reference expression. getTaskReductionRefExpr()4631 Expr *getTaskReductionRefExpr() { 4632 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 4633 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)]); 4634 } getTaskReductionRefExpr()4635 const Expr *getTaskReductionRefExpr() const { 4636 return const_cast<OMPDistributeParallelForDirective *>(this) 4637 ->getTaskReductionRefExpr(); 4638 } 4639 4640 /// Return true if current directive has inner cancel directive. hasCancel()4641 bool hasCancel() const { return HasCancel; } 4642 classof(const Stmt * T)4643 static bool classof(const Stmt *T) { 4644 return T->getStmtClass() == OMPDistributeParallelForDirectiveClass; 4645 } 4646 }; 4647 4648 /// This represents '#pragma omp distribute parallel for simd' composite 4649 /// directive. 4650 /// 4651 /// \code 4652 /// #pragma omp distribute parallel for simd private(x) 4653 /// \endcode 4654 /// In this example directive '#pragma omp distribute parallel for simd' has 4655 /// clause 'private' with the variables 'x' 4656 /// 4657 class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective { 4658 friend class ASTStmtReader; 4659 friend class OMPExecutableDirective; 4660 4661 /// Build directive with the given start and end location. 4662 /// 4663 /// \param StartLoc Starting location of the directive kind. 4664 /// \param EndLoc Ending location of the directive. 4665 /// \param CollapsedNum Number of collapsed nested loops. 4666 /// OMPDistributeParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4667 OMPDistributeParallelForSimdDirective(SourceLocation StartLoc, 4668 SourceLocation EndLoc, 4669 unsigned CollapsedNum) 4670 : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass, 4671 llvm::omp::OMPD_distribute_parallel_for_simd, StartLoc, 4672 EndLoc, CollapsedNum) {} 4673 4674 /// Build an empty directive. 4675 /// 4676 /// \param CollapsedNum Number of collapsed nested loops. 4677 /// OMPDistributeParallelForSimdDirective(unsigned CollapsedNum)4678 explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum) 4679 : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass, 4680 llvm::omp::OMPD_distribute_parallel_for_simd, 4681 SourceLocation(), SourceLocation(), CollapsedNum) {} 4682 4683 public: 4684 /// Creates directive with a list of \a Clauses. 4685 /// 4686 /// \param C AST context. 4687 /// \param StartLoc Starting location of the directive kind. 4688 /// \param EndLoc Ending Location of the directive. 4689 /// \param CollapsedNum Number of collapsed loops. 4690 /// \param Clauses List of clauses. 4691 /// \param AssociatedStmt Statement, associated with the directive. 4692 /// \param Exprs Helper expressions for CodeGen. 4693 /// 4694 static OMPDistributeParallelForSimdDirective *Create( 4695 const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4696 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4697 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4698 4699 /// Creates an empty directive with the place for \a NumClauses clauses. 4700 /// 4701 /// \param C AST context. 4702 /// \param CollapsedNum Number of collapsed nested loops. 4703 /// \param NumClauses Number of clauses. 4704 /// 4705 static OMPDistributeParallelForSimdDirective *CreateEmpty( 4706 const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 4707 EmptyShell); 4708 classof(const Stmt * T)4709 static bool classof(const Stmt *T) { 4710 return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass; 4711 } 4712 }; 4713 4714 /// This represents '#pragma omp distribute simd' composite directive. 4715 /// 4716 /// \code 4717 /// #pragma omp distribute simd private(x) 4718 /// \endcode 4719 /// In this example directive '#pragma omp distribute simd' has clause 4720 /// 'private' with the variables 'x' 4721 /// 4722 class OMPDistributeSimdDirective final : public OMPLoopDirective { 4723 friend class ASTStmtReader; 4724 friend class OMPExecutableDirective; 4725 4726 /// Build directive with the given start and end location. 4727 /// 4728 /// \param StartLoc Starting location of the directive kind. 4729 /// \param EndLoc Ending location of the directive. 4730 /// \param CollapsedNum Number of collapsed nested loops. 4731 /// OMPDistributeSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4732 OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4733 unsigned CollapsedNum) 4734 : OMPLoopDirective(OMPDistributeSimdDirectiveClass, 4735 llvm::omp::OMPD_distribute_simd, StartLoc, EndLoc, 4736 CollapsedNum) {} 4737 4738 /// Build an empty directive. 4739 /// 4740 /// \param CollapsedNum Number of collapsed nested loops. 4741 /// OMPDistributeSimdDirective(unsigned CollapsedNum)4742 explicit OMPDistributeSimdDirective(unsigned CollapsedNum) 4743 : OMPLoopDirective(OMPDistributeSimdDirectiveClass, 4744 llvm::omp::OMPD_distribute_simd, SourceLocation(), 4745 SourceLocation(), CollapsedNum) {} 4746 4747 public: 4748 /// Creates directive with a list of \a Clauses. 4749 /// 4750 /// \param C AST context. 4751 /// \param StartLoc Starting location of the directive kind. 4752 /// \param EndLoc Ending Location of the directive. 4753 /// \param CollapsedNum Number of collapsed loops. 4754 /// \param Clauses List of clauses. 4755 /// \param AssociatedStmt Statement, associated with the directive. 4756 /// \param Exprs Helper expressions for CodeGen. 4757 /// 4758 static OMPDistributeSimdDirective * 4759 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4760 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4761 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4762 4763 /// Creates an empty directive with the place for \a NumClauses clauses. 4764 /// 4765 /// \param C AST context. 4766 /// \param CollapsedNum Number of collapsed nested loops. 4767 /// \param NumClauses Number of clauses. 4768 /// 4769 static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C, 4770 unsigned NumClauses, 4771 unsigned CollapsedNum, 4772 EmptyShell); 4773 classof(const Stmt * T)4774 static bool classof(const Stmt *T) { 4775 return T->getStmtClass() == OMPDistributeSimdDirectiveClass; 4776 } 4777 }; 4778 4779 /// This represents '#pragma omp target parallel for simd' directive. 4780 /// 4781 /// \code 4782 /// #pragma omp target parallel for simd private(a) map(b) safelen(c) 4783 /// \endcode 4784 /// In this example directive '#pragma omp target parallel for simd' has clauses 4785 /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen' 4786 /// with the variable 'c'. 4787 /// 4788 class OMPTargetParallelForSimdDirective final : public OMPLoopDirective { 4789 friend class ASTStmtReader; 4790 friend class OMPExecutableDirective; 4791 4792 /// Build directive with the given start and end location. 4793 /// 4794 /// \param StartLoc Starting location of the directive kind. 4795 /// \param EndLoc Ending location of the directive. 4796 /// \param CollapsedNum Number of collapsed nested loops. 4797 /// OMPTargetParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4798 OMPTargetParallelForSimdDirective(SourceLocation StartLoc, 4799 SourceLocation EndLoc, 4800 unsigned CollapsedNum) 4801 : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass, 4802 llvm::omp::OMPD_target_parallel_for_simd, StartLoc, 4803 EndLoc, CollapsedNum) {} 4804 4805 /// Build an empty directive. 4806 /// 4807 /// \param CollapsedNum Number of collapsed nested loops. 4808 /// OMPTargetParallelForSimdDirective(unsigned CollapsedNum)4809 explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum) 4810 : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass, 4811 llvm::omp::OMPD_target_parallel_for_simd, 4812 SourceLocation(), SourceLocation(), CollapsedNum) {} 4813 4814 public: 4815 /// Creates directive with a list of \a Clauses. 4816 /// 4817 /// \param C AST context. 4818 /// \param StartLoc Starting location of the directive kind. 4819 /// \param EndLoc Ending Location of the directive. 4820 /// \param CollapsedNum Number of collapsed loops. 4821 /// \param Clauses List of clauses. 4822 /// \param AssociatedStmt Statement, associated with the directive. 4823 /// \param Exprs Helper expressions for CodeGen. 4824 /// 4825 static OMPTargetParallelForSimdDirective * 4826 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4827 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4828 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4829 4830 /// Creates an empty directive with the place for \a NumClauses clauses. 4831 /// 4832 /// \param C AST context. 4833 /// \param CollapsedNum Number of collapsed nested loops. 4834 /// \param NumClauses Number of clauses. 4835 /// 4836 static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C, 4837 unsigned NumClauses, 4838 unsigned CollapsedNum, 4839 EmptyShell); 4840 classof(const Stmt * T)4841 static bool classof(const Stmt *T) { 4842 return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass; 4843 } 4844 }; 4845 4846 /// This represents '#pragma omp target simd' directive. 4847 /// 4848 /// \code 4849 /// #pragma omp target simd private(a) map(b) safelen(c) 4850 /// \endcode 4851 /// In this example directive '#pragma omp target simd' has clauses 'private' 4852 /// with the variable 'a', 'map' with the variable 'b' and 'safelen' with 4853 /// the variable 'c'. 4854 /// 4855 class OMPTargetSimdDirective final : public OMPLoopDirective { 4856 friend class ASTStmtReader; 4857 friend class OMPExecutableDirective; 4858 4859 /// Build directive with the given start and end location. 4860 /// 4861 /// \param StartLoc Starting location of the directive kind. 4862 /// \param EndLoc Ending location of the directive. 4863 /// \param CollapsedNum Number of collapsed nested loops. 4864 /// OMPTargetSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4865 OMPTargetSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4866 unsigned CollapsedNum) 4867 : OMPLoopDirective(OMPTargetSimdDirectiveClass, 4868 llvm::omp::OMPD_target_simd, StartLoc, EndLoc, 4869 CollapsedNum) {} 4870 4871 /// Build an empty directive. 4872 /// 4873 /// \param CollapsedNum Number of collapsed nested loops. 4874 /// OMPTargetSimdDirective(unsigned CollapsedNum)4875 explicit OMPTargetSimdDirective(unsigned CollapsedNum) 4876 : OMPLoopDirective(OMPTargetSimdDirectiveClass, 4877 llvm::omp::OMPD_target_simd, SourceLocation(), 4878 SourceLocation(), CollapsedNum) {} 4879 4880 public: 4881 /// Creates directive with a list of \a Clauses. 4882 /// 4883 /// \param C AST context. 4884 /// \param StartLoc Starting location of the directive kind. 4885 /// \param EndLoc Ending Location of the directive. 4886 /// \param CollapsedNum Number of collapsed loops. 4887 /// \param Clauses List of clauses. 4888 /// \param AssociatedStmt Statement, associated with the directive. 4889 /// \param Exprs Helper expressions for CodeGen. 4890 /// 4891 static OMPTargetSimdDirective * 4892 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4893 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4894 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4895 4896 /// Creates an empty directive with the place for \a NumClauses clauses. 4897 /// 4898 /// \param C AST context. 4899 /// \param CollapsedNum Number of collapsed nested loops. 4900 /// \param NumClauses Number of clauses. 4901 /// 4902 static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C, 4903 unsigned NumClauses, 4904 unsigned CollapsedNum, 4905 EmptyShell); 4906 classof(const Stmt * T)4907 static bool classof(const Stmt *T) { 4908 return T->getStmtClass() == OMPTargetSimdDirectiveClass; 4909 } 4910 }; 4911 4912 /// This represents '#pragma omp teams distribute' directive. 4913 /// 4914 /// \code 4915 /// #pragma omp teams distribute private(a,b) 4916 /// \endcode 4917 /// In this example directive '#pragma omp teams distribute' has clauses 4918 /// 'private' with the variables 'a' and 'b' 4919 /// 4920 class OMPTeamsDistributeDirective final : public OMPLoopDirective { 4921 friend class ASTStmtReader; 4922 friend class OMPExecutableDirective; 4923 4924 /// Build directive with the given start and end location. 4925 /// 4926 /// \param StartLoc Starting location of the directive kind. 4927 /// \param EndLoc Ending location of the directive. 4928 /// \param CollapsedNum Number of collapsed nested loops. 4929 /// OMPTeamsDistributeDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4930 OMPTeamsDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, 4931 unsigned CollapsedNum) 4932 : OMPLoopDirective(OMPTeamsDistributeDirectiveClass, 4933 llvm::omp::OMPD_teams_distribute, StartLoc, EndLoc, 4934 CollapsedNum) {} 4935 4936 /// Build an empty directive. 4937 /// 4938 /// \param CollapsedNum Number of collapsed nested loops. 4939 /// OMPTeamsDistributeDirective(unsigned CollapsedNum)4940 explicit OMPTeamsDistributeDirective(unsigned CollapsedNum) 4941 : OMPLoopDirective(OMPTeamsDistributeDirectiveClass, 4942 llvm::omp::OMPD_teams_distribute, SourceLocation(), 4943 SourceLocation(), CollapsedNum) {} 4944 4945 public: 4946 /// Creates directive with a list of \a Clauses. 4947 /// 4948 /// \param C AST context. 4949 /// \param StartLoc Starting location of the directive kind. 4950 /// \param EndLoc Ending Location of the directive. 4951 /// \param CollapsedNum Number of collapsed loops. 4952 /// \param Clauses List of clauses. 4953 /// \param AssociatedStmt Statement, associated with the directive. 4954 /// \param Exprs Helper expressions for CodeGen. 4955 /// 4956 static OMPTeamsDistributeDirective * 4957 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 4958 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 4959 Stmt *AssociatedStmt, const HelperExprs &Exprs); 4960 4961 /// Creates an empty directive with the place for \a NumClauses clauses. 4962 /// 4963 /// \param C AST context. 4964 /// \param CollapsedNum Number of collapsed nested loops. 4965 /// \param NumClauses Number of clauses. 4966 /// 4967 static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C, 4968 unsigned NumClauses, 4969 unsigned CollapsedNum, 4970 EmptyShell); 4971 classof(const Stmt * T)4972 static bool classof(const Stmt *T) { 4973 return T->getStmtClass() == OMPTeamsDistributeDirectiveClass; 4974 } 4975 }; 4976 4977 /// This represents '#pragma omp teams distribute simd' 4978 /// combined directive. 4979 /// 4980 /// \code 4981 /// #pragma omp teams distribute simd private(a,b) 4982 /// \endcode 4983 /// In this example directive '#pragma omp teams distribute simd' 4984 /// has clause 'private' with the variables 'a' and 'b' 4985 /// 4986 class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective { 4987 friend class ASTStmtReader; 4988 friend class OMPExecutableDirective; 4989 4990 /// Build directive with the given start and end location. 4991 /// 4992 /// \param StartLoc Starting location of the directive kind. 4993 /// \param EndLoc Ending location of the directive. 4994 /// \param CollapsedNum Number of collapsed nested loops. 4995 /// OMPTeamsDistributeSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4996 OMPTeamsDistributeSimdDirective(SourceLocation StartLoc, 4997 SourceLocation EndLoc, unsigned CollapsedNum) 4998 : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass, 4999 llvm::omp::OMPD_teams_distribute_simd, StartLoc, 5000 EndLoc, CollapsedNum) {} 5001 5002 /// Build an empty directive. 5003 /// 5004 /// \param CollapsedNum Number of collapsed nested loops. 5005 /// OMPTeamsDistributeSimdDirective(unsigned CollapsedNum)5006 explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum) 5007 : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass, 5008 llvm::omp::OMPD_teams_distribute_simd, 5009 SourceLocation(), SourceLocation(), CollapsedNum) {} 5010 5011 public: 5012 /// Creates directive with a list of \a Clauses. 5013 /// 5014 /// \param C AST context. 5015 /// \param StartLoc Starting location of the directive kind. 5016 /// \param EndLoc Ending Location of the directive. 5017 /// \param CollapsedNum Number of collapsed loops. 5018 /// \param Clauses List of clauses. 5019 /// \param AssociatedStmt Statement, associated with the directive. 5020 /// \param Exprs Helper expressions for CodeGen. 5021 /// 5022 static OMPTeamsDistributeSimdDirective * 5023 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5024 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 5025 Stmt *AssociatedStmt, const HelperExprs &Exprs); 5026 5027 /// Creates an empty directive with the place 5028 /// for \a NumClauses clauses. 5029 /// 5030 /// \param C AST context. 5031 /// \param CollapsedNum Number of collapsed nested loops. 5032 /// \param NumClauses Number of clauses. 5033 /// 5034 static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C, 5035 unsigned NumClauses, 5036 unsigned CollapsedNum, 5037 EmptyShell); 5038 classof(const Stmt * T)5039 static bool classof(const Stmt *T) { 5040 return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass; 5041 } 5042 }; 5043 5044 /// This represents '#pragma omp teams distribute parallel for simd' composite 5045 /// directive. 5046 /// 5047 /// \code 5048 /// #pragma omp teams distribute parallel for simd private(x) 5049 /// \endcode 5050 /// In this example directive '#pragma omp teams distribute parallel for simd' 5051 /// has clause 'private' with the variables 'x' 5052 /// 5053 class OMPTeamsDistributeParallelForSimdDirective final 5054 : public OMPLoopDirective { 5055 friend class ASTStmtReader; 5056 friend class OMPExecutableDirective; 5057 5058 /// Build directive with the given start and end location. 5059 /// 5060 /// \param StartLoc Starting location of the directive kind. 5061 /// \param EndLoc Ending location of the directive. 5062 /// \param CollapsedNum Number of collapsed nested loops. 5063 /// OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5064 OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc, 5065 SourceLocation EndLoc, 5066 unsigned CollapsedNum) 5067 : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass, 5068 llvm::omp::OMPD_teams_distribute_parallel_for_simd, 5069 StartLoc, EndLoc, CollapsedNum) {} 5070 5071 /// Build an empty directive. 5072 /// 5073 /// \param CollapsedNum Number of collapsed nested loops. 5074 /// OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum)5075 explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum) 5076 : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass, 5077 llvm::omp::OMPD_teams_distribute_parallel_for_simd, 5078 SourceLocation(), SourceLocation(), CollapsedNum) {} 5079 5080 public: 5081 /// Creates directive with a list of \a Clauses. 5082 /// 5083 /// \param C AST context. 5084 /// \param StartLoc Starting location of the directive kind. 5085 /// \param EndLoc Ending Location of the directive. 5086 /// \param CollapsedNum Number of collapsed loops. 5087 /// \param Clauses List of clauses. 5088 /// \param AssociatedStmt Statement, associated with the directive. 5089 /// \param Exprs Helper expressions for CodeGen. 5090 /// 5091 static OMPTeamsDistributeParallelForSimdDirective * 5092 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5093 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 5094 Stmt *AssociatedStmt, const HelperExprs &Exprs); 5095 5096 /// Creates an empty directive with the place for \a NumClauses clauses. 5097 /// 5098 /// \param C AST context. 5099 /// \param CollapsedNum Number of collapsed nested loops. 5100 /// \param NumClauses Number of clauses. 5101 /// 5102 static OMPTeamsDistributeParallelForSimdDirective * 5103 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 5104 EmptyShell); 5105 classof(const Stmt * T)5106 static bool classof(const Stmt *T) { 5107 return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass; 5108 } 5109 }; 5110 5111 /// This represents '#pragma omp teams distribute parallel for' composite 5112 /// directive. 5113 /// 5114 /// \code 5115 /// #pragma omp teams distribute parallel for private(x) 5116 /// \endcode 5117 /// In this example directive '#pragma omp teams distribute parallel for' 5118 /// has clause 'private' with the variables 'x' 5119 /// 5120 class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective { 5121 friend class ASTStmtReader; 5122 friend class OMPExecutableDirective; 5123 /// true if the construct has inner cancel directive. 5124 bool HasCancel = false; 5125 5126 /// Build directive with the given start and end location. 5127 /// 5128 /// \param StartLoc Starting location of the directive kind. 5129 /// \param EndLoc Ending location of the directive. 5130 /// \param CollapsedNum Number of collapsed nested loops. 5131 /// OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5132 OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc, 5133 SourceLocation EndLoc, 5134 unsigned CollapsedNum) 5135 : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass, 5136 llvm::omp::OMPD_teams_distribute_parallel_for, 5137 StartLoc, EndLoc, CollapsedNum) {} 5138 5139 /// Build an empty directive. 5140 /// 5141 /// \param CollapsedNum Number of collapsed nested loops. 5142 /// OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum)5143 explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum) 5144 : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass, 5145 llvm::omp::OMPD_teams_distribute_parallel_for, 5146 SourceLocation(), SourceLocation(), CollapsedNum) {} 5147 5148 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)5149 void setTaskReductionRefExpr(Expr *E) { 5150 Data->getChildren()[numLoopChildren( 5151 getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)] = E; 5152 } 5153 5154 /// Set cancel state. setHasCancel(bool Has)5155 void setHasCancel(bool Has) { HasCancel = Has; } 5156 5157 public: 5158 /// Creates directive with a list of \a Clauses. 5159 /// 5160 /// \param C AST context. 5161 /// \param StartLoc Starting location of the directive kind. 5162 /// \param EndLoc Ending Location of the directive. 5163 /// \param CollapsedNum Number of collapsed loops. 5164 /// \param Clauses List of clauses. 5165 /// \param AssociatedStmt Statement, associated with the directive. 5166 /// \param Exprs Helper expressions for CodeGen. 5167 /// \param TaskRedRef Task reduction special reference expression to handle 5168 /// taskgroup descriptor. 5169 /// \param HasCancel true if this directive has inner cancel directive. 5170 /// 5171 static OMPTeamsDistributeParallelForDirective * 5172 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5173 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 5174 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 5175 bool HasCancel); 5176 5177 /// Creates an empty directive with the place for \a NumClauses clauses. 5178 /// 5179 /// \param C AST context. 5180 /// \param CollapsedNum Number of collapsed nested loops. 5181 /// \param NumClauses Number of clauses. 5182 /// 5183 static OMPTeamsDistributeParallelForDirective * 5184 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 5185 EmptyShell); 5186 5187 /// Returns special task reduction reference expression. getTaskReductionRefExpr()5188 Expr *getTaskReductionRefExpr() { 5189 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 5190 getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)]); 5191 } getTaskReductionRefExpr()5192 const Expr *getTaskReductionRefExpr() const { 5193 return const_cast<OMPTeamsDistributeParallelForDirective *>(this) 5194 ->getTaskReductionRefExpr(); 5195 } 5196 5197 /// Return true if current directive has inner cancel directive. hasCancel()5198 bool hasCancel() const { return HasCancel; } 5199 classof(const Stmt * T)5200 static bool classof(const Stmt *T) { 5201 return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass; 5202 } 5203 }; 5204 5205 /// This represents '#pragma omp target teams' directive. 5206 /// 5207 /// \code 5208 /// #pragma omp target teams if(a>0) 5209 /// \endcode 5210 /// In this example directive '#pragma omp target teams' has clause 'if' with 5211 /// condition 'a>0'. 5212 /// 5213 class OMPTargetTeamsDirective final : public OMPExecutableDirective { 5214 friend class ASTStmtReader; 5215 friend class OMPExecutableDirective; 5216 /// Build directive with the given start and end location. 5217 /// 5218 /// \param StartLoc Starting location of the directive kind. 5219 /// \param EndLoc Ending location of the directive. 5220 /// OMPTargetTeamsDirective(SourceLocation StartLoc,SourceLocation EndLoc)5221 OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5222 : OMPExecutableDirective(OMPTargetTeamsDirectiveClass, 5223 llvm::omp::OMPD_target_teams, StartLoc, EndLoc) { 5224 } 5225 5226 /// Build an empty directive. 5227 /// OMPTargetTeamsDirective()5228 explicit OMPTargetTeamsDirective() 5229 : OMPExecutableDirective(OMPTargetTeamsDirectiveClass, 5230 llvm::omp::OMPD_target_teams, SourceLocation(), 5231 SourceLocation()) {} 5232 5233 public: 5234 /// Creates directive with a list of \a Clauses. 5235 /// 5236 /// \param C AST context. 5237 /// \param StartLoc Starting location of the directive kind. 5238 /// \param EndLoc Ending Location of the directive. 5239 /// \param Clauses List of clauses. 5240 /// \param AssociatedStmt Statement, associated with the directive. 5241 /// 5242 static OMPTargetTeamsDirective *Create(const ASTContext &C, 5243 SourceLocation StartLoc, 5244 SourceLocation EndLoc, 5245 ArrayRef<OMPClause *> Clauses, 5246 Stmt *AssociatedStmt); 5247 5248 /// Creates an empty directive with the place for \a NumClauses clauses. 5249 /// 5250 /// \param C AST context. 5251 /// \param NumClauses Number of clauses. 5252 /// 5253 static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C, 5254 unsigned NumClauses, EmptyShell); 5255 classof(const Stmt * T)5256 static bool classof(const Stmt *T) { 5257 return T->getStmtClass() == OMPTargetTeamsDirectiveClass; 5258 } 5259 }; 5260 5261 /// This represents '#pragma omp target teams distribute' combined directive. 5262 /// 5263 /// \code 5264 /// #pragma omp target teams distribute private(x) 5265 /// \endcode 5266 /// In this example directive '#pragma omp target teams distribute' has clause 5267 /// 'private' with the variables 'x' 5268 /// 5269 class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective { 5270 friend class ASTStmtReader; 5271 friend class OMPExecutableDirective; 5272 5273 /// Build directive with the given start and end location. 5274 /// 5275 /// \param StartLoc Starting location of the directive kind. 5276 /// \param EndLoc Ending location of the directive. 5277 /// \param CollapsedNum Number of collapsed nested loops. 5278 /// OMPTargetTeamsDistributeDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5279 OMPTargetTeamsDistributeDirective(SourceLocation StartLoc, 5280 SourceLocation EndLoc, 5281 unsigned CollapsedNum) 5282 : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass, 5283 llvm::omp::OMPD_target_teams_distribute, StartLoc, 5284 EndLoc, CollapsedNum) {} 5285 5286 /// Build an empty directive. 5287 /// 5288 /// \param CollapsedNum Number of collapsed nested loops. 5289 /// OMPTargetTeamsDistributeDirective(unsigned CollapsedNum)5290 explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum) 5291 : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass, 5292 llvm::omp::OMPD_target_teams_distribute, 5293 SourceLocation(), SourceLocation(), CollapsedNum) {} 5294 5295 public: 5296 /// Creates directive with a list of \a Clauses. 5297 /// 5298 /// \param C AST context. 5299 /// \param StartLoc Starting location of the directive kind. 5300 /// \param EndLoc Ending Location of the directive. 5301 /// \param CollapsedNum Number of collapsed loops. 5302 /// \param Clauses List of clauses. 5303 /// \param AssociatedStmt Statement, associated with the directive. 5304 /// \param Exprs Helper expressions for CodeGen. 5305 /// 5306 static OMPTargetTeamsDistributeDirective * 5307 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5308 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 5309 Stmt *AssociatedStmt, const HelperExprs &Exprs); 5310 5311 /// Creates an empty directive with the place for \a NumClauses clauses. 5312 /// 5313 /// \param C AST context. 5314 /// \param CollapsedNum Number of collapsed nested loops. 5315 /// \param NumClauses Number of clauses. 5316 /// 5317 static OMPTargetTeamsDistributeDirective * 5318 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 5319 EmptyShell); 5320 classof(const Stmt * T)5321 static bool classof(const Stmt *T) { 5322 return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass; 5323 } 5324 }; 5325 5326 /// This represents '#pragma omp target teams distribute parallel for' combined 5327 /// directive. 5328 /// 5329 /// \code 5330 /// #pragma omp target teams distribute parallel for private(x) 5331 /// \endcode 5332 /// In this example directive '#pragma omp target teams distribute parallel 5333 /// for' has clause 'private' with the variables 'x' 5334 /// 5335 class OMPTargetTeamsDistributeParallelForDirective final 5336 : public OMPLoopDirective { 5337 friend class ASTStmtReader; 5338 friend class OMPExecutableDirective; 5339 /// true if the construct has inner cancel directive. 5340 bool HasCancel = false; 5341 5342 /// Build directive with the given start and end location. 5343 /// 5344 /// \param StartLoc Starting location of the directive kind. 5345 /// \param EndLoc Ending location of the directive. 5346 /// \param CollapsedNum Number of collapsed nested loops. 5347 /// OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5348 OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc, 5349 SourceLocation EndLoc, 5350 unsigned CollapsedNum) 5351 : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass, 5352 llvm::omp::OMPD_target_teams_distribute_parallel_for, 5353 StartLoc, EndLoc, CollapsedNum) {} 5354 5355 /// Build an empty directive. 5356 /// 5357 /// \param CollapsedNum Number of collapsed nested loops. 5358 /// OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum)5359 explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum) 5360 : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass, 5361 llvm::omp::OMPD_target_teams_distribute_parallel_for, 5362 SourceLocation(), SourceLocation(), CollapsedNum) {} 5363 5364 /// Sets special task reduction descriptor. setTaskReductionRefExpr(Expr * E)5365 void setTaskReductionRefExpr(Expr *E) { 5366 Data->getChildren()[numLoopChildren( 5367 getLoopsNumber(), 5368 llvm::omp::OMPD_target_teams_distribute_parallel_for)] = E; 5369 } 5370 5371 /// Set cancel state. setHasCancel(bool Has)5372 void setHasCancel(bool Has) { HasCancel = Has; } 5373 5374 public: 5375 /// Creates directive with a list of \a Clauses. 5376 /// 5377 /// \param C AST context. 5378 /// \param StartLoc Starting location of the directive kind. 5379 /// \param EndLoc Ending Location of the directive. 5380 /// \param CollapsedNum Number of collapsed loops. 5381 /// \param Clauses List of clauses. 5382 /// \param AssociatedStmt Statement, associated with the directive. 5383 /// \param Exprs Helper expressions for CodeGen. 5384 /// \param TaskRedRef Task reduction special reference expression to handle 5385 /// taskgroup descriptor. 5386 /// \param HasCancel true if this directive has inner cancel directive. 5387 /// 5388 static OMPTargetTeamsDistributeParallelForDirective * 5389 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5390 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 5391 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 5392 bool HasCancel); 5393 5394 /// Creates an empty directive with the place for \a NumClauses clauses. 5395 /// 5396 /// \param C AST context. 5397 /// \param CollapsedNum Number of collapsed nested loops. 5398 /// \param NumClauses Number of clauses. 5399 /// 5400 static OMPTargetTeamsDistributeParallelForDirective * 5401 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 5402 EmptyShell); 5403 5404 /// Returns special task reduction reference expression. getTaskReductionRefExpr()5405 Expr *getTaskReductionRefExpr() { 5406 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 5407 getLoopsNumber(), 5408 llvm::omp::OMPD_target_teams_distribute_parallel_for)]); 5409 } getTaskReductionRefExpr()5410 const Expr *getTaskReductionRefExpr() const { 5411 return const_cast<OMPTargetTeamsDistributeParallelForDirective *>(this) 5412 ->getTaskReductionRefExpr(); 5413 } 5414 5415 /// Return true if current directive has inner cancel directive. hasCancel()5416 bool hasCancel() const { return HasCancel; } 5417 classof(const Stmt * T)5418 static bool classof(const Stmt *T) { 5419 return T->getStmtClass() == 5420 OMPTargetTeamsDistributeParallelForDirectiveClass; 5421 } 5422 }; 5423 5424 /// This represents '#pragma omp target teams distribute parallel for simd' 5425 /// combined directive. 5426 /// 5427 /// \code 5428 /// #pragma omp target teams distribute parallel for simd private(x) 5429 /// \endcode 5430 /// In this example directive '#pragma omp target teams distribute parallel 5431 /// for simd' has clause 'private' with the variables 'x' 5432 /// 5433 class OMPTargetTeamsDistributeParallelForSimdDirective final 5434 : public OMPLoopDirective { 5435 friend class ASTStmtReader; 5436 friend class OMPExecutableDirective; 5437 5438 /// Build directive with the given start and end location. 5439 /// 5440 /// \param StartLoc Starting location of the directive kind. 5441 /// \param EndLoc Ending location of the directive. 5442 /// \param CollapsedNum Number of collapsed nested loops. 5443 /// OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5444 OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc, 5445 SourceLocation EndLoc, 5446 unsigned CollapsedNum) 5447 : OMPLoopDirective( 5448 OMPTargetTeamsDistributeParallelForSimdDirectiveClass, 5449 llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, StartLoc, 5450 EndLoc, CollapsedNum) {} 5451 5452 /// Build an empty directive. 5453 /// 5454 /// \param CollapsedNum Number of collapsed nested loops. 5455 /// OMPTargetTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum)5456 explicit OMPTargetTeamsDistributeParallelForSimdDirective( 5457 unsigned CollapsedNum) 5458 : OMPLoopDirective( 5459 OMPTargetTeamsDistributeParallelForSimdDirectiveClass, 5460 llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, 5461 SourceLocation(), SourceLocation(), CollapsedNum) {} 5462 5463 public: 5464 /// Creates directive with a list of \a Clauses. 5465 /// 5466 /// \param C AST context. 5467 /// \param StartLoc Starting location of the directive kind. 5468 /// \param EndLoc Ending Location of the directive. 5469 /// \param CollapsedNum Number of collapsed loops. 5470 /// \param Clauses List of clauses. 5471 /// \param AssociatedStmt Statement, associated with the directive. 5472 /// \param Exprs Helper expressions for CodeGen. 5473 /// 5474 static OMPTargetTeamsDistributeParallelForSimdDirective * 5475 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5476 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 5477 Stmt *AssociatedStmt, const HelperExprs &Exprs); 5478 5479 /// Creates an empty directive with the place for \a NumClauses clauses. 5480 /// 5481 /// \param C AST context. 5482 /// \param CollapsedNum Number of collapsed nested loops. 5483 /// \param NumClauses Number of clauses. 5484 /// 5485 static OMPTargetTeamsDistributeParallelForSimdDirective * 5486 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 5487 EmptyShell); 5488 classof(const Stmt * T)5489 static bool classof(const Stmt *T) { 5490 return T->getStmtClass() == 5491 OMPTargetTeamsDistributeParallelForSimdDirectiveClass; 5492 } 5493 }; 5494 5495 /// This represents '#pragma omp target teams distribute simd' combined 5496 /// directive. 5497 /// 5498 /// \code 5499 /// #pragma omp target teams distribute simd private(x) 5500 /// \endcode 5501 /// In this example directive '#pragma omp target teams distribute simd' 5502 /// has clause 'private' with the variables 'x' 5503 /// 5504 class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective { 5505 friend class ASTStmtReader; 5506 friend class OMPExecutableDirective; 5507 5508 /// Build directive with the given start and end location. 5509 /// 5510 /// \param StartLoc Starting location of the directive kind. 5511 /// \param EndLoc Ending location of the directive. 5512 /// \param CollapsedNum Number of collapsed nested loops. 5513 /// OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5514 OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc, 5515 SourceLocation EndLoc, 5516 unsigned CollapsedNum) 5517 : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass, 5518 llvm::omp::OMPD_target_teams_distribute_simd, StartLoc, 5519 EndLoc, CollapsedNum) {} 5520 5521 /// Build an empty directive. 5522 /// 5523 /// \param CollapsedNum Number of collapsed nested loops. 5524 /// OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum)5525 explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum) 5526 : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass, 5527 llvm::omp::OMPD_target_teams_distribute_simd, 5528 SourceLocation(), SourceLocation(), CollapsedNum) {} 5529 5530 public: 5531 /// Creates directive with a list of \a Clauses. 5532 /// 5533 /// \param C AST context. 5534 /// \param StartLoc Starting location of the directive kind. 5535 /// \param EndLoc Ending Location of the directive. 5536 /// \param CollapsedNum Number of collapsed loops. 5537 /// \param Clauses List of clauses. 5538 /// \param AssociatedStmt Statement, associated with the directive. 5539 /// \param Exprs Helper expressions for CodeGen. 5540 /// 5541 static OMPTargetTeamsDistributeSimdDirective * 5542 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5543 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 5544 Stmt *AssociatedStmt, const HelperExprs &Exprs); 5545 5546 /// Creates an empty directive with the place for \a NumClauses clauses. 5547 /// 5548 /// \param C AST context. 5549 /// \param CollapsedNum Number of collapsed nested loops. 5550 /// \param NumClauses Number of clauses. 5551 /// 5552 static OMPTargetTeamsDistributeSimdDirective * 5553 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 5554 EmptyShell); 5555 classof(const Stmt * T)5556 static bool classof(const Stmt *T) { 5557 return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass; 5558 } 5559 }; 5560 5561 /// This represents the '#pragma omp tile' loop transformation directive. 5562 class OMPTileDirective final : public OMPLoopTransformationDirective { 5563 friend class ASTStmtReader; 5564 friend class OMPExecutableDirective; 5565 5566 /// Default list of offsets. 5567 enum { 5568 PreInitsOffset = 0, 5569 TransformedStmtOffset, 5570 }; 5571 OMPTileDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumLoops)5572 explicit OMPTileDirective(SourceLocation StartLoc, SourceLocation EndLoc, 5573 unsigned NumLoops) 5574 : OMPLoopTransformationDirective(OMPTileDirectiveClass, 5575 llvm::omp::OMPD_tile, StartLoc, EndLoc, 5576 NumLoops) { 5577 setNumGeneratedLoops(3 * NumLoops); 5578 } 5579 setPreInits(Stmt * PreInits)5580 void setPreInits(Stmt *PreInits) { 5581 Data->getChildren()[PreInitsOffset] = PreInits; 5582 } 5583 setTransformedStmt(Stmt * S)5584 void setTransformedStmt(Stmt *S) { 5585 Data->getChildren()[TransformedStmtOffset] = S; 5586 } 5587 5588 public: 5589 /// Create a new AST node representation for '#pragma omp tile'. 5590 /// 5591 /// \param C Context of the AST. 5592 /// \param StartLoc Location of the introducer (e.g. the 'omp' token). 5593 /// \param EndLoc Location of the directive's end (e.g. the tok::eod). 5594 /// \param Clauses The directive's clauses. 5595 /// \param NumLoops Number of associated loops (number of items in the 5596 /// 'sizes' clause). 5597 /// \param AssociatedStmt The outermost associated loop. 5598 /// \param TransformedStmt The loop nest after tiling, or nullptr in 5599 /// dependent contexts. 5600 /// \param PreInits Helper preinits statements for the loop nest. 5601 static OMPTileDirective *Create(const ASTContext &C, SourceLocation StartLoc, 5602 SourceLocation EndLoc, 5603 ArrayRef<OMPClause *> Clauses, 5604 unsigned NumLoops, Stmt *AssociatedStmt, 5605 Stmt *TransformedStmt, Stmt *PreInits); 5606 5607 /// Build an empty '#pragma omp tile' AST node for deserialization. 5608 /// 5609 /// \param C Context of the AST. 5610 /// \param NumClauses Number of clauses to allocate. 5611 /// \param NumLoops Number of associated loops to allocate. 5612 static OMPTileDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 5613 unsigned NumLoops); 5614 5615 /// Gets/sets the associated loops after tiling. 5616 /// 5617 /// This is in de-sugared format stored as a CompoundStmt. 5618 /// 5619 /// \code 5620 /// for (...) 5621 /// ... 5622 /// \endcode 5623 /// 5624 /// Note that if the generated loops a become associated loops of another 5625 /// directive, they may need to be hoisted before them. getTransformedStmt()5626 Stmt *getTransformedStmt() const { 5627 return Data->getChildren()[TransformedStmtOffset]; 5628 } 5629 5630 /// Return preinits statement. getPreInits()5631 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } 5632 classof(const Stmt * T)5633 static bool classof(const Stmt *T) { 5634 return T->getStmtClass() == OMPTileDirectiveClass; 5635 } 5636 }; 5637 5638 /// This represents the '#pragma omp unroll' loop transformation directive. 5639 /// 5640 /// \code 5641 /// #pragma omp unroll 5642 /// for (int i = 0; i < 64; ++i) 5643 /// \endcode 5644 class OMPUnrollDirective final : public OMPLoopTransformationDirective { 5645 friend class ASTStmtReader; 5646 friend class OMPExecutableDirective; 5647 5648 /// Default list of offsets. 5649 enum { 5650 PreInitsOffset = 0, 5651 TransformedStmtOffset, 5652 }; 5653 OMPUnrollDirective(SourceLocation StartLoc,SourceLocation EndLoc)5654 explicit OMPUnrollDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5655 : OMPLoopTransformationDirective(OMPUnrollDirectiveClass, 5656 llvm::omp::OMPD_unroll, StartLoc, EndLoc, 5657 1) {} 5658 5659 /// Set the pre-init statements. setPreInits(Stmt * PreInits)5660 void setPreInits(Stmt *PreInits) { 5661 Data->getChildren()[PreInitsOffset] = PreInits; 5662 } 5663 5664 /// Set the de-sugared statement. setTransformedStmt(Stmt * S)5665 void setTransformedStmt(Stmt *S) { 5666 Data->getChildren()[TransformedStmtOffset] = S; 5667 } 5668 5669 public: 5670 /// Create a new AST node representation for '#pragma omp unroll'. 5671 /// 5672 /// \param C Context of the AST. 5673 /// \param StartLoc Location of the introducer (e.g. the 'omp' token). 5674 /// \param EndLoc Location of the directive's end (e.g. the tok::eod). 5675 /// \param Clauses The directive's clauses. 5676 /// \param AssociatedStmt The outermost associated loop. 5677 /// \param TransformedStmt The loop nest after tiling, or nullptr in 5678 /// dependent contexts. 5679 /// \param PreInits Helper preinits statements for the loop nest. 5680 static OMPUnrollDirective * 5681 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5682 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, 5683 unsigned NumGeneratedLoops, Stmt *TransformedStmt, Stmt *PreInits); 5684 5685 /// Build an empty '#pragma omp unroll' AST node for deserialization. 5686 /// 5687 /// \param C Context of the AST. 5688 /// \param NumClauses Number of clauses to allocate. 5689 static OMPUnrollDirective *CreateEmpty(const ASTContext &C, 5690 unsigned NumClauses); 5691 5692 /// Get the de-sugared associated loops after unrolling. 5693 /// 5694 /// This is only used if the unrolled loop becomes an associated loop of 5695 /// another directive, otherwise the loop is emitted directly using loop 5696 /// transformation metadata. When the unrolled loop cannot be used by another 5697 /// directive (e.g. because of the full clause), the transformed stmt can also 5698 /// be nullptr. getTransformedStmt()5699 Stmt *getTransformedStmt() const { 5700 return Data->getChildren()[TransformedStmtOffset]; 5701 } 5702 5703 /// Return the pre-init statements. getPreInits()5704 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } 5705 classof(const Stmt * T)5706 static bool classof(const Stmt *T) { 5707 return T->getStmtClass() == OMPUnrollDirectiveClass; 5708 } 5709 }; 5710 5711 /// This represents '#pragma omp scan' directive. 5712 /// 5713 /// \code 5714 /// #pragma omp scan inclusive(a) 5715 /// \endcode 5716 /// In this example directive '#pragma omp scan' has clause 'inclusive' with 5717 /// list item 'a'. 5718 class OMPScanDirective final : public OMPExecutableDirective { 5719 friend class ASTStmtReader; 5720 friend class OMPExecutableDirective; 5721 /// Build directive with the given start and end location. 5722 /// 5723 /// \param StartLoc Starting location of the directive kind. 5724 /// \param EndLoc Ending location of the directive. 5725 /// OMPScanDirective(SourceLocation StartLoc,SourceLocation EndLoc)5726 OMPScanDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5727 : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan, 5728 StartLoc, EndLoc) {} 5729 5730 /// Build an empty directive. 5731 /// OMPScanDirective()5732 explicit OMPScanDirective() 5733 : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan, 5734 SourceLocation(), SourceLocation()) {} 5735 5736 public: 5737 /// Creates directive with a list of \a Clauses. 5738 /// 5739 /// \param C AST context. 5740 /// \param StartLoc Starting location of the directive kind. 5741 /// \param EndLoc Ending Location of the directive. 5742 /// \param Clauses List of clauses (only single OMPFlushClause clause is 5743 /// allowed). 5744 /// 5745 static OMPScanDirective *Create(const ASTContext &C, SourceLocation StartLoc, 5746 SourceLocation EndLoc, 5747 ArrayRef<OMPClause *> Clauses); 5748 5749 /// Creates an empty directive with the place for \a NumClauses 5750 /// clauses. 5751 /// 5752 /// \param C AST context. 5753 /// \param NumClauses Number of clauses. 5754 /// 5755 static OMPScanDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 5756 EmptyShell); 5757 classof(const Stmt * T)5758 static bool classof(const Stmt *T) { 5759 return T->getStmtClass() == OMPScanDirectiveClass; 5760 } 5761 }; 5762 5763 /// This represents '#pragma omp interop' directive. 5764 /// 5765 /// \code 5766 /// #pragma omp interop init(target:obj) device(x) depend(inout:y) nowait 5767 /// \endcode 5768 /// In this example directive '#pragma omp interop' has 5769 /// clauses 'init', 'device', 'depend' and 'nowait'. 5770 /// 5771 class OMPInteropDirective final : public OMPExecutableDirective { 5772 friend class ASTStmtReader; 5773 friend class OMPExecutableDirective; 5774 5775 /// Build directive with the given start and end location. 5776 /// 5777 /// \param StartLoc Starting location of the directive. 5778 /// \param EndLoc Ending location of the directive. 5779 /// OMPInteropDirective(SourceLocation StartLoc,SourceLocation EndLoc)5780 OMPInteropDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5781 : OMPExecutableDirective(OMPInteropDirectiveClass, 5782 llvm::omp::OMPD_interop, StartLoc, EndLoc) {} 5783 5784 /// Build an empty directive. 5785 /// OMPInteropDirective()5786 explicit OMPInteropDirective() 5787 : OMPExecutableDirective(OMPInteropDirectiveClass, 5788 llvm::omp::OMPD_interop, SourceLocation(), 5789 SourceLocation()) {} 5790 5791 public: 5792 /// Creates directive. 5793 /// 5794 /// \param C AST context. 5795 /// \param StartLoc Starting location of the directive. 5796 /// \param EndLoc Ending Location of the directive. 5797 /// \param Clauses The directive's clauses. 5798 /// 5799 static OMPInteropDirective *Create(const ASTContext &C, 5800 SourceLocation StartLoc, 5801 SourceLocation EndLoc, 5802 ArrayRef<OMPClause *> Clauses); 5803 5804 /// Creates an empty directive. 5805 /// 5806 /// \param C AST context. 5807 /// 5808 static OMPInteropDirective *CreateEmpty(const ASTContext &C, 5809 unsigned NumClauses, EmptyShell); 5810 classof(const Stmt * T)5811 static bool classof(const Stmt *T) { 5812 return T->getStmtClass() == OMPInteropDirectiveClass; 5813 } 5814 }; 5815 5816 /// This represents '#pragma omp dispatch' directive. 5817 /// 5818 /// \code 5819 /// #pragma omp dispatch device(dnum) 5820 /// \endcode 5821 /// This example shows a directive '#pragma omp dispatch' with a 5822 /// device clause with variable 'dnum'. 5823 /// 5824 class OMPDispatchDirective final : public OMPExecutableDirective { 5825 friend class ASTStmtReader; 5826 friend class OMPExecutableDirective; 5827 5828 /// The location of the target-call. 5829 SourceLocation TargetCallLoc; 5830 5831 /// Set the location of the target-call. setTargetCallLoc(SourceLocation Loc)5832 void setTargetCallLoc(SourceLocation Loc) { TargetCallLoc = Loc; } 5833 5834 /// Build directive with the given start and end location. 5835 /// 5836 /// \param StartLoc Starting location of the directive kind. 5837 /// \param EndLoc Ending location of the directive. 5838 /// OMPDispatchDirective(SourceLocation StartLoc,SourceLocation EndLoc)5839 OMPDispatchDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5840 : OMPExecutableDirective(OMPDispatchDirectiveClass, 5841 llvm::omp::OMPD_dispatch, StartLoc, EndLoc) {} 5842 5843 /// Build an empty directive. 5844 /// OMPDispatchDirective()5845 explicit OMPDispatchDirective() 5846 : OMPExecutableDirective(OMPDispatchDirectiveClass, 5847 llvm::omp::OMPD_dispatch, SourceLocation(), 5848 SourceLocation()) {} 5849 5850 public: 5851 /// Creates directive with a list of \a Clauses. 5852 /// 5853 /// \param C AST context. 5854 /// \param StartLoc Starting location of the directive kind. 5855 /// \param EndLoc Ending Location of the directive. 5856 /// \param Clauses List of clauses. 5857 /// \param AssociatedStmt Statement, associated with the directive. 5858 /// \param TargetCallLoc Location of the target-call. 5859 /// 5860 static OMPDispatchDirective * 5861 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5862 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, 5863 SourceLocation TargetCallLoc); 5864 5865 /// Creates an empty directive with the place for \a NumClauses 5866 /// clauses. 5867 /// 5868 /// \param C AST context. 5869 /// \param NumClauses Number of clauses. 5870 /// 5871 static OMPDispatchDirective *CreateEmpty(const ASTContext &C, 5872 unsigned NumClauses, EmptyShell); 5873 5874 /// Return location of target-call. getTargetCallLoc()5875 SourceLocation getTargetCallLoc() const { return TargetCallLoc; } 5876 classof(const Stmt * T)5877 static bool classof(const Stmt *T) { 5878 return T->getStmtClass() == OMPDispatchDirectiveClass; 5879 } 5880 }; 5881 5882 /// This represents '#pragma omp masked' directive. 5883 /// \code 5884 /// #pragma omp masked filter(tid) 5885 /// \endcode 5886 /// This example shows a directive '#pragma omp masked' with a filter clause 5887 /// with variable 'tid'. 5888 /// 5889 class OMPMaskedDirective final : public OMPExecutableDirective { 5890 friend class ASTStmtReader; 5891 friend class OMPExecutableDirective; 5892 5893 /// Build directive with the given start and end location. 5894 /// 5895 /// \param StartLoc Starting location of the directive kind. 5896 /// \param EndLoc Ending location of the directive. 5897 /// OMPMaskedDirective(SourceLocation StartLoc,SourceLocation EndLoc)5898 OMPMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5899 : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked, 5900 StartLoc, EndLoc) {} 5901 5902 /// Build an empty directive. 5903 /// OMPMaskedDirective()5904 explicit OMPMaskedDirective() 5905 : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked, 5906 SourceLocation(), SourceLocation()) {} 5907 5908 public: 5909 /// Creates directive. 5910 /// 5911 /// \param C AST context. 5912 /// \param StartLoc Starting location of the directive kind. 5913 /// \param EndLoc Ending Location of the directive. 5914 /// \param AssociatedStmt Statement, associated with the directive. 5915 /// 5916 static OMPMaskedDirective * 5917 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 5918 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 5919 5920 /// Creates an empty directive. 5921 /// 5922 /// \param C AST context. 5923 /// 5924 static OMPMaskedDirective *CreateEmpty(const ASTContext &C, 5925 unsigned NumClauses, EmptyShell); 5926 classof(const Stmt * T)5927 static bool classof(const Stmt *T) { 5928 return T->getStmtClass() == OMPMaskedDirectiveClass; 5929 } 5930 }; 5931 5932 /// This represents '#pragma omp metadirective' directive. 5933 /// 5934 /// \code 5935 /// #pragma omp metadirective when(user={condition(N>10)}: parallel for) 5936 /// \endcode 5937 /// In this example directive '#pragma omp metadirective' has clauses 'when' 5938 /// with a dynamic user condition to check if a variable 'N > 10' 5939 /// 5940 class OMPMetaDirective final : public OMPExecutableDirective { 5941 friend class ASTStmtReader; 5942 friend class OMPExecutableDirective; 5943 Stmt *IfStmt; 5944 OMPMetaDirective(SourceLocation StartLoc,SourceLocation EndLoc)5945 OMPMetaDirective(SourceLocation StartLoc, SourceLocation EndLoc) 5946 : OMPExecutableDirective(OMPMetaDirectiveClass, 5947 llvm::omp::OMPD_metadirective, StartLoc, 5948 EndLoc) {} OMPMetaDirective()5949 explicit OMPMetaDirective() 5950 : OMPExecutableDirective(OMPMetaDirectiveClass, 5951 llvm::omp::OMPD_metadirective, SourceLocation(), 5952 SourceLocation()) {} 5953 setIfStmt(Stmt * S)5954 void setIfStmt(Stmt *S) { IfStmt = S; } 5955 5956 public: 5957 static OMPMetaDirective *Create(const ASTContext &C, SourceLocation StartLoc, 5958 SourceLocation EndLoc, 5959 ArrayRef<OMPClause *> Clauses, 5960 Stmt *AssociatedStmt, Stmt *IfStmt); 5961 static OMPMetaDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 5962 EmptyShell); getIfStmt()5963 Stmt *getIfStmt() const { return IfStmt; } 5964 classof(const Stmt * T)5965 static bool classof(const Stmt *T) { 5966 return T->getStmtClass() == OMPMetaDirectiveClass; 5967 } 5968 }; 5969 5970 /// This represents '#pragma omp loop' directive. 5971 /// 5972 /// \code 5973 /// #pragma omp loop private(a,b) binding(parallel) order(concurrent) 5974 /// \endcode 5975 /// In this example directive '#pragma omp loop' has 5976 /// clauses 'private' with the variables 'a' and 'b', 'binding' with 5977 /// modifier 'parallel' and 'order(concurrent). 5978 /// 5979 class OMPGenericLoopDirective final : public OMPLoopDirective { 5980 friend class ASTStmtReader; 5981 friend class OMPExecutableDirective; 5982 /// Build directive with the given start and end location. 5983 /// 5984 /// \param StartLoc Starting location of the directive kind. 5985 /// \param EndLoc Ending location of the directive. 5986 /// \param CollapsedNum Number of collapsed nested loops. 5987 /// OMPGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5988 OMPGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 5989 unsigned CollapsedNum) 5990 : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop, 5991 StartLoc, EndLoc, CollapsedNum) {} 5992 5993 /// Build an empty directive. 5994 /// 5995 /// \param CollapsedNum Number of collapsed nested loops. 5996 /// OMPGenericLoopDirective(unsigned CollapsedNum)5997 explicit OMPGenericLoopDirective(unsigned CollapsedNum) 5998 : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop, 5999 SourceLocation(), SourceLocation(), CollapsedNum) {} 6000 6001 public: 6002 /// Creates directive with a list of \p Clauses. 6003 /// 6004 /// \param C AST context. 6005 /// \param StartLoc Starting location of the directive kind. 6006 /// \param EndLoc Ending Location of the directive. 6007 /// \param CollapsedNum Number of collapsed loops. 6008 /// \param Clauses List of clauses. 6009 /// \param AssociatedStmt Statement, associated with the directive. 6010 /// \param Exprs Helper expressions for CodeGen. 6011 /// 6012 static OMPGenericLoopDirective * 6013 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 6014 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 6015 Stmt *AssociatedStmt, const HelperExprs &Exprs); 6016 6017 /// Creates an empty directive with a place for \a NumClauses clauses. 6018 /// 6019 /// \param C AST context. 6020 /// \param NumClauses Number of clauses. 6021 /// \param CollapsedNum Number of collapsed nested loops. 6022 /// 6023 static OMPGenericLoopDirective *CreateEmpty(const ASTContext &C, 6024 unsigned NumClauses, 6025 unsigned CollapsedNum, 6026 EmptyShell); 6027 classof(const Stmt * T)6028 static bool classof(const Stmt *T) { 6029 return T->getStmtClass() == OMPGenericLoopDirectiveClass; 6030 } 6031 }; 6032 6033 /// This represents '#pragma omp teams loop' directive. 6034 /// 6035 /// \code 6036 /// #pragma omp teams loop private(a,b) order(concurrent) 6037 /// \endcode 6038 /// In this example directive '#pragma omp teams loop' has 6039 /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). 6040 /// 6041 class OMPTeamsGenericLoopDirective final : public OMPLoopDirective { 6042 friend class ASTStmtReader; 6043 friend class OMPExecutableDirective; 6044 /// Build directive with the given start and end location. 6045 /// 6046 /// \param StartLoc Starting location of the directive kind. 6047 /// \param EndLoc Ending location of the directive. 6048 /// \param CollapsedNum Number of collapsed nested loops. 6049 /// OMPTeamsGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)6050 OMPTeamsGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 6051 unsigned CollapsedNum) 6052 : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass, 6053 llvm::omp::OMPD_teams_loop, StartLoc, EndLoc, 6054 CollapsedNum) {} 6055 6056 /// Build an empty directive. 6057 /// 6058 /// \param CollapsedNum Number of collapsed nested loops. 6059 /// OMPTeamsGenericLoopDirective(unsigned CollapsedNum)6060 explicit OMPTeamsGenericLoopDirective(unsigned CollapsedNum) 6061 : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass, 6062 llvm::omp::OMPD_teams_loop, SourceLocation(), 6063 SourceLocation(), CollapsedNum) {} 6064 6065 public: 6066 /// Creates directive with a list of \p Clauses. 6067 /// 6068 /// \param C AST context. 6069 /// \param StartLoc Starting location of the directive kind. 6070 /// \param EndLoc Ending Location of the directive. 6071 /// \param CollapsedNum Number of collapsed loops. 6072 /// \param Clauses List of clauses. 6073 /// \param AssociatedStmt Statement, associated with the directive. 6074 /// \param Exprs Helper expressions for CodeGen. 6075 /// 6076 static OMPTeamsGenericLoopDirective * 6077 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 6078 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 6079 Stmt *AssociatedStmt, const HelperExprs &Exprs); 6080 6081 /// Creates an empty directive with the place 6082 /// for \a NumClauses clauses. 6083 /// 6084 /// \param C AST context. 6085 /// \param CollapsedNum Number of collapsed nested loops. 6086 /// \param NumClauses Number of clauses. 6087 /// 6088 static OMPTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C, 6089 unsigned NumClauses, 6090 unsigned CollapsedNum, 6091 EmptyShell); 6092 classof(const Stmt * T)6093 static bool classof(const Stmt *T) { 6094 return T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass; 6095 } 6096 }; 6097 6098 /// This represents '#pragma omp target teams loop' directive. 6099 /// 6100 /// \code 6101 /// #pragma omp target teams loop private(a,b) order(concurrent) 6102 /// \endcode 6103 /// In this example directive '#pragma omp target teams loop' has 6104 /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). 6105 /// 6106 class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective { 6107 friend class ASTStmtReader; 6108 friend class OMPExecutableDirective; 6109 /// Build directive with the given start and end location. 6110 /// 6111 /// \param StartLoc Starting location of the directive kind. 6112 /// \param EndLoc Ending location of the directive. 6113 /// \param CollapsedNum Number of collapsed nested loops. 6114 /// OMPTargetTeamsGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)6115 OMPTargetTeamsGenericLoopDirective(SourceLocation StartLoc, 6116 SourceLocation EndLoc, 6117 unsigned CollapsedNum) 6118 : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass, 6119 llvm::omp::OMPD_target_teams_loop, StartLoc, EndLoc, 6120 CollapsedNum) {} 6121 6122 /// Build an empty directive. 6123 /// 6124 /// \param CollapsedNum Number of collapsed nested loops. 6125 /// OMPTargetTeamsGenericLoopDirective(unsigned CollapsedNum)6126 explicit OMPTargetTeamsGenericLoopDirective(unsigned CollapsedNum) 6127 : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass, 6128 llvm::omp::OMPD_target_teams_loop, SourceLocation(), 6129 SourceLocation(), CollapsedNum) {} 6130 6131 public: 6132 /// Creates directive with a list of \p Clauses. 6133 /// 6134 /// \param C AST context. 6135 /// \param StartLoc Starting location of the directive kind. 6136 /// \param EndLoc Ending Location of the directive. 6137 /// \param CollapsedNum Number of collapsed loops. 6138 /// \param Clauses List of clauses. 6139 /// \param AssociatedStmt Statement, associated with the directive. 6140 /// \param Exprs Helper expressions for CodeGen. 6141 /// 6142 static OMPTargetTeamsGenericLoopDirective * 6143 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 6144 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 6145 Stmt *AssociatedStmt, const HelperExprs &Exprs); 6146 6147 /// Creates an empty directive with the place 6148 /// for \a NumClauses clauses. 6149 /// 6150 /// \param C AST context. 6151 /// \param CollapsedNum Number of collapsed nested loops. 6152 /// \param NumClauses Number of clauses. 6153 /// 6154 static OMPTargetTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C, 6155 unsigned NumClauses, 6156 unsigned CollapsedNum, 6157 EmptyShell); 6158 classof(const Stmt * T)6159 static bool classof(const Stmt *T) { 6160 return T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass; 6161 } 6162 }; 6163 6164 /// This represents '#pragma omp parallel loop' directive. 6165 /// 6166 /// \code 6167 /// #pragma omp parallel loop private(a,b) order(concurrent) 6168 /// \endcode 6169 /// In this example directive '#pragma omp parallel loop' has 6170 /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). 6171 /// 6172 class OMPParallelGenericLoopDirective final : public OMPLoopDirective { 6173 friend class ASTStmtReader; 6174 friend class OMPExecutableDirective; 6175 /// Build directive with the given start and end location. 6176 /// 6177 /// \param StartLoc Starting location of the directive kind. 6178 /// \param EndLoc Ending location of the directive. 6179 /// \param CollapsedNum Number of collapsed nested loops. 6180 /// OMPParallelGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)6181 OMPParallelGenericLoopDirective(SourceLocation StartLoc, 6182 SourceLocation EndLoc, unsigned CollapsedNum) 6183 : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass, 6184 llvm::omp::OMPD_parallel_loop, StartLoc, EndLoc, 6185 CollapsedNum) {} 6186 6187 /// Build an empty directive. 6188 /// 6189 /// \param CollapsedNum Number of collapsed nested loops. 6190 /// OMPParallelGenericLoopDirective(unsigned CollapsedNum)6191 explicit OMPParallelGenericLoopDirective(unsigned CollapsedNum) 6192 : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass, 6193 llvm::omp::OMPD_parallel_loop, SourceLocation(), 6194 SourceLocation(), CollapsedNum) {} 6195 6196 public: 6197 /// Creates directive with a list of \p Clauses. 6198 /// 6199 /// \param C AST context. 6200 /// \param StartLoc Starting location of the directive kind. 6201 /// \param EndLoc Ending Location of the directive. 6202 /// \param CollapsedNum Number of collapsed loops. 6203 /// \param Clauses List of clauses. 6204 /// \param AssociatedStmt Statement, associated with the directive. 6205 /// \param Exprs Helper expressions for CodeGen. 6206 /// 6207 static OMPParallelGenericLoopDirective * 6208 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 6209 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 6210 Stmt *AssociatedStmt, const HelperExprs &Exprs); 6211 6212 /// Creates an empty directive with the place 6213 /// for \a NumClauses clauses. 6214 /// 6215 /// \param C AST context. 6216 /// \param CollapsedNum Number of collapsed nested loops. 6217 /// \param NumClauses Number of clauses. 6218 /// 6219 static OMPParallelGenericLoopDirective *CreateEmpty(const ASTContext &C, 6220 unsigned NumClauses, 6221 unsigned CollapsedNum, 6222 EmptyShell); 6223 classof(const Stmt * T)6224 static bool classof(const Stmt *T) { 6225 return T->getStmtClass() == OMPParallelGenericLoopDirectiveClass; 6226 } 6227 }; 6228 6229 /// This represents '#pragma omp target parallel loop' directive. 6230 /// 6231 /// \code 6232 /// #pragma omp target parallel loop private(a,b) order(concurrent) 6233 /// \endcode 6234 /// In this example directive '#pragma omp target parallel loop' has 6235 /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). 6236 /// 6237 class OMPTargetParallelGenericLoopDirective final : public OMPLoopDirective { 6238 friend class ASTStmtReader; 6239 friend class OMPExecutableDirective; 6240 /// Build directive with the given start and end location. 6241 /// 6242 /// \param StartLoc Starting location of the directive kind. 6243 /// \param EndLoc Ending location of the directive. 6244 /// \param CollapsedNum Number of collapsed nested loops. 6245 /// OMPTargetParallelGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)6246 OMPTargetParallelGenericLoopDirective(SourceLocation StartLoc, 6247 SourceLocation EndLoc, 6248 unsigned CollapsedNum) 6249 : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass, 6250 llvm::omp::OMPD_target_parallel_loop, StartLoc, EndLoc, 6251 CollapsedNum) {} 6252 6253 /// Build an empty directive. 6254 /// 6255 /// \param CollapsedNum Number of collapsed nested loops. 6256 /// OMPTargetParallelGenericLoopDirective(unsigned CollapsedNum)6257 explicit OMPTargetParallelGenericLoopDirective(unsigned CollapsedNum) 6258 : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass, 6259 llvm::omp::OMPD_target_parallel_loop, SourceLocation(), 6260 SourceLocation(), CollapsedNum) {} 6261 6262 public: 6263 /// Creates directive with a list of \p Clauses. 6264 /// 6265 /// \param C AST context. 6266 /// \param StartLoc Starting location of the directive kind. 6267 /// \param EndLoc Ending Location of the directive. 6268 /// \param CollapsedNum Number of collapsed loops. 6269 /// \param Clauses List of clauses. 6270 /// \param AssociatedStmt Statement, associated with the directive. 6271 /// \param Exprs Helper expressions for CodeGen. 6272 /// 6273 static OMPTargetParallelGenericLoopDirective * 6274 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 6275 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 6276 Stmt *AssociatedStmt, const HelperExprs &Exprs); 6277 6278 /// Creates an empty directive with the place 6279 /// for \a NumClauses clauses. 6280 /// 6281 /// \param C AST context. 6282 /// \param CollapsedNum Number of collapsed nested loops. 6283 /// \param NumClauses Number of clauses. 6284 /// 6285 static OMPTargetParallelGenericLoopDirective * 6286 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 6287 EmptyShell); 6288 classof(const Stmt * T)6289 static bool classof(const Stmt *T) { 6290 return T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass; 6291 } 6292 }; 6293 6294 /// This represents '#pragma omp error' directive. 6295 /// 6296 /// \code 6297 /// #pragma omp error 6298 /// \endcode 6299 class OMPErrorDirective final : public OMPExecutableDirective { 6300 friend class ASTStmtReader; 6301 friend class OMPExecutableDirective; 6302 /// Build directive with the given start and end location. 6303 /// 6304 /// \param StartLoc Starting location of the directive kind. 6305 /// \param EndLoc Ending location of the directive. 6306 /// OMPErrorDirective(SourceLocation StartLoc,SourceLocation EndLoc)6307 OMPErrorDirective(SourceLocation StartLoc, SourceLocation EndLoc) 6308 : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error, 6309 StartLoc, EndLoc) {} 6310 /// Build an empty directive. 6311 /// OMPErrorDirective()6312 explicit OMPErrorDirective() 6313 : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error, 6314 SourceLocation(), SourceLocation()) {} 6315 6316 public: 6317 /// 6318 /// \param C AST context. 6319 /// \param StartLoc Starting location of the directive kind. 6320 /// \param EndLoc Ending Location of the directive. 6321 /// \param Clauses List of clauses. 6322 /// 6323 static OMPErrorDirective *Create(const ASTContext &C, SourceLocation StartLoc, 6324 SourceLocation EndLoc, 6325 ArrayRef<OMPClause *> Clauses); 6326 6327 /// Creates an empty directive. 6328 /// 6329 /// \param C AST context. 6330 /// 6331 static OMPErrorDirective *CreateEmpty(const ASTContext &C, 6332 unsigned NumClauses, EmptyShell); 6333 classof(const Stmt * T)6334 static bool classof(const Stmt *T) { 6335 return T->getStmtClass() == OMPErrorDirectiveClass; 6336 } 6337 }; 6338 } // end namespace clang 6339 6340 #endif 6341